Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of Automatics v1.9.0
plugins/Automatics.dll
Decompiled a week 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.Collections.ObjectModel; using System.Collections.Specialized; using System.ComponentModel; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Serialization; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using System.Text.RegularExpressions; using System.Threading; using Automatics.AutomaticDoor; using Automatics.AutomaticFarming; using Automatics.AutomaticMapping; using Automatics.AutomaticProcessing; using Automatics.AutomaticStorage; using Automatics.AutomaticSupply; using Automatics.ConsoleCommands; using Automatics.Valheim; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using JetBrains.Annotations; using LitJson; using ModUtils; using NDesk.Options; using Splatform; using TMPro; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.Rendering; using UnityEngine.UI; using Valheim.SettingsGui; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: InternalsVisibleTo("Automatics.SmokeTest")] [assembly: AssemblyTitle("Automatics")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("Automatics")] [assembly: AssemblyCopyright("Copyright (c) 2022-2026 EideeHi")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("1821CB9A-56A9-4013-B268-86F0704773CF")] [assembly: AssemblyFileVersion("1.9.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = "")] [assembly: AssemblyVersion("1.9.0.0")] namespace ModUtils { public class Configuration { private sealed class LocalizedConfigEntry { public ConfigEntryBase Entry { get; set; } public L10N Localization { get; set; } public string Section { get; set; } public string Key { get; set; } public ConfigurationManagerAttributes Attributes { get; set; } public bool CategoryManaged { get; set; } public bool DispNameManaged { get; set; } public bool DescriptionManaged { get; set; } } private const int DefaultOrder = 4096; private static readonly object LocalizedEntriesLock; private static readonly Dictionary<ConfigEntryBase, LocalizedConfigEntry> LocalizedEntries; private static readonly string[] DescriptionFieldNames; private readonly ConfigFile _config; private readonly L10N _localization; private Logger _logger; private string Section { get; set; } = "general"; private int Order { get; set; } = 4096; static Configuration() { //IL_005a: 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_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Expected O, but got Unknown //IL_00ac: 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_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Expected O, but got Unknown LocalizedEntriesLock = new object(); DescriptionFieldNames = new string[4] { "<Description>k__BackingField", "Description", "description", "_description" }; LocalizedEntries = new Dictionary<ConfigEntryBase, LocalizedConfigEntry>(); if (!TomlTypeConverter.CanConvert(typeof(StringList))) { TomlTypeConverter.AddConverter(typeof(StringList), new TypeConverter { ConvertToObject = (string str, Type type) => (!string.IsNullOrEmpty(str)) ? new StringList(Csv.ParseLine(str, trimUnquotedFields: true)) : new StringList(), ConvertToString = delegate(object obj, Type type) { StringList source = (StringList)obj; return string.Join(", ", source.Select(Csv.Escape)); } }); } if (!TomlTypeConverter.CanConvert(typeof(KeyboardShortcut))) { TomlTypeConverter.AddConverter(typeof(KeyboardShortcut), new TypeConverter { ConvertToObject = (string str, Type type) => KeyboardShortcut.Deserialize(str), ConvertToString = delegate(object obj, Type type) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) KeyboardShortcut val = (KeyboardShortcut)obj; return ((KeyboardShortcut)(ref val)).Serialize(); } }); } } public Configuration(ConfigFile config, L10N localization) { _config = config; _localization = localization; } internal static void RefreshAllLocalizedMetadata() { LocalizedConfigEntry[] array; lock (LocalizedEntriesLock) { array = LocalizedEntries.Values.ToArray(); } LocalizedConfigEntry[] array2 = array; for (int i = 0; i < array2.Length; i++) { RefreshLocalizedMetadata(array2[i]); } } private static void RegisterLocalizedEntry(ConfigEntryBase entry, L10N localization, string section, string key, ConfigurationManagerAttributes attributes, bool categoryManaged, bool dispNameManaged, bool descriptionManaged) { LocalizedConfigEntry localizedConfigEntry = new LocalizedConfigEntry { Entry = entry, Localization = localization, Section = section, Key = key, Attributes = attributes, CategoryManaged = categoryManaged, DispNameManaged = dispNameManaged, DescriptionManaged = descriptionManaged }; lock (LocalizedEntriesLock) { LocalizedEntries[entry] = localizedConfigEntry; } RefreshLocalizedMetadata(localizedConfigEntry); } private static void RefreshLocalizedMetadata(LocalizedConfigEntry entry) { //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Expected O, but got Unknown if (entry?.Entry == null || entry.Localization == null) { return; } try { ConfigurationManagerAttributes attributes = entry.Attributes; if (attributes != null) { if (entry.CategoryManaged) { attributes.Category = entry.Localization.Translate("@config_" + entry.Section + "_section"); } if (entry.DispNameManaged) { attributes.DispName = entry.Localization.Translate("@config_" + entry.Section + "_" + entry.Key + "_name"); } string text = (attributes.Description = (entry.DescriptionManaged ? entry.Localization.Translate("@config_" + entry.Section + "_" + entry.Key + "_description") : attributes.Description)); ConfigDescription description = entry.Entry.Description; AcceptableValueBase val = ((description != null) ? description.AcceptableValues : null); object[] array = ReplaceConfigurationManagerAttributes((description != null) ? description.Tags : null, attributes); ConfigDescription description2 = new ConfigDescription(text, val, array); if (!TrySetEntryDescription(entry.Entry, description2)) { Debug.LogError((object)("[ModUtils] Failed to replace ConfigDescription for [" + entry.Section + ":" + entry.Key + "].")); } } } catch (Exception arg) { Debug.LogError((object)$"[ModUtils] Failed to refresh localized config metadata for [{entry.Section}:{entry.Key}]: {arg}"); } } private static object[] ReplaceConfigurationManagerAttributes(object[] tags, ConfigurationManagerAttributes attributes) { if (tags == null || tags.Length == 0) { return new object[1] { attributes }; } bool flag = false; List<object> list = new List<object>(tags.Length); foreach (object obj in tags) { if (obj is ConfigurationManagerAttributes) { if (!flag) { list.Add(attributes); flag = true; } } else { list.Add(obj); } } if (!flag) { list.Add(attributes); } return list.ToArray(); } private static bool TrySetEntryDescription(ConfigEntryBase entry, ConfigDescription description) { MethodInfo methodInfo = AccessTools.PropertySetter(((object)entry).GetType(), "Description") ?? AccessTools.PropertySetter(typeof(ConfigEntryBase), "Description"); if (methodInfo != null) { methodInfo.Invoke(entry, new object[1] { description }); return true; } string[] descriptionFieldNames = DescriptionFieldNames; foreach (string text in descriptionFieldNames) { FieldInfo fieldInfo = AccessTools.Field(((object)entry).GetType(), text) ?? AccessTools.Field(typeof(ConfigEntryBase), text); if (!(fieldInfo == null) && typeof(ConfigDescription).IsAssignableFrom(fieldInfo.FieldType)) { fieldInfo.SetValue(entry, description); return true; } } return false; } private void LogSection(string section) { _logger?.Debug("[CONFIG] === " + GetSection(section) + " / [" + section + "]"); } private void LogConfigEntry<T>(ConfigEntry<T> entry, ConfigurationManagerAttributes attributes) { _logger?.Debug("[CONFIG] ==== " + attributes.DispName + " / [" + ((ConfigEntryBase)entry).Definition.Key + "]"); _logger?.Debug("[CONFIG] " + ((ConfigEntryBase)entry).Description.Description); _logger?.Debug("[CONFIG] "); Type type = typeof(T); object defaultValue = ((ConfigEntryBase)entry).DefaultValue; if (attributes.ObjToStr != null) { _logger?.Debug("[CONFIG] - Default value: " + attributes.ObjToStr(defaultValue)); } else if (TomlTypeConverter.CanConvert(type)) { _logger?.Debug("[CONFIG] - Default value: " + TomlTypeConverter.ConvertToString(defaultValue, type)); } else { _logger?.Debug($"[CONFIG] - Default value: {defaultValue}"); } AcceptableValueBase acceptableValues = ((ConfigEntryBase)entry).Description.AcceptableValues; if (acceptableValues != null) { string[] array = acceptableValues.ToDescriptionString().Split('\n'); foreach (string text in array) { _logger?.Debug("[CONFIG] - " + text); } } else if (type.IsEnum) { List<string> list = (from x in Enum.GetValues(type).OfType<T>() select Enum.GetName(type, x)).ToList(); _logger?.Debug("[CONFIG] - Acceptable values: " + string.Join(", ", list)); if (type.GetCustomAttributes(typeof(FlagsAttribute), inherit: false).Any()) { IEnumerable<string> values = list.Where((string x) => !string.Equals(x, "none", StringComparison.OrdinalIgnoreCase) && !string.Equals(x, "all", StringComparison.OrdinalIgnoreCase)).Take(2); _logger?.Debug("[CONFIG] - Multiple values can be set at the same time by separating them with , (e.g. " + string.Join(", ", values) + ")"); } } _logger?.Debug("[CONFIG] "); } public void SetDebugLogger(Logger logger) { _logger = logger; } public void ChangeSection(string section, int initialOrder = 4096) { Section = section; Order = initialOrder; if (_logger != null) { LogSection(Section); } } private ConfigEntry<T> Bind<T>(string section, int order, string key, T defaultValue, AcceptableValueBase acceptableValue = null, Action<ConfigurationManagerAttributes> initializer = null) { //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Expected O, but got Unknown L10N.EnsurePatched(); string section2 = GetSection(section); string name = GetName(section, key); ConfigurationManagerAttributes configurationManagerAttributes = new ConfigurationManagerAttributes { Category = section2, Order = order, DispName = name, CustomDrawer = ConfigurationCustomDrawer.Get(typeof(T), acceptableValue) }; initializer?.Invoke(configurationManagerAttributes); bool categoryManaged = string.Equals(configurationManagerAttributes.Category, section2, StringComparison.Ordinal); bool dispNameManaged = string.Equals(configurationManagerAttributes.DispName, name, StringComparison.Ordinal); bool flag = string.IsNullOrEmpty(configurationManagerAttributes.Description); string text = (configurationManagerAttributes.Description = (flag ? GetDescription(section, key) : configurationManagerAttributes.Description)); ConfigEntry<T> val = _config.Bind<T>(section, key, defaultValue, new ConfigDescription(text, acceptableValue, new object[1] { configurationManagerAttributes })); RegisterLocalizedEntry((ConfigEntryBase)(object)val, _localization, section, key, configurationManagerAttributes, categoryManaged, dispNameManaged, flag); if (_logger != null) { LogConfigEntry<T>(val, configurationManagerAttributes); } return val; } public ConfigEntry<T> Bind<T>(string section, string key, T defaultValue, AcceptableValueBase acceptableValue = null, Action<ConfigurationManagerAttributes> initializer = null) { return Bind(section, Order--, key, defaultValue, acceptableValue, initializer); } public ConfigEntry<T> Bind<T>(string section, string key, T defaultValue, (T, T) acceptableValue, Action<ConfigurationManagerAttributes> initializer = null) where T : IComparable { var (val, val2) = acceptableValue; return Bind(section, key, defaultValue, (AcceptableValueBase)(object)new AcceptableValueRange<T>(val, val2), initializer); } public ConfigEntry<T> Bind<T>(string key, T defaultValue, AcceptableValueBase acceptableValue = null, Action<ConfigurationManagerAttributes> initializer = null) { return Bind(Section, key, defaultValue, acceptableValue, initializer); } public ConfigEntry<T> Bind<T>(string key, T defaultValue, (T, T) acceptableValue, Action<ConfigurationManagerAttributes> initializer = null) where T : IComparable { return Bind(Section, key, defaultValue, acceptableValue, initializer); } private string GetSection(string section) { return _localization.Translate("@config_" + section + "_section"); } private string GetName(string section, string key) { return _localization.Translate("@config_" + section + "_" + key + "_name"); } private string GetDescription(string section, string key) { return _localization.Translate("@config_" + section + "_" + key + "_description"); } } public class StringList : ICollection<string>, IEnumerable<string>, IEnumerable { private readonly HashSet<string> _values; public int Count => _values.Count; public bool IsReadOnly => false; public StringList() { _values = new HashSet<string>(); } public StringList(IEnumerable<string> collection) { _values = new HashSet<string>(collection); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } public IEnumerator<string> GetEnumerator() { return _values.GetEnumerator(); } public void Add(string item) { _values.Add(item); } public void Clear() { _values.Clear(); } public bool Contains(string item) { return _values.Contains(item); } public void CopyTo(string[] array, int arrayIndex) { _values.CopyTo(array, arrayIndex); } public bool Remove(string item) { return _values.Remove(item); } public bool TryAdd(string item) { return _values.Add(item); } } public class LocalizedDescriptionAttribute : DescriptionAttribute { private readonly string _prefix; private readonly string _key; public override string Description => L10N.Translate(_prefix, _key); public LocalizedDescriptionAttribute(string prefix, string key) : base(key) { _prefix = prefix; _key = key; } public LocalizedDescriptionAttribute(string key) : this("", key) { } } public class AcceptableValueEnum<T> : AcceptableValueBase where T : Enum { private readonly bool _isFlags; private readonly IList<T> _values; public AcceptableValueEnum(params T[] values) : base(typeof(T)) { _isFlags = ((AcceptableValueBase)this).ValueType.GetCustomAttributes(typeof(FlagsAttribute), inherit: false).Any(); _values = MakeValues(((AcceptableValueBase)this).ValueType, (IReadOnlyCollection<T>)(object)values, _isFlags); } private static IList<T> MakeValues(Type type, IReadOnlyCollection<T> values, bool isFlags) { object collection; if (values.Count != 0) { collection = values; } else { collection = Enum.GetValues(type).OfType<T>(); } List<T> list = new List<T>((IEnumerable<T>)collection); if (!isFlags) { return list; } HashSet<long> hashSet = new HashSet<long>(); foreach (long item in list.Select((T @enum) => Convert.ToInt64(@enum))) { long[] array = hashSet.ToArray(); foreach (long num2 in array) { hashSet.Add(num2 | item); } hashSet.Add(item); } return hashSet.Select((long x) => Enum.ToObject(type, x)).Cast<T>().ToList(); } public override object Clamp(object value) { if (!((AcceptableValueBase)this).IsValid(value)) { return _values[0]; } return value; } public override bool IsValid(object value) { if (value is T item) { return _values.Contains(item); } if (!(value is IConvertible)) { return false; } long @long = Convert.ToInt64(value); return _values.Any((T x) => Convert.ToInt64(x) == @long); } public override string ToDescriptionString() { StringBuilder stringBuilder = new StringBuilder(); Type type = typeof(T); List<string> list = (from x in _values where Enum.IsDefined(type, x) select Enum.GetName(type, x)).ToList(); stringBuilder.Append("# Acceptable values: ").Append(string.Join(", ", list)); if (!_isFlags) { return stringBuilder.ToString(); } List<string> list2 = list.Where((string x) => !string.Equals(x, "none", StringComparison.OrdinalIgnoreCase) && !string.Equals(x, "all", StringComparison.OrdinalIgnoreCase)).Take(2).ToList(); if (list2.Count == 2) { stringBuilder.Append('\n').Append("# Multiple values can be set at the same time by separating them with , (e.g. ").Append(string.Join(", ", list2)) .Append(")"); } return stringBuilder.ToString(); } } public static class ConfigurationCustomDrawer { public delegate bool IsMatchConfig(Type type, AcceptableValueBase acceptableValue); public delegate Action<ConfigEntryBase> CustomDrawerSupplier(); private sealed class MultiSelectSource<T> { internal Func<IEnumerable<T>> AllElementSupplier { get; } internal Func<T, string> LabelGenerator { get; } internal MultiSelectSource(Func<IEnumerable<T>> allElementSupplier, Func<T, string> labelGenerator) { AllElementSupplier = allElementSupplier; LabelGenerator = labelGenerator; } } private const string L10NPrefix = "mod_utils"; private const string EnabledKey = "@config_button_enabled"; private const string DisabledKey = "@config_button_disabled"; private const string AddKey = "@config_button_add"; private const string RemoveKey = "@config_button_remove"; private static readonly Dictionary<IsMatchConfig, CustomDrawerSupplier> CustomDrawers; private static bool _defaultTranslationsInitialized; private static readonly Dictionary<string, Dictionary<string, string>> BuiltinDrawerTranslations; private static readonly Dictionary<string, Dictionary<string, string>> CustomDrawerTranslations; private static readonly Dictionary<string, string> OwnedDefaults; private static readonly ConditionalWeakTable<Action<ConfigEntryBase>, object> MultiSelectSources; static ConfigurationCustomDrawer() { BuiltinDrawerTranslations = new Dictionary<string, Dictionary<string, string>>(StringComparer.OrdinalIgnoreCase) { { "English", new Dictionary<string, string> { { "@config_button_enabled", "Enabled" }, { "@config_button_disabled", "Disabled" }, { "@config_button_add", "Add" }, { "@config_button_remove", "Remove" } } }, { "Japanese", new Dictionary<string, string> { { "@config_button_enabled", "有効" }, { "@config_button_disabled", "無効" }, { "@config_button_add", "追加" }, { "@config_button_remove", "削除" } } } }; CustomDrawerTranslations = new Dictionary<string, Dictionary<string, string>>(StringComparer.OrdinalIgnoreCase); OwnedDefaults = new Dictionary<string, string>(); MultiSelectSources = new ConditionalWeakTable<Action<ConfigEntryBase>, object>(); CustomDrawers = new Dictionary<IsMatchConfig, CustomDrawerSupplier> { { IsBool, () => Bool }, { IsFloatWithRange, () => FloatSlider }, { IsStringList, StringList }, { IsFlagsEnum, () => Flags } }; } public static void RegisterDefaultDrawerTranslation(string language, string key, string value) { if (!CustomDrawerTranslations.TryGetValue(language, out var value2)) { value2 = new Dictionary<string, string>(); CustomDrawerTranslations[language] = value2; } value2[key] = value; if (_defaultTranslationsInitialized) { RefreshDefaultTranslations(); } } internal static void EnsureDefaultTranslations() { if (!_defaultTranslationsInitialized) { _defaultTranslationsInitialized = TryAddDefaultTranslations(); } } internal static void RefreshDefaultTranslations() { _defaultTranslationsInitialized = false; _defaultTranslationsInitialized = TryAddDefaultTranslations(); if (!_defaultTranslationsInitialized) { Debug.LogWarning((object)"[ModUtils] Failed to refresh custom drawer fallback translations for the current language."); } } private static Dictionary<string, string> ResolveDrawerTranslations(string language) { Dictionary<string, string> dictionary = new Dictionary<string, string>(BuiltinDrawerTranslations["English"]); if (CustomDrawerTranslations.TryGetValue("English", out var value)) { foreach (KeyValuePair<string, string> item in value) { dictionary[item.Key] = item.Value; } } if (!string.Equals(language, "English", StringComparison.OrdinalIgnoreCase)) { if (BuiltinDrawerTranslations.TryGetValue(language, out var value2)) { foreach (KeyValuePair<string, string> item2 in value2) { dictionary[item2.Key] = item2.Value; } } if (CustomDrawerTranslations.TryGetValue(language, out var value3)) { foreach (KeyValuePair<string, string> item3 in value3) { dictionary[item3.Key] = item3.Value; } } } return dictionary; } private static bool TryAddDefaultTranslations() { Localization instance; try { instance = Localization.instance; } catch (Exception) { return false; } if (instance == null) { return false; } Dictionary<string, string> field = Reflections.GetField<Dictionary<string, string>>(instance, "m_translations"); if (field == null) { return false; } string text; try { text = instance.GetSelectedLanguage(); } catch (Exception) { return false; } if (string.IsNullOrEmpty(text)) { text = "English"; } foreach (KeyValuePair<string, string> item in ResolveDrawerTranslations(text)) { string translationKey = L10N.GetTranslationKey("mod_utils", item.Key); if (field.TryGetValue(translationKey, out var value)) { if (OwnedDefaults.TryGetValue(translationKey, out var value2) && value == value2) { field[translationKey] = item.Value; } } else { field[translationKey] = item.Value; } OwnedDefaults[translationKey] = item.Value; } return true; } private static bool IsBool(Type type, AcceptableValueBase acceptableValue) { return type == typeof(bool); } private static bool IsFloatWithRange(Type type, AcceptableValueBase acceptableValue) { if (type == typeof(float)) { return acceptableValue is AcceptableValueRange<float>; } return false; } private static bool IsStringList(Type type, AcceptableValueBase acceptableValue) { return type == typeof(StringList); } private static bool HasFlagsAttribute(Type type) { if (type.IsEnum) { return type.GetCustomAttributes(typeof(FlagsAttribute), inherit: false).Any(); } return false; } private static bool IsFlagsEnum(Type type, AcceptableValueBase acceptableValue) { return HasFlagsAttribute(type); } public static void Bool(ConfigEntryBase entry) { EnsureDefaultTranslations(); bool flag = (bool)entry.BoxedValue; string text = L10N.Translate("mod_utils", flag ? "@config_button_enabled" : "@config_button_disabled"); bool flag2 = GUILayout.Toggle(flag, text, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) }); if (flag2 != flag) { entry.BoxedValue = flag2; } } public static void FloatSlider(ConfigEntryBase entry) { AcceptableValueRange<float> val = (AcceptableValueRange<float>)(object)entry.Description.AcceptableValues; float num = (float)entry.BoxedValue; float minValue = val.MinValue; float maxValue = val.MaxValue; float num2 = GUILayout.HorizontalSlider(num, minValue, maxValue, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) }); num2 = Mathf.Floor(num2 * 100f) / 100f; if (Math.Abs(num2 - num) > Mathf.Abs(maxValue - minValue) / 1000f) { entry.BoxedValue = num2; } string text = num.ToString("0.00", CultureInfo.InvariantCulture); string text2 = GUILayout.TextField(text, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(50f) }); if (text2 == text) { return; } try { num2 = (float)Convert.ToDouble(text2, CultureInfo.InvariantCulture); object boxedValue = Convert.ChangeType(((AcceptableValueBase)val).Clamp((object)num2), entry.SettingType, CultureInfo.InvariantCulture); entry.BoxedValue = boxedValue; } catch (FormatException) { } } private static Action<ConfigEntryBase> StringList() { string inputText = ""; return delegate(ConfigEntryBase entry) { //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Expected O, but got Unknown //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Expected O, but got Unknown //IL_013f: Unknown result type (might be due to invalid IL or missing references) EnsureDefaultTranslations(); int num = Mathf.Min(Screen.width, 650); int num2 = num - Mathf.RoundToInt((float)num / 2.5f) - 115; string text = L10N.Translate("mod_utils", "@config_button_add"); string text2 = L10N.Translate("mod_utils", "@config_button_remove"); StringList stringList = new StringList((StringList)entry.BoxedValue); GUILayout.BeginVertical((GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.MaxWidth((float)num2) }); GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); inputText = GUILayout.TextField(inputText, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) }); if (GUILayout.Button(text, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(false) }) && !string.IsNullOrEmpty(inputText)) { if (stringList.TryAdd(inputText)) { entry.BoxedValue = stringList; } inputText = ""; } GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); double num3 = 0.0; foreach (string item in stringList.ToList()) { int num4 = Mathf.FloorToInt(GUI.skin.label.CalcSize(new GUIContent(item)).x) + Mathf.FloorToInt(GUI.skin.button.CalcSize(new GUIContent(text2)).x); num3 += (double)num4; if (num3 > (double)num2) { GUILayout.EndHorizontal(); num3 = num4; GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); } GUILayout.Label(item, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(false) }); if (GUILayout.Button(text2, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(false) }) && stringList.Remove(item)) { entry.BoxedValue = stringList; } } GUILayout.EndHorizontal(); GUILayout.EndVertical(); GUILayout.FlexibleSpace(); }; } public static void Flags(ConfigEntryBase entry) { //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Expected O, but got Unknown //IL_00c2: Unknown result type (might be due to invalid IL or missing references) int num = Mathf.Min(Screen.width, 650); int num2 = num - Mathf.RoundToInt((float)num / 2.5f) - 115; Type settingType = entry.SettingType; long num3 = Convert.ToInt64(entry.BoxedValue); AcceptableValueBase acceptableValues = entry.Description.AcceptableValues; GUILayout.BeginVertical((GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.MaxWidth((float)num2) }); int num4 = 0; GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); foreach (object value2 in Enum.GetValues(settingType)) { if (acceptableValues != null && !acceptableValues.IsValid(value2)) { continue; } long num5 = Convert.ToInt64(value2); if (num5 != 0L) { string enumLabel = GetEnumLabel(settingType, value2); int num6 = Mathf.FloorToInt(GUI.skin.toggle.CalcSize(new GUIContent(enumLabel + "_")).x); num4 += num6; if (num4 > num2) { GUILayout.EndHorizontal(); num4 = num6; GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); } GUI.changed = false; bool flag = GUILayout.Toggle((num3 & num5) == num5, enumLabel, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(false) }); if (GUI.changed) { long value = (flag ? (num3 | num5) : (num3 & ~num5)); entry.BoxedValue = Enum.ToObject(settingType, value); } } } GUILayout.EndHorizontal(); GUI.changed = false; GUILayout.EndVertical(); GUILayout.FlexibleSpace(); } public static Action<ConfigEntryBase> MultiSelect<T>(Func<IEnumerable<T>> allElementSupplier, Func<T, string> labelGenerator) where T : IComparable<T> { Action<ConfigEntryBase> action = delegate(ConfigEntryBase entry) { //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Expected O, but got Unknown //IL_0140: Unknown result type (might be due to invalid IL or missing references) int num = Mathf.Min(Screen.width, 650); int num2 = num - Mathf.RoundToInt((float)num / 2.5f) - 115; GUILayout.BeginVertical((GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.MaxWidth((float)num2) }); Type settingType = entry.SettingType; ConstructorInfo constructor = settingType.GetConstructor(new Type[1] { typeof(IEnumerable<T>) }); if ((object)constructor == null) { GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); GUILayout.Label($"{settingType} does not define a constructor that takes IEnumerable<{typeof(T)}> as an argument.", Array.Empty<GUILayoutOption>()); GUILayout.EndHorizontal(); GUI.changed = false; GUILayout.EndVertical(); GUILayout.FlexibleSpace(); } else { ICollection<T> collection = (ICollection<T>)constructor.Invoke(new object[1] { entry.BoxedValue }); AcceptableValueBase acceptableValues = entry.Description.AcceptableValues; int num3 = 0; GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); foreach (T item in allElementSupplier()) { if (acceptableValues == null || acceptableValues.IsValid((object)item)) { string text = labelGenerator(item) ?? item.ToString(); int num4 = Mathf.FloorToInt(GUI.skin.toggle.CalcSize(new GUIContent(text + "_")).x); num3 += num4; if (num3 > num2) { GUILayout.EndHorizontal(); num3 = num4; GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); } GUI.changed = false; bool flag = GUILayout.Toggle(collection.Contains(item), text, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(false) }); if (GUI.changed) { if (flag) { collection.Add(item); } else { collection.Remove(item); } entry.BoxedValue = collection; } } } GUILayout.EndHorizontal(); GUI.changed = false; GUILayout.EndVertical(); GUILayout.FlexibleSpace(); } }; MultiSelectSources.Add(action, new MultiSelectSource<T>(allElementSupplier, labelGenerator)); return action; } internal static bool TryGetMultiSelectSource<T>(Action<ConfigEntryBase> drawer, out Func<IEnumerable<T>> allElementSupplier, out Func<T, string> labelGenerator) { if (drawer != null && MultiSelectSources.TryGetValue(drawer, out var value) && value is MultiSelectSource<T> multiSelectSource) { allElementSupplier = multiSelectSource.AllElementSupplier; labelGenerator = multiSelectSource.LabelGenerator; return true; } allElementSupplier = null; labelGenerator = null; return false; } internal static bool IsMultiSelect(Action<ConfigEntryBase> drawer) { object value; if (drawer != null) { return MultiSelectSources.TryGetValue(drawer, out value); } return false; } public static void Register(IsMatchConfig matcher, CustomDrawerSupplier supplier) { CustomDrawers[matcher] = supplier; } public static Action<ConfigEntryBase> Get(Type type, AcceptableValueBase acceptableValue) { return (from x in CustomDrawers where x.Key(type, acceptableValue) select x.Value()).FirstOrDefault(); } private static string GetEnumLabel(Type type, object @object) { return (type.GetMember(Enum.GetName(type, @object) ?? "").FirstOrDefault()?.GetCustomAttributes(typeof(DescriptionAttribute), inherit: false).OfType<DescriptionAttribute>().FirstOrDefault())?.Description ?? @object.ToString(); } } public static class ConfigurationGui { internal const string L10NPrefix = "mod_utils"; internal const string ModsTabKey = "@config_gui_mods_tab"; internal const string BackKey = "@config_gui_back"; internal const string ResetKey = "@config_gui_reset"; internal const string StagedApplyHintKey = "@config_gui_staged_apply_hint"; internal const string ResetAllKey = "@config_gui_reset_all"; internal const string ApplyKey = "@config_gui_apply"; internal const string DiscardHeaderKey = "@config_gui_discard_header"; internal const string DiscardQuestionKey = "@config_gui_discard_question"; internal const string SearchPlaceholderKey = "@config_gui_search"; internal const string ShowAdvancedKey = "@config_gui_show_advanced"; internal const string ReadOnlyKey = "@config_gui_read_only"; internal const string PressKeyKey = "@config_gui_press_key"; internal const string ClearKey = "@config_gui_clear"; private const string ShowOnSettingsScreenSection = "mod_utils"; private const string ShowOnSettingsScreenKey = "show_on_settings_screen"; private const string ShowOnSettingsScreenCategoryKey = "@config_mod_utils_section"; private const string ShowOnSettingsScreenNameKey = "@config_mod_utils_show_on_settings_screen_name"; private const string ShowOnSettingsScreenDescriptionKey = "@config_mod_utils_show_on_settings_screen_description"; internal const string PageName = "ModUtils.ModsTab.v1"; internal const string TabButtonName = "ModUtils.ModsTab.v1.Button"; internal const string ListName = "List"; internal const string PanelsName = "Panels"; internal const string ButtonTemplateName = "ButtonTemplate"; private const string HarmonyIdPrefix = "net.eideehi.modutils.configurationgui."; private const float ListPadding = 16f; private const float ListSpacing = 8f; private const float ModButtonMinWidth = 320f; private static readonly List<ConfigurationGuiPlugin> Plugins = new List<ConfigurationGuiPlugin>(); private static readonly List<KeyValuePair<ConfigurationCustomDrawer.IsMatchConfig, Func<ConfigurationGuiCustomEditor>>> CustomEditors = new List<KeyValuePair<ConfigurationCustomDrawer.IsMatchConfig, Func<ConfigurationGuiCustomEditor>>>(); private static readonly Dictionary<string, Dictionary<string, string>> DefaultTranslations = new Dictionary<string, Dictionary<string, string>> { { "English", new Dictionary<string, string> { { "@config_gui_mods_tab", "Mods" }, { "@config_gui_back", "Back" }, { "@config_gui_reset", "Reset" }, { "@config_gui_staged_apply_hint", "Changes are saved when you press Apply." }, { "@config_gui_reset_all", "Reset all" }, { "@config_gui_apply", "Apply" }, { "@config_gui_discard_header", "Unsaved changes" }, { "@config_gui_discard_question", "Discard the changes that are not applied and go back?" }, { "@config_gui_search", "Search" }, { "@config_gui_show_advanced", "Show advanced settings" }, { "@config_gui_read_only", "Read-only" }, { "@config_gui_press_key", "Press a key..." }, { "@config_gui_clear", "Clear" }, { "@config_mod_utils_section", "Settings screen" }, { "@config_mod_utils_show_on_settings_screen_name", "Show on the Settings screen" }, { "@config_mod_utils_show_on_settings_screen_description", "Shows this mod on the Mods tab of the game's Settings screen. When no mod is shown there, the tab is not added. A change applies the next time the Settings screen opens. After turning this off, turn it back on in ConfigurationManager or in this mod's config file." } } }, { "Japanese", new Dictionary<string, string> { { "@config_gui_mods_tab", "Mod" }, { "@config_gui_back", "戻る" }, { "@config_gui_reset", "リセット" }, { "@config_gui_staged_apply_hint", "変更は「確定」を押すと保存されます。" }, { "@config_gui_reset_all", "すべて初期値に戻す" }, { "@config_gui_apply", "確定" }, { "@config_gui_discard_header", "未確定の変更" }, { "@config_gui_discard_question", "確定していない変更を破棄して戻りますか?" }, { "@config_gui_search", "検索" }, { "@config_gui_show_advanced", "上級者向けの設定を表示" }, { "@config_gui_read_only", "読み取り専用" }, { "@config_gui_press_key", "キーを押してください..." }, { "@config_gui_clear", "クリア" }, { "@config_mod_utils_section", "設定画面" }, { "@config_mod_utils_show_on_settings_screen_name", "設定画面に表示" }, { "@config_mod_utils_show_on_settings_screen_description", "ゲームの設定画面の「Mod」タブにこの Mod を表示します。表示する Mod がひとつもないときは、タブは追加されません。変更は次に設定画面を開いたときに反映されます。オフにしたあとで戻すときは、ConfigurationManager かこの Mod の設定ファイルで変更してください。" } } } }; private static bool _patchAttempted; private static bool _translationsRegistered; public static void Register(BaseUnityPlugin plugin) { if ((Object)(object)plugin == (Object)null) { throw new ArgumentNullException("plugin"); } BepInPlugin metadata = plugin.Info.Metadata; if (!Plugins.Any((ConfigurationGuiPlugin x) => string.Equals(x.Guid, metadata.GUID, StringComparison.Ordinal))) { RegisterTranslations(); ConfigurationCustomDrawer.EnsureDefaultTranslations(); ConfigEntry<bool> showOnSettingsScreen = new Configuration(plugin.Config, new L10N("mod_utils")).Bind("mod_utils", "show_on_settings_screen", defaultValue: true); Plugins.Add(new ConfigurationGuiPlugin(metadata.GUID, metadata.Name, metadata.Version, plugin.Config, showOnSettingsScreen)); ApplyPatch(metadata.GUID); } } public static void RegisterEditor(ConfigurationCustomDrawer.IsMatchConfig matcher, Func<ConfigurationGuiCustomEditor> factory) { if (matcher == null) { throw new ArgumentNullException("matcher"); } if (factory == null) { throw new ArgumentNullException("factory"); } CustomEditors.Add(new KeyValuePair<ConfigurationCustomDrawer.IsMatchConfig, Func<ConfigurationGuiCustomEditor>>(matcher, factory)); } internal static bool TryCreateCustomEditor(ConfigEntryBase entry, string pluginName, out ConfigurationGuiCustomEditor editor) { editor = null; try { Type settingType = entry.SettingType; ConfigDescription description = entry.Description; AcceptableValueBase acceptableValue = ((description != null) ? description.AcceptableValues : null); for (int num = CustomEditors.Count - 1; num >= 0; num--) { if (CustomEditors[num].Key(settingType, acceptableValue)) { editor = CustomEditors[num].Value(); break; } } return true; } catch (Exception ex) { ConfigDefinition definition = entry.Definition; Debug.LogError((object)$"[ModUtils] Failed to create the registered editor for [{definition.Section}:{definition.Key}] of {pluginName}: {ex}"); return false; } } internal static string Translate(string key) { return L10N.Translate("mod_utils", key); } internal static Transform FindChild(Transform parent, string name) { if ((Object)(object)parent == (Object)null) { return null; } for (int i = 0; i < parent.childCount; i++) { Transform child = parent.GetChild(i); if (string.Equals(((Object)child).name, name, StringComparison.Ordinal)) { return child; } } return null; } private static void RegisterTranslations() { if (_translationsRegistered) { return; } _translationsRegistered = true; foreach (KeyValuePair<string, Dictionary<string, string>> defaultTranslation in DefaultTranslations) { foreach (KeyValuePair<string, string> item in defaultTranslation.Value) { ConfigurationCustomDrawer.RegisterDefaultDrawerTranslation(defaultTranslation.Key, item.Key, item.Value); } } } private static void ApplyPatch(string guid) { //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Expected O, but got Unknown if (_patchAttempted) { return; } _patchAttempted = true; try { MethodInfo methodInfo = AccessTools.Method(typeof(Settings), "Awake", (Type[])null, (Type[])null); if (methodInfo == null) { Debug.LogWarning((object)"[ModUtils] Settings.Awake was not found. The Mods settings tab is unavailable."); } else { new Harmony("net.eideehi.modutils.configurationgui." + guid).Patch((MethodBase)methodInfo, new HarmonyMethod(typeof(ConfigurationGui), "OnSettingsAwake", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } } catch (Exception arg) { Debug.LogError((object)$"[ModUtils] Failed to patch Settings.Awake. The Mods settings tab is unavailable. {arg}"); } } private static void OnSettingsAwake(Settings __instance) { try { AddModsTab(__instance); } catch (Exception arg) { Debug.LogError((object)$"[ModUtils] Failed to add the Mods tab to the settings screen: {arg}"); } } private static void AddModsTab(Settings settings) { if (!Plugins.Any((ConfigurationGuiPlugin x) => x.ShowOnSettingsScreen.Value)) { return; } TabHandler componentInChildren = ((Component)settings).GetComponentInChildren<TabHandler>(); if (!((Object)(object)componentInChildren == (Object)null) && componentInChildren.m_tabs != null && componentInChildren.m_tabs.Count != 0) { ConfigurationCustomDrawer.RefreshDefaultTranslations(); RectTransform val = FindPage(componentInChildren) ?? CreatePage(settings, componentInChildren); if (!((Object)(object)val == (Object)null)) { AddPluginButtons(val); } } } private static RectTransform FindPage(TabHandler tabHandler) { foreach (Tab tab in tabHandler.m_tabs) { if ((Object)(object)tab?.m_page != (Object)null && string.Equals(((Object)tab.m_page).name, "ModUtils.ModsTab.v1", StringComparison.Ordinal)) { return tab.m_page; } } return null; } private static RectTransform CreatePage(Settings settings, TabHandler tabHandler) { //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Expected O, but got Unknown //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Expected O, but got Unknown //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Expected O, but got Unknown //IL_013d: Expected O, but got Unknown List<Tab> tabs = tabHandler.m_tabs; Button val = null; int num = tabs.Count - 1; while (num >= 0 && (Object)(object)val == (Object)null) { if ((Object)(object)tabs[num]?.m_button != (Object)null) { val = tabs[num].m_button; } num--; } RectTransform val2 = tabs[0]?.m_page; Button val3 = ConfigurationGuiTemplates.FindButton(settings); if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null || (Object)(object)((Transform)val2).parent == (Object)null || (Object)(object)val3 == (Object)null) { Debug.LogWarning((object)"[ModUtils] The settings screen has no usable tab button, page or button to copy. The Mods tab is not added."); return null; } GameObject val4 = null; GameObject val5 = null; try { val4 = CreateTabButton(settings, val); val5 = CreatePageObject(val2, tabs); CreatePageChildren(settings, (RectTransform)val5.transform, val3); val5.AddComponent<ConfigurationGuiTab>(); } catch { if ((Object)(object)val4 != (Object)null) { Object.Destroy((Object)(object)val4); } if ((Object)(object)val5 != (Object)null) { Object.Destroy((Object)(object)val5); } throw; } RectTransform val6 = (RectTransform)val5.transform; tabs.Add(new Tab { m_button = val4.GetComponent<Button>(), m_page = val6, m_default = false, m_onClick = new UnityEvent() }); return val6; } private static GameObject CreateTabButton(Settings settings, Button source) { Transform transform = ((Component)source).transform; GameObject val = Object.Instantiate<GameObject>(((Component)source).gameObject, transform.parent, false); ((Object)val).name = "ModUtils.ModsTab.v1.Button"; val.transform.SetSiblingIndex(transform.GetSiblingIndex() + 1); RemoveTabKeyHints(settings, transform, val.transform); ConfigurationGuiTemplates.Sanitize(val); string text = "$" + L10N.GetTranslationKey("mod_utils", "@config_gui_mods_tab"); TMP_Text[] componentsInChildren = val.GetComponentsInChildren<TMP_Text>(true); for (int i = 0; i < componentsInChildren.Length; i++) { componentsInChildren[i].text = text; } Localization val2 = L10N.TryGetLocalization(); if (val2 != null) { val2.Localize(val.transform); } return val; } private static void RemoveTabKeyHints(Settings settings, Transform source, Transform clone) { if (!(AccessTools.Field(typeof(Settings), "m_tabKeyHints")?.GetValue(settings) is GameObject[] array)) { return; } GameObject[] array2 = array; foreach (GameObject val in array2) { if (!((Object)(object)val == (Object)null) && !((Object)(object)val.transform == (Object)(object)source) && val.transform.IsChildOf(source)) { Transform val2 = FindCopy(source, clone, val.transform); if (!((Object)(object)val2 == (Object)null)) { ((Component)val2).gameObject.SetActive(false); Object.Destroy((Object)(object)((Component)val2).gameObject); } } } } private static Transform FindCopy(Transform sourceRoot, Transform cloneRoot, Transform sourceTarget) { List<int> list = new List<int>(); Transform val = sourceTarget; while ((Object)(object)val != (Object)(object)sourceRoot) { list.Add(val.GetSiblingIndex()); val = val.parent; } Transform val2 = cloneRoot; for (int num = list.Count - 1; num >= 0; num--) { if (list[num] >= val2.childCount) { return null; } val2 = val2.GetChild(list[num]); } return val2; } private static GameObject CreatePageObject(RectTransform firstPage, List<Tab> tabs) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: 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_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007c: 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_008d: 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_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: 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) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: 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_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Expected O, but got Unknown GameObject val = new GameObject("ModUtils.ModsTab.v1", new Type[1] { typeof(RectTransform) }); val.SetActive(false); val.layer = ((Component)firstPage).gameObject.layer; RectTransform val2 = (RectTransform)val.transform; ((Transform)val2).SetParent(((Transform)firstPage).parent, false); val2.anchorMin = firstPage.anchorMin; val2.anchorMax = firstPage.anchorMax; val2.pivot = firstPage.pivot; val2.sizeDelta = firstPage.sizeDelta; val2.anchoredPosition = firstPage.anchoredPosition; ((Transform)val2).localScale = ((Transform)firstPage).localScale; ((Transform)val2).localRotation = ((Transform)firstPage).localRotation; int num = tabs.Where((Tab x) => (Object)(object)x?.m_page != (Object)null && (Object)(object)((Transform)x.m_page).parent == (Object)(object)((Transform)firstPage).parent).Max((Tab x) => ((Transform)x.m_page).GetSiblingIndex()); ((Transform)val2).SetSiblingIndex(num + 1); return val; } private static void CreatePageChildren(Settings settings, RectTransform page, Button buttonStyle) { //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Expected O, but got Unknown //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Expected O, but got Unknown RectTransform obj = ConfigurationGuiTemplates.CreateRect("List", (Transform)(object)page); ConfigurationGuiTemplates.Stretch(obj, 16f, 16f, 16f, 16f); VerticalLayoutGroup obj2 = ((Component)obj).gameObject.AddComponent<VerticalLayoutGroup>(); ((LayoutGroup)obj2).childAlignment = (TextAnchor)1; ((HorizontalOrVerticalLayoutGroup)obj2).spacing = 8f; ((HorizontalOrVerticalLayoutGroup)obj2).childControlWidth = true; ((HorizontalOrVerticalLayoutGroup)obj2).childControlHeight = true; ((HorizontalOrVerticalLayoutGroup)obj2).childForceExpandWidth = false; ((HorizontalOrVerticalLayoutGroup)obj2).childForceExpandHeight = false; RectTransform obj3 = ConfigurationGuiTemplates.CreateRect("Panels", (Transform)(object)page); ConfigurationGuiTemplates.Stretch(obj3, 0f, 0f, 0f, 0f); ((Component)obj3).gameObject.SetActive(false); Button val = ConfigurationGuiTemplates.Clone<Button>(buttonStyle, (Transform)(object)page, "ButtonTemplate"); ((Component)val).gameObject.SetActive(false); TMP_Text val2 = ((Component)val).GetComponentInChildren<TMP_Text>(true); if ((Object)(object)val2 == (Object)null) { val2 = (TMP_Text)(object)ConfigurationGuiTemplates.CreateText(((Component)val).transform, "Label", ConfigurationGuiTemplates.FindLabel(settings)); ConfigurationGuiTemplates.Stretch((RectTransform)val2.transform, 0f, 0f, 0f, 0f); val2.alignment = (TextAlignmentOptions)514; } val2.text = ""; RectTransform val3 = (RectTransform)((Component)buttonStyle).transform; GameObject gameObject = ((Component)val).gameObject; Rect rect = val3.rect; ConfigurationGuiTemplates.AddLayout(gameObject, -1f, -1f, Mathf.Max(((Rect)(ref rect)).width, 320f), ConfigurationGuiTemplates.VanillaControlHeight((Component)(object)buttonStyle)); } private static void AddPluginButtons(RectTransform page) { //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Expected O, but got Unknown //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Expected O, but got Unknown Transform val = FindChild((Transform)(object)page, "List"); Transform val2 = FindChild((Transform)(object)page, "ButtonTemplate"); if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null) { Debug.LogWarning((object)"[ModUtils] The Mods tab has no mod list or button template. Mods cannot be listed."); return; } foreach (ConfigurationGuiPlugin plugin in Plugins) { if (plugin.ShowOnSettingsScreen.Value && !((Object)(object)FindChild(val, plugin.Guid) != (Object)null)) { GameObject obj = Object.Instantiate<GameObject>(((Component)val2).gameObject, val, false); ((Object)obj).name = plugin.Guid; Button component = obj.GetComponent<Button>(); TMP_Text componentInChildren = obj.GetComponentInChildren<TMP_Text>(true); if ((Object)(object)componentInChildren != (Object)null) { componentInChildren.text = plugin.Name; } ConfigurationGuiPlugin owner = plugin; component.onClick = new ButtonClickedEvent(); ((UnityEvent)component.onClick).AddListener((UnityAction)delegate { ConfigurationGuiPanel.Open(owner, page); }); obj.SetActive(true); } } SortByLabel(val); } private static void SortByLabel(Transform list) { List<Transform> list2 = new List<Transform>(); for (int i = 0; i < list.childCount; i++) { list2.Add(list.GetChild(i)); } List<Transform> list3 = list2.OrderBy<Transform, string>(GetLabel, StringComparer.OrdinalIgnoreCase).ThenBy<Transform, string>((Transform x) => ((Object)x).name, StringComparer.Ordinal).ToList(); for (int num = 0; num < list3.Count; num++) { list3[num].SetSiblingIndex(num); } } private static string GetLabel(Transform button) { TMP_Text componentInChildren = ((Component)button).GetComponentInChildren<TMP_Text>(true); if (!((Object)(object)componentInChildren != (Object)null)) { return ((Object)button).name; } return componentInChildren.text ?? ""; } } internal sealed class ConfigurationGuiPlugin { internal string Guid { get; } internal string Name { get; } internal Version Version { get; } internal ConfigFile Config { get; } internal ConfigEntry<bool> ShowOnSettingsScreen { get; } internal ConfigurationGuiPlugin(string guid, string name, Version version, ConfigFile config, ConfigEntry<bool> showOnSettingsScreen) { Guid = guid; Name = name; Version = version; Config = config; ShowOnSettingsScreen = showOnSettingsScreen; } } public abstract class ConfigurationGuiCustomEditor { private ConfigurationGuiCustomEditorHost _host; private ConfigurationGuiWidgets _widgets; protected ConfigEntryBase Entry => _host.HostEntry; protected object Value => _host.HostValue; protected float LineHeight { get; set; } internal float HostLineHeight => LineHeight; protected abstract float Build(RectTransform slot, ConfigurationGuiWidgets widgets); protected abstract void Refresh(); protected virtual void SetInteractable(bool interactable) { _widgets?.SetInteractable(interactable); } protected virtual bool ConsumesEscape() { if (_widgets != null) { return _widgets.ConsumesEscape(); } return false; } protected void Commit(object value) { _host.CommitFromEditor(value); } protected void SetHeight(float height) { _host.SetSlotHeight(height); } internal void Attach(ConfigurationGuiCustomEditorHost host) { _host = host; } internal float HostBuild(RectTransform slot, ConfigurationGuiWidgets widgets) { _widgets = widgets; return Build(slot, widgets); } internal void HostRefresh() { Refresh(); } internal void HostSetInteractable(bool interactable) { SetInteractable(interactable); } internal bool HostConsumesEscape() { return ConsumesEscape(); } } internal sealed class ConfigurationGuiCustomEditorHost : ConfigurationGuiEditor { private readonly ConfigurationGuiCustomEditor _editor; private readonly bool _readOnly; private ConfigurationGuiEditor _fallback; private RectTransform _slot; internal override bool IsEditable => _fallback == null; internal ConfigEntryBase HostEntry => base.Entry; internal object HostValue => base.Value; internal ConfigurationGuiCustomEditorHost(ConfigEntryBase entry, ConfigurationGuiCustomEditor editor) : base(entry) { _editor = editor; ConfigurationManagerAttributes attributes = ConfigurationGuiPanel.GetAttributes(entry); _readOnly = attributes != null && attributes.ReadOnly == true; editor?.Attach(this); } internal override float Build(RectTransform slot, ConfigurationGuiTemplates templates) { _slot = slot; VerticalLayoutGroup obj = ((Component)slot).gameObject.AddComponent<VerticalLayoutGroup>(); ((HorizontalOrVerticalLayoutGroup)obj).spacing = 4f; ((LayoutGroup)obj).childAlignment = (TextAnchor)0; ((HorizontalOrVerticalLayoutGroup)obj).childControlWidth = true; ((HorizontalOrVerticalLayoutGroup)obj).childControlHeight = true; ((HorizontalOrVerticalLayoutGroup)obj).childForceExpandWidth = true; ((HorizontalOrVerticalLayoutGroup)obj).childForceExpandHeight = false; try { float result = _editor.HostBuild(slot, new ConfigurationGuiWidgets(templates)); base.LineHeight = _editor.HostLineHeight; return result; } catch (Exception e) { LogError("Build", e); } for (int num = ((Transform)slot).childCount - 1; num >= 0; num--) { Object.DestroyImmediate((Object)(object)((Component)((Transform)slot).GetChild(num)).gameObject); } Component[] components = ((Component)slot).GetComponents<Component>(); for (int num2 = components.Length - 1; num2 >= 0; num2--) { if (!(components[num2] is RectTransform)) { Object.DestroyImmediate((Object)(object)components[num2]); } } base.LineHeight = 0f; _fallback = ConfigurationGuiEditor.CreateReadOnly(base.Entry, base.Pending); return _fallback.Build(slot, templates); } internal override void Refresh() { if (_fallback != null) { _fallback.Refresh(); return; } try { _editor.HostRefresh(); } catch (Exception e) { LogError("Refresh", e); } } internal override void SetInteractable(bool interactable) { if (_fallback != null) { _fallback.SetInteractable(interactable); return; } try { _editor.HostSetInteractable(interactable); } catch (Exception e) { LogError("SetInteractable", e); } } internal override bool ConsumesEscape() { if (_fallback != null) { return false; } try { return _editor.HostConsumesEscape(); } catch (Exception e) { LogError("ConsumesEscape", e); return false; } } internal void CommitFromEditor(object value) { if (_readOnly) { Refresh(); } else { Commit(value); } } internal void SetSlotHeight(float height) { LayoutElement val = (((Object)(object)_slot != (Object)null) ? ((Component)_slot).GetComponent<LayoutElement>() : null); if (!((Object)(object)val == (Object)null)) { val.minHeight = height; val.preferredHeight = height; } } private void LogError(string member, Exception e) { ConfigDefinition definition = base.Entry.Definition; Debug.LogError((object)$"[ModUtils] The registered editor for [{definition.Section}:{definition.Key}] of {base.Pending.PluginName} failed in {member}: {e}"); } } internal abstract class ConfigurationGuiEditor { protected ConfigEntryBase Entry { get; } protected object Value => Pending.Get(Entry); private protected ConfigurationGuiPendingValues Pending { get; private set; } internal virtual bool IsEditable => true; internal float LineHeight { get; private protected set; } protected ConfigurationGuiEditor(ConfigEntryBase entry) { Entry = entry; } internal static ConfigurationGuiEditor Create(ConfigEntryBase entry, ConfigurationGuiPendingValues pending, ConfigurationGuiTemplates templates) { ConfigurationGuiEditor configurationGuiEditor = Select(entry, pending.PluginName, templates); configurationGuiEditor.Pending = pending; return configurationGuiEditor; } internal static ConfigurationGuiEditor CreateReadOnly(ConfigEntryBase entry, ConfigurationGuiPendingValues pending) { return new ConfigurationGuiReadOnlyEditor(entry) { Pending = pending }; } private static ConfigurationGuiEditor Select(ConfigEntryBase entry, string pluginName, ConfigurationGuiTemplates templates) { if (!ConfigurationGui.TryCreateCustomEditor(entry, pluginName, out var editor)) { return new ConfigurationGuiReadOnlyEditor(entry); } if (editor != null) { return new ConfigurationGuiCustomEditorHost(entry, editor); } Type settingType = entry.SettingType; ConfigDescription description = entry.Description; AcceptableValueBase val = ((description != null) ? description.AcceptableValues : null); if (settingType == typeof(bool) && (Object)(object)templates.Toggle != (Object)null) { return new ConfigurationGuiToggleEditor(entry); } if (settingType == typeof(int) && val is AcceptableValueRange<int> val2 && (Object)(object)templates.Slider != (Object)null && (Object)(object)templates.InputField != (Object)null) { return new ConfigurationGuiSliderEditor(entry, val2.MinValue, val2.MaxValue, wholeNumbers: true); } if (settingType == typeof(float) && val is AcceptableValueRange<float> val3 && (Object)(object)templates.Slider != (Object)null && (Object)(object)templates.InputField != (Object)null) { return new ConfigurationGuiSliderEditor(entry, val3.MinValue, val3.MaxValue, wholeNumbers: false); } if ((settingType == typeof(int) || settingType == typeof(float) || settingType == typeof(string)) && (Object)(object)templates.InputField != (Object)null) { return new ConfigurationGuiTextEditor(entry, serialized: false); } if (settingType == typeof(KeyboardShortcut) && (Object)(object)templates.Button != (Object)null) { return new ConfigurationGuiKeyEditor(entry, shortcut: true); } if (settingType == typeof(KeyCode) && (Object)(object)templates.Button != (Object)null) { return new ConfigurationGuiKeyEditor(entry, shortcut: false); } if (settingType.IsEnum) { if (!settingType.IsDefined(typeof(FlagsAttribute), inherit: false)) { if ((Object)(object)templates.Dropdown != (Object)null) { return new ConfigurationGuiDropdownEditor(entry); } } else if ((Object)(object)templates.Toggle != (Object)null) { return new ConfigurationGuiFlagsEditor(entry); } } if (settingType == typeof(StringList)) { ConfigDescription description2 = entry.Description; Action<ConfigEntryBase> drawer = ((description2 == null) ? null : description2.Tags?.OfType<ConfigurationManagerAttributes>().FirstOrDefault()?.CustomDrawer); Func<IEnumerable<string>> allElementSupplier; Func<string, string> labelGenerator; if (!ConfigurationCustomDrawer.IsMultiSelect(drawer)) { if ((Object)(object)templates.InputField != (Object)null) { return new ConfigurationGuiTextEditor(entry, serialized: true); } } else if (ConfigurationCustomDrawer.TryGetMultiSelectSource(drawer, out allElementSupplier, out labelGenerator) && (Object)(object)templates.Toggle != (Object)null && (Object)(object)templates.Button != (Object)null && settingType.GetConstructor(new Type[1] { typeof(IEnumerable<string>) }) != null) { return new ConfigurationGuiMultiSelectEditor(entry, allElementSupplier, labelGenerator); } } return new ConfigurationGuiReadOnlyEditor(entry); } protected static string GetEnumLabel(Type type, object value) { string name = Enum.GetName(type, value); return (((name == null) ? null : type.GetMember(name).FirstOrDefault())?.GetCustomAttributes(typeof(DescriptionAttribute), inherit: false).OfType<DescriptionAttribute>().FirstOrDefault())?.Description ?? value.ToString(); } internal abstract float Build(RectTransform slot, ConfigurationGuiTemplates templates); internal abstract void Refresh(); internal abstract void SetInteractable(bool interactable); internal virtual bool ConsumesEscape() { return false; } internal void ResetToDefault() { Commit(Entry.DefaultValue); } protected void Commit(object value) { try { Pending.Stage(Entry, value); } catch (Exception arg) { Debug.LogError((object)$"[ModUtils] Failed to stage [{Entry.Definition.Section}:{Entry.Definition.Key}]: {arg}"); } Refresh(); } } internal sealed class ConfigurationGuiToggleEditor : ConfigurationGuiEditor { private Toggle _toggle; internal ConfigurationGuiToggleEditor(ConfigEntryBase entry) : base(entry) { } internal override float Build(RectTransform slot, ConfigurationGuiTemplates templates) { //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Expected O, but got Unknown _toggle = ConfigurationGuiTemplates.Clone<Toggle>(templates.Toggle, (Transform)(object)slot, "Toggle"); TMP_Text[] componentsInChildren = ((Component)_toggle).GetComponentsInChildren<TMP_Text>(true); foreach (TMP_Text val in componentsInChildren) { if ((Object)(object)val != (Object)(object)_toggle.graphic) { val.text = ""; } } float num = ConfigurationGuiTemplates.ControlHeight((Component)(object)templates.Toggle); ConfigurationGuiTemplates.FillWidth((RectTransform)((Component)_toggle).transform, num); Refresh(); ((UnityEvent<bool>)(object)_toggle.onValueChanged).AddListener((UnityAction<bool>)delegate(bool value) { Commit(value); }); return num; } internal override void Refresh() { _toggle.SetIsOnWithoutNotify((bool)base.Value); } internal override void SetInteractable(bool interactable) { ((Selectable)_toggle).interactable = interactable; } } internal sealed class ConfigurationGuiSliderEditor : ConfigurationGuiEditor { private const float ValueWidth = 110f; private const float ValueSpacing = 8f; private readonly float _min; private readonly float _max; private readonly bool _wholeNumbers; private ConfigurationGuiInputField _field; private ConfigurationGuiPointerHold _hold; private string _shown = ""; private Slider _slider; internal ConfigurationGuiSliderEditor(ConfigEntryBase entry, float min, float max, bool wholeNumbers) : base(entry) { _min = min; _max = max; _wholeNumbers = wholeNumbers; } internal override float Build(RectTransform slot, ConfigurationGuiTemplates templates) { //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Expected O, but got Unknown //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_0114: 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_0129: 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_013e: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Unknown result type (might be due to invalid IL or missing references) float num = ConfigurationGuiTemplates.ControlHeight((Component)(object)templates.Slider); _slider = ConfigurationGuiTemplates.Clone<Slider>(templates.Slider, (Transform)(object)slot, "Slider"); TMP_Text[] componentsInChildren = ((Component)_slider).GetComponentsInChildren<TMP_Text>(true); for (int i = 0; i < componentsInChildren.Length; i++) { componentsInChildren[i].text = ""; } RectTransform val = (RectTransform)((Component)_slider).transform; ConfigurationGuiTemplates.FillWidth(val, num); val.offsetMax = new Vector2(-118f, val.offsetMax.y); Navigation navigation = ((Selectable)_slider).navigation; ((Navigation)(ref navigation)).mode = (Mode)2; ((Selectable)_slider).navigation = navigation; _slider.wholeNumbers = _wholeNumbers; _slider.minValue = _min; _slider.maxValue = _max; _field = ConfigurationGuiInputField.Create(templates, (Transform)(object)slot, "Value", OnEditFinished); RectTransform val2 = (RectTransform)((Component)_field.Input).transform; val2.anchorMin = new Vector2(1f, 0.5f); val2.anchorMax = new Vector2(1f, 0.5f); val2.pivot = new Vector2(1f, 0.5f); val2.sizeDelta = new Vector2(110f, num); val2.anchoredPosition = Vector2.zero; _hold = ((Component)_slider).gameObject.AddComponent<ConfigurationGuiPointerHold>(); _hold.Released = OnReleased; Refresh(); ((UnityEvent<float>)(object)_slider.onValueChanged).AddListener((UnityAction<float>)OnValueChanged); ((UnityEvent<string>)(object)_field.Input.onValueChanged).AddListener((UnityAction<string>)OnTextChanged); return num; } internal override void Refresh() { object value = base.Value; if (_wholeNumbers) { int num = (int)value; _slider.SetValueWithoutNotify((float)num); _shown = num.ToString(CultureInfo.InvariantCulture); } else { float valueWithoutNotify = (float)value; _slider.SetValueWithoutNotify(valueWithoutNotify); _shown = valueWithoutNotify.ToString(CultureInfo.InvariantCulture); } _field.Input.SetTextWithoutNotify(_shown); } internal override void SetInteractable(bool interactable) { ((Selectable)_slider).interactable = interactable; ((Selectable)_field.Input).interactable = interactable; } internal override bool ConsumesEscape() { return _field.ConsumesEscape(); } private void OnValueChanged(float value) { _field.Input.SetTextWithoutNotify(_wholeNumbers ? Mathf.RoundToInt(value).ToString(CultureInfo.InvariantCulture) : FloorToHundredths(value).ToString(CultureInfo.InvariantCulture)); if (!_hold.IsHeld) { Commit(ToEntryValue(value)); } } private void OnReleased() { if (((Selectable)_slider).interactable) { Commit(ToEntryValue(_slider.value)); } } private void OnTextChanged(string text) { if (ConfigurationGuiInputField.TryParseNumber(text, _wholeNumbers, out var value)) { _slider.SetValueWithoutNotify(Mathf.Clamp(_wholeNumbers ? ((float)(int)value) : ((float)value), _min, _max)); } } private void OnEditFinished(string text) { object value; if (string.Equals(text, _shown, StringComparison.Ordinal)) { Refresh(); } else if (ConfigurationGuiInputField.TryParseNumber(text, _wholeNumbers, out value)) { Commit(value); } else { Refresh(); } } private object ToEntryValue(float value) { if (_wholeNumbers) { return Mathf.RoundToInt(value); } return FloorToHundredths(value); } private static float FloorToHundredths(float value) { return Mathf.Floor(value * 100f + 0.001f) / 100f; } } internal sealed class ConfigurationGuiDropdownEditor : ConfigurationGuiEditor { private readonly List<object> _values = new List<object>(); private TMP_Dropdown _dropdown; internal ConfigurationGuiDropdownEditor(ConfigEntryBase entry) : base(entry) { } internal override float Build(RectTransform slot, ConfigurationGuiTemplates templates) { //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Expected O, but got Unknown //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_009f: 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_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) _dropdown = ConfigurationGuiTemplates.Clone<TMP_Dropdown>(templates.Dropdown, (Transform)(object)slot, "Dropdown"); HideVanillaTitle(_dropdown); float num = ConfigurationGuiTemplates.ControlHeight((Component)(object)templates.Dropdown); ConfigurationGuiTemplates.FillWidth((RectTransform)((Component)_dropdown).transform, num); TMP_Text captionText = _dropdown.captionText; captionText.enableAutoSizing = false; captionText.fontSize = templates.Label.fontSize; captionText.textWrappingMode = (TextWrappingModes)0; captionText.overflowMode = (TextOverflowModes)3; RectTransform rectTransform = captionText.rectTransform; rectTransform.anchorMin = new Vector2(rectTransform.anchorMin.x, 0f); rectTransform.anchorMax = new Vector2(rectTransform.anchorMax.x, 1f); rectTransform.offsetMin = new Vector2(rectTransform.offsetMin.x, 0f); rectTransform.offsetMax = new Vector2(rectTransform.offsetMax.x, 0f); captionText.margin = new Vector4(captionText.margin.x, 0f, captionText.margin.z, 0f); Type type = base.Entry.SettingType; ConfigDescription description = base.Entry.Description; AcceptableValueBase val = ((description != null) ? description.AcceptableValues : null); foreach (object value in Enum.GetValues(type)) { if (val == null || val.IsValid(value)) { _values.Add(value); } } _dropdown.ClearOptions(); _dropdown.AddOptions(_values.Select((object x) => ConfigurationGuiEditor.GetEnumLabel(type, x)).ToList()); Refresh(); ((UnityEvent<int>)(object)_dropdown.onValueChanged).AddListener((UnityAction<int>)OnValueChanged); return num; } private static void HideVanillaTitle(TMP_Dropdown dropdown) { List<Transform> list = new List<Transform>(); if ((Object)(object)dropdown.captionText != (Object)null) { list.Add(dropdown.captionText.transform); } if ((Object)(object)dropdown.itemText != (Object)null) { list.Add(dropdown.itemText.transform); } TMP_Text[] componentsInChildren = ((Component)dropdown).GetComponentsInChildren<TMP_Text>(true); foreach (TMP_Text text in componentsInChildren) { Transform transform = text.transform; if ((!((Object)(object)dropdown.template != (Object)null) || !transform.IsChildOf((Transform)(object)dropdown.template)) && !list.Any((Transform x) => x.IsChildOf(transform))) { if (((Component)transform).GetComponentsInChildren<Graphic>(true).Any((Graphic x) => (Object)(object)x != (Object)(object)text && !(x is TMP_SubMeshUI))) { text.text = ""; } else { ((Component)text).gameObject.SetActive(false); } } } } internal override void Refresh() { object value = base.Value; int num = _values.IndexOf(value); if (num < 0) { _values.Add(value); _dropdown.AddOptions(new List<string> { ConfigurationGuiEditor.GetEnumLabel(base.Entry.SettingType, value) }); num = _values.Count - 1; } _dropdown.SetValueWithoutNotify(num); } internal override void SetInteractable(bool interactable) { ((Selectable)_dropdown).interactable = interactable; } private void OnValueChanged(int index) { if (index >= 0 && index < _values.Count) { Commit(_values[index]); } } } internal sealed class ConfigurationGuiReadOnlyEditor : ConfigurationGuiEditor { private const int MaxLength = 120; private ConfigurationGuiSwatch _swatch; private TMP_Text _text; internal override bool IsEditable => false; internal ConfigurationGuiReadOnlyEditor(ConfigEntryBase entry) : base(entry) { } internal override float Build(RectTransform slot, ConfigurationGuiTemplates templates) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Expected O, but got Unknown _text = (TMP_Text)(object)ConfigurationGuiTemplates.CreateText((Transform)(object)slot, "Value", templates.Label); RectTransform val = (RectTransform)_text.transform; ConfigurationGuiTemplates.Stretch(val, 0f, 0f, 0f, 0f); if (base.Entry.SettingType == typeof(Color)) { _swatch = ConfigurationGuiSwatch.Create(slot, val, 30f); } Refresh(); return 30f; } internal override void Refresh() { //IL_007f: Unknown result type (might be due to invalid IL or missing references) object value = base.Value; string text; try { text = TomlTypeConverter.ConvertToString(value, base.Entry.SettingType); } catch (Exception) { text = value?.ToString(); } text = (text ?? "").Replace('\r', ' ').Replace('\n', ' '); _text.text = ((text.Length > 120) ? (text.Substring(0, 120) + "...") : text); _swatch?.Show((Color)value); } internal override void SetInteractable(bool interactable) { } } internal sealed class ConfigurationGuiSwatch { private const float Margin = 3f; private const float Spacing = 8f; private const float FrameWidth = 2f; private static readonly Color FrameColor = new Color(0.05f, 0.05f, 0.05f, 0.9f); private static readonly Regex ColorCodePattern = new Regex("^#([0-9A-Fa-f]{6}|[0-9A-Fa-f]{8})$"); private readonly Image _fill; private ConfigurationGuiSwatch(Image fill) { _fill = fill; } internal static bool IsColorCode(object value) { if (value is string input) { return ColorCodePattern.IsMatch(input); } return false; } internal static bool TryParseColor(string value, out Color color) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) color = default(Color); if (string.IsNullOrWhiteSpace(value)) { return false; } string text = value.Trim(); if (!text.StartsWith("#", StringComparison.Ordinal)) { text = "#" + text; } return ColorUtility.TryParseHtmlString(text, ref color); } internal static ConfigurationGuiSwatch Create(RectTransform slot, RectTransform beside, float height) { //IL_001f: 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_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: 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) float num = height - 6f; RectTransform val = ConfigurationGuiTemplates.CreateRect("Swatch", (Transform)(object)slot); val.anchorMin = new Vector2(1f, 0.5f); val.anchorMax = new Vector2(1f, 0.5f); val.pivot = new Vector2(1f, 0.5f); val.sizeDelta = new Vector2(num, num); val.anchoredPosition = Vector2.zero; Image obj = ((Component)val).gameObject.AddComponent<Image>(); ((Graphic)obj).color = FrameColor; ((Graphic)obj).raycastTarget = false; RectTransform obj2 = ConfigurationGuiTemplates.CreateRect("Fill", (Transform)(object)val); ConfigurationGuiTemplates.Stretch(obj2, 2f, 2f, 2f, 2f); Image obj3 = ((Component)obj2).gameObject.AddComponent<Image>(); ((Graphic)obj3).color = Color.clear; ((Graphic)obj3).raycastTarget = false; beside.offsetMax = new Vector2(0f - (num + 8f), beside.offsetMax.y); return new ConfigurationGuiSwatch(obj3); } internal void Show(Color color) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) ((Graphic)_fill).color = color; } internal void Show(string text) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) ((Graphic)_fill).color = (TryParseColor(text, out var color) ? color : Color.clear); } } internal sealed class ConfigurationGuiPointerHold : MonoBehaviour, IPointerDownHandler, IEventSystemHandler, IPointerUpHandler { internal Action Released; internal bool IsHeld { get; private set; } public void OnPointerDown(PointerEventData eventData) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) if ((int)eventData.button == 0) { IsHeld = true; } } public void OnPointerUp(PointerEventData eventData) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) if (IsHeld && (int)eventData.button == 0) { IsHeld = false; Released?.Invoke(); } } private void OnDisable() { IsHeld = false; } } internal sealed class ConfigurationGuiFullDescription { private const int Padding = 12; private const float Spacing = 4f; private const float TextScale = 0.9f; private readonly RectTransform _root; private readonly TMP_Text _text; private readonly TMP_Text _topic; private ConfigurationGuiFullDescription(RectTransform root, TMP_Text topic, TMP_Text text) { _root = root; _topic = topic; _text = text; } internal static ConfigurationGuiFullDescription Create(Transform panel, ConfigurationGuiTemplates templates) { //IL_0072: 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_0088: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Expected O, but got Unknown if ((Object)(object)templates.TooltipFrame == (Object)null) { return null; } RectTransform val = ConfigurationGuiTemplates.CreateRect("FullDescriptionLayer", panel); ConfigurationGuiTemplates.AddLayout(((Component)val).gameObject).ignoreLayout = true; ConfigurationGuiTemplates.Stretch(val, 0f, 0f, 0f, 0f); RectTransform val2 = ConfigurationGuiTemplates.CreateRect("FullDescription", (Transform)(object)val); val2.anchorMin = Vector2.zero; val2.anchorMax = Vector2.zero; val2.pivot = Vector2.zero; VerticalLayoutGroup obj = ((Component)val2).gameObject.AddComponent<VerticalLayoutGroup>(); ((LayoutGroup)obj).padding = new RectOffset(12, 12, 12, 12); ((HorizontalOrVerticalLayoutGroup)obj).spacing = 4f; ((HorizontalOrVerticalLayoutGroup)obj).childControlWidth = true; ((HorizontalOrVerticalLayoutGroup)obj).childControlHeight = true; ((HorizontalOrVerticalLayoutGroup)obj).childForceExpandWidth = true; ((HorizontalOrVerticalLayoutGroup)obj).childForceExpandHeight = false; ((Component)val2).gameObject.AddComponent<ContentSizeFitter>().verticalFit = (FitMode)2; ((Component)val2).gameObject.AddComponent<CanvasGroup>().blocksRaycasts = false; Image val3 = ConfigurationGuiTemplates.Clone<Image>(templates.TooltipFrame, (Transform)(object)val2, "Frame"); for (int num = ((Component)val3).transform.childCount - 1; num >= 0; num--) { Object.Destroy((Object)(object)((Component)((Component)val3).transform.GetChild(num)).gameObject); } ((Graphic)val3).raycastTarget = false; ConfigurationGuiTemplates.AddLayout(((Component)val3).gameObject).ignoreLayout = true; ConfigurationGuiTemplates.Stretch(((Graphic)val3).rectTransform, 0f, 0f, 0f, 0f); TextMeshProUGUI val4 = ConfigurationGuiTemplates.CreateText((Transform)(object)val2, "Topic", templates.Label); ((TMP_Text)val4).fontStyle = (FontStyles)1; TextMeshProUGUI val5 = ConfigurationGuiTemplates.CreateText((Transform)(object)val2, "Text", templates.Label, 0.9f); TextMeshProUGUI[] array = (TextMeshProUGUI[])(object)new TextMeshProUGUI[2] { val4, val5 }; foreach (TextMeshProUGUI obj2 in array) { ((TMP_Text)obj2).textWrappingMode = (TextWrappingModes)1; ((TMP_Text)obj2).overflowMode = (TextOverflowModes)0; ((TMP_Text)obj2).alignment = (TextAlignmentOptions)257; } ((Component)val2).gameObject.SetActive(false); return new ConfigurationGuiFullDescription(val2, (TMP_Text)(object)val4, (TMP_Text)(object)val5); } internal void Show(RectTransform area, string topic, string text) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) _topic.text = topic; _text.text = text; Vector3[] array = (Vector3[])(object)new Vector3[4]; area.GetWorldCorners(array); ((Transform)_root).position = array[0]; RectTransform root = _root; Rect rect = area.rect; root.SetSizeWithCurrentAnchors((Axis)0, ((Rect)(ref rect)).width); ((Component)_root).gameObject.SetActive(true); } internal void Hide() { ((Component)_root).gameObject.SetActive(false); } } internal sealed class ConfigurationGuiKeyEditor : ConfigurationGuiEditor { private const float ClearWidth = 110f; private const float Spacing = 8f; private static ConfigurationGuiKeyEditor _capturing; private readonly bool _shortcut; private Button _button; private ConfigurationGuiKeyCapture _capture; private Button _clear; private int _endFrame = -1; private bool IsCapturing => _capturing == this; internal ConfigurationGuiKeyEditor(ConfigEntryBase entry, bool shortcut) : base(entry) { _shortcut = shortcut; } internal override float Build(RectTransform slot, ConfigurationGuiTemplates templates) { //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Expected O, but got Unknown //IL_017c: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Expected O, but got Unknown float num = ConfigurationGuiTemplates.ControlHeight((Component)(object)templates.Button); HorizontalLayoutGroup obj = ((Component)slot).gameObject.AddComponent<HorizontalLayoutGroup>(); ((HorizontalOrVerticalLayoutGroup)obj).spacing = 8f; ((LayoutGroup)obj).childAlignment = (TextAnchor)3; ((HorizontalOrVerticalLayoutGroup)obj).childControlWidth = true; ((HorizontalOrVerticalLayoutGroup)obj).childControlHeight = true; ((HorizontalOrVerticalLayoutGroup)obj).childForceExpandWidth = false; ((HorizontalOrVerticalLayoutGroup)obj).childForceExpandHeight = false; _button = ConfigurationGuiTemplates.Clone<Button>(templates.Button, (Transform)(object)slot, "Key"); ConfigurationGuiTemplates.SetFixedButtonLabel(_button, templates.Label, 0f, (TextAlignmentOptions)514); ConfigurationGuiTemplates.AddLayout(((Component)_button).gameObject, 0f, -1f, 0f, num, 1f); _capture = ((Component)_button).gameObject.AddComponent<ConfigurationGuiKeyCapture>(); ((Behaviour)_capture).enabled = false; _capture.Owner = this; ((UnityEvent)_button.onClick).AddListener(new UnityAction(StartCapture)); if (_shortcut) { _clear = ConfigurationGuiTemplates.Clone<Button>(templates.Button, (Transform)(object)slot, "Clear"); ConfigurationGuiTemplates.SetLabel((Component)(object)_clear, ConfigurationGui.Translate("@config_gui_clear")); ConfigurationGuiTemplates.SetFixedButtonLabel(_clear, templates.Label, 110f, (TextAlignmentOptions)514); ConfigurationGuiTemplates.AddLayout(((Component)_clear).gameObject, 110f, -1f, 110f, num); ((UnityEvent)_clear.onClick).AddListener((UnityAction)delegate { //IL_0007: Unknown result type (might be due to invalid IL or missing references) StopCapture(); Commit(KeyboardShortcut.Empty); }); } Refresh(); return num; } internal override void Refresh() { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) ConfigurationGuiTemplates.SetLabel(label: IsCapturing ? ConfigurationGui.Translate("@config_gui_press_key") : ((!_shortcut) ? base.Value.ToString() : ((object)(KeyboardShortcut)base.Value/*cast due to .constrained prefix*/).ToString()), component: (Component)(object)_button); } internal override void SetInteractable(bool interactable) { ((Selectable)_button).interactable = interactable; if ((Object)(object)_clear != (Object)null) { ((Selectable)_clear).interactable = interactable; } } internal override bool ConsumesEscape() { if (!IsCapturing) { return _endFrame == Time.frameCount; } return true; } internal void StopCapture() { if (IsCapturing) { _capturing = null; _endFrame = Time.frameCount; if ((Object)(object)_capture != (Object)null) { ((Behaviour)_capture).enabled = false; } if ((Object)(object)_button != (Object)null) { Refresh(); } } } internal void FinishCapture(KeyCode key, KeyCode[] heldKeys) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) StopCapture(); Commit(_shortcut ? ((object)new KeyboardShortcut(key, heldKeys)) : ((object)key)); } private void StartCapture() { if (!IsCapturing) { if (_capturing != null) { _capturing.StopCapture(); } _capturing = this; if ((Object)(object)EventSystem.current != (Object)null) { EventSystem.current.SetSelectedGameObject((GameObject)null); } _capture.Begin(); Refresh(); } } } internal sealed class ConfigurationGuiKeyCapture : MonoBehaviour { private static KeyCode[] _keys; internal ConfigurationGuiKeyEditor Owner; private int _startFrame; private static KeyCode[] Keys => _keys ?? (_keys = UnityInput.Current.SupportedKeyCodes.Except((IEnumerable<KeyCode>)(object)new KeyCode[3] { default(KeyCode), (KeyCode)323, (KeyCode)27 }).ToArray()); internal void Begin() { _startFrame = Time.frameCount; ((Behaviour)this).enabled = true; } private void Update() { //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) if (Owner == null || Time.frameCount == _startFrame) { return; } if (ZInput.GetKeyDown((KeyCode)27, true)) { Owner.StopCapture(); return; } IInputSystem current = UnityInput.Current; KeyCode[] keys = Keys; foreach (KeyCode val in keys) { if (current.GetKeyUp(val)) { Owner.FinishCapture(val, ((IEnumerable<KeyCode>)Keys).Where((Func<KeyCode, bool>)current.GetKey).ToArray()); break; } } } private void OnDisable() { if (Owner != null) { Owner.StopCapture(); } } } internal sealed class ConfigurationGuiPanel : MonoBehaviour { private sealed class Section { internal string Category { get; } internal Button Header { get; } internal TMP_Text HeaderLabel { get; } internal RectTransform Body { get; } internal List<Row> Rows { get; } = new List<Row>(); internal bool Collapsed { get; set; } internal bool CollapsedInSearch { get; set; } internal Section(string category, Button header, TMP_Text headerLabel, RectTransform body) { Category = category; Header = header; HeaderLabel = headerLabel; Body = body; } } private sealed class Row { internal ConfigEntryBase Entry { get; } internal int Index { get; } internal string Category { get; } internal string Name { get; } internal string Description { get; } internal int Order { get; } internal bool ReadOnly { get; } internal bool Advanced { get; } internal GameObject Object { get; set; } internal ConfigurationGuiEditor Editor { get; set; } internal bool Editable { get; set; } private Row(ConfigEntryBase entry, int index, string category, string name, string description, int order, bool readOnly, bool advanced) { Entry = entry; Index = index; Category = category; Name = name; Description = description; Order = order; ReadOnly = readOnly; Advanced = advanced; } internal static Row Create(ConfigEntryBase entry, int index) { ConfigurationManagerAttributes attributes = GetAttributes(entry); if (attributes != null && attributes.Browsable == false) { return null; } ConfigDefinition definition = entry.Definition; string category = (string.IsNullOrEmpty(attributes?.Category) ? definition.Section : attributes.Category); string name = (string.IsNullOrEmpty(attributes?.DispName) ? definition.Key : attributes.DispName); object obj; if (!string.IsNullOrEmpty(attributes?.Description)) { obj = attributes.Description; } else { ConfigDescription description = entry.Description; obj = ((description != null) ? description.Description : null); } string text = (string)obj; return new Row(entry, index, category, name, text ?? "", (attributes?.Order).GetValueOrDefault(), attributes != null && attributes.ReadOnly == true, attributes != null && attributes.IsAdvanced == true); } internal bool Matches(string[] terms) { ConfigDefinition definition = Entry.Definition; return terms.All((string x) => Contains(Name, x) || Contains(Category, x) || Contains(Description, x) || Contains(definition.Section, x) || Contains(definition.Key, x)); } private static bool Contains(string text, string term) { if (text != null) { return text.IndexOf(term, StringComparison.OrdinalIgnoreCase) >= 0; } return false; } } private const float Padding = 8f; private const float Spacing = 6f; private const float RowMinHeight = 34f; private const int RowPadding = 2; private const float RowSpacing = 8f; private const float SectionRowSpacing = 2f; private const float SectionHeaderHeight = 36f; private const int WheelStepRows = 3; private const float NameMinWidth = 120f; private const float EditorMinWidth = 200f; private const float ResetWidth = 120f; private const float ScrollMinHeight = 120f; private const float ScrollbarSpacing = 4f; private const float DescriptionLines = 3.6f; private const float UnfoldDelay = 1.5f; private const float BackMinWidth = 120f; private const float BackMaxWidth = 260f; private const int RowsPerFrame = 16; private static bool _showAdvanced; private readonly List<Row> _rows = new List<Row>(); private readonly List<Section> _sections = new List<Section>(); private readonly Queue<(Section Section, Row Row)> _unbuiltRows = new Queue<(Section, Row)>(); private Button _apply; private bool _closed; private TMP_Text _description; private ConfigurationGuiFullDescription _fullDescription; private ConfigurationGuiRowHover _hoveredRow; private GameObject _list; private GameObject _panels; private ConfigurationGuiPendingValues _pending; private bool _prompting; private Button _resetAll; private ConfigurationGuiInputField _search; private bool _searching; private string[] _searchTerms = Array.Empty<string>(); private ConfigurationGuiTemplates _templates; private float _unfoldTime = float.PositiveInfinity; internal ConfigurationGuiRowHover HoveredRow => _hoveredRow; internal static void Open(ConfigurationGuiPlugin plugin, RectTransform page) { GameObject val = null; try { Settings instance = Settings.instance; Transform val2 = ConfigurationGui.FindChild((Transform)(object)page, "List"); Transform val3 = ConfigurationGui.FindChild((Transform)(object)page, "Panels"); if (!((Object)(object)instance == (Object)null) && !((Object)(object)val2 == (Object)null) && !((Object)(object)val3 == (Object)null)) { ConfigurationGuiTemplates configurationGuiTemplates = ConfigurationGuiTemplates.Find(instance); if ((Object)(object)configurationGuiTemplates.Label == (Object)null || (Object)(object)configurationGuiTemplates.Button == (Object)null) { Debug.LogWarning((object)"[ModUtils] The settings screen has no label or button to copy. The mod panel cannot be shown."); return; } RectTransform obj = ConfigurationGuiTemplates.CreateRect(plugin.Guid, val3); val = ((Component)obj).gameObject; ConfigurationGuiTemplates.Stretch(obj, 0f, 0f, 0f, 0f); ConfigurationGuiPanel configurationGuiPanel = val.AddComponent<ConfigurationGuiPanel>(); configurationGuiPanel._list = ((Component)val2).gameObject; configurationGuiPanel._panels = ((Component)val3).gameObject; configurationGuiPanel.Build(plugin, configurationGuiTemplates); ((Component)val2).gameObject.SetActive(false); ((Component)val3).gameObject.SetActive(true); instance.BlockNavigation(true); } } catch (Exception arg) { if ((Object)(object)val != (Object)null) { Object.Destroy((Object)(object)val); } Debug.LogError((object)$"[ModUtils] Failed to open the configuration panel of {plugin.Name}: {arg}"); } } internal bool IsEscapeConsumed() { if (_search != null && _search.ConsumesEscape()) { return true; } foreach (Row row in _rows) { if (row.Editor.ConsumesEscape()) { return true; } } return false; } internal void ShowDescription(ConfigurationGuiRowHover row) { string text = (((Object)(object)row != (Object)null) ? row.Description : ""); if ((Object)(object)_description != (Object)null) { _description.text = text ?? ""; } _hoveredRow = row; _unfoldTime = (string.IsNullOrEmpty(text) ? float.PositiveInfinity : (Time.unscaledTime + 1.5f)); _fullDescription?.Hide(); } private void UnfoldDescription() { _unfoldTime = float.PositiveInfinity; if (!IsEditingText()) { _description.ForceMeshUpdate(false, false); if (_description.isTextTruncated) { _fullDescription?.Show(_description.rectTransform, _hoveredRow.RowName, _description.text); } } } private static bool IsEditingText() { GameObject val = (((Object)(object)EventSystem.current !=