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 ConfigManager v1.0.9
ConfigManager.dll
Decompiled 3 days ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Text; using System.Threading; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using ConfigurationManager.Utilities; using HarmonyLib; using TMPro; using UnityEngine; using UnityEngine.Events; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("ConfigManager")] [assembly: AssemblyDescription("Standalone Valheim configuration manager")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("sighsorry")] [assembly: AssemblyMetadata("Author", "sighsorry")] [assembly: AssemblyProduct("ConfigManager")] [assembly: AssemblyCopyright("Copyright © 2018-2026 ConfigManager contributors; modifications © 2026 sighsorry")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("0bac4d10-1d45-4b13-861c-48bae48536e9")] [assembly: AssemblyFileVersion("1.0.9")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyVersion("1.0.9.0")] public struct HSLColor { public float h; public float s; public float l; public float a; public HSLColor(float h, float s, float l, float a) { this.h = h; this.s = s; this.l = l; this.a = a; } public HSLColor(float h, float s, float l) { this.h = h; this.s = s; this.l = l; a = 1f; } public HSLColor(Color c) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) HSLColor hSLColor = FromRGBA(c); h = hSLColor.h; s = hSLColor.s; l = hSLColor.l; a = hSLColor.a; } public static HSLColor FromRGBA(Color c) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: 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_00a4: 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_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) float num = c.a; float num2 = Mathf.Min(Mathf.Min(c.r, c.g), c.b); float num3 = Mathf.Max(Mathf.Max(c.r, c.g), c.b); float num4 = (num2 + num3) / 2f; float num5; float num6; if (num2 == num3) { num5 = 0f; num6 = 0f; } else { float num7 = num3 - num2; num5 = ((num4 <= 0.5f) ? (num7 / (num3 + num2)) : (num7 / (2f - (num3 + num2)))); num6 = 0f; if (c.r == num3) { num6 = (c.g - c.b) / num7; } else if (c.g == num3) { num6 = 2f + (c.b - c.r) / num7; } else if (c.b == num3) { num6 = 4f + (c.r - c.g) / num7; } num6 = Mathf.Repeat(num6 * 60f, 360f); } return new HSLColor(num6, num5, num4, num); } public Color ToRGBA() { //IL_00b1: Unknown result type (might be due to invalid IL or missing references) float num = a; float num2 = ((l <= 0.5f) ? (l * (1f + s)) : (l + s - l * s)); float n = 2f * l - num2; float num3; float num4; float num5; if (s == 0f) { num3 = (num4 = (num5 = l)); } else { num3 = Value(n, num2, h + 120f); num4 = Value(n, num2, h); num5 = Value(n, num2, h - 120f); } return new Color(num3, num4, num5, num); } private static float Value(float n1, float n2, float hue) { hue = Mathf.Repeat(hue, 360f); if (hue < 60f) { return n1 + (n2 - n1) * hue / 60f; } if (hue < 180f) { return n2; } if (hue < 240f) { return n1 + (n2 - n1) * (240f - hue) / 60f; } return n1; } public static implicit operator HSLColor(Color src) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) return FromRGBA(src); } public static implicit operator Color(HSLColor src) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) return src.ToRGBA(); } } namespace ConfigurationManager { internal sealed class ConfigurationManagerAttributes { public string Category { get; set; } public string DispName { get; set; } public int? CategoryOrder { get; set; } public int? Order { get; set; } public bool? Browsable { get; set; } public bool? IsAdvanced { get; set; } public bool? ReadOnly { get; set; } public bool? HideDefaultButton { get; set; } } internal readonly struct ThemePalette { public Color WindowBackground { get; } public Color EntryBackground { get; } public Color TooltipBackground { get; } public Color HeaderBackground { get; } public Color HeaderHoverBackground { get; } public Color SettingWindowBackground { get; } public Color Widget { get; } public Color Enabled { get; } public Color MainText { get; } public Color DefaultValueText { get; } public Color ChangedValueText { get; } public Color ReadOnlyText { get; } public Color FileEditorText { get; } private ThemePalette(Color windowBackground, Color entryBackground, Color tooltipBackground, Color headerBackground, Color headerHoverBackground, Color settingWindowBackground, Color widget, Color enabled, Color mainText, Color defaultValueText, Color changedValueText, Color readOnlyText, Color fileEditorText) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0026: 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) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003e: 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_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) WindowBackground = windowBackground; EntryBackground = entryBackground; TooltipBackground = tooltipBackground; HeaderBackground = headerBackground; HeaderHoverBackground = headerHoverBackground; SettingWindowBackground = settingWindowBackground; Widget = widget; Enabled = enabled; MainText = mainText; DefaultValueText = defaultValueText; ChangedValueText = changedValueText; ReadOnlyText = readOnlyText; FileEditorText = fileEditorText; } public static ThemePalette CreateValheim() { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: 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) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) return new ThemePalette(new Color(0f, 0f, 0f, 1f), new Color(0.55f, 0.5f, 0.5f, 0.94f), new Color(0.55f, 0.5f, 0.45f, 0.95f), new Color(0.74f, 0.54f, 0.37f, 0.8f), new Color(0.88f, 0.46f, 0f, 0.8f), new Color(0.55f, 0.5f, 0.5f, 0.65f), new Color(0.88f, 0.46f, 0f, 0.8f), new Color(0.88f, 0.46f, 0f, 1f), new Color(1f, 0.827f, 0.463f, 1f), new Color(1f, 0.827f, 0.463f, 1f), new Color(0.9f, 0.9f, 0.9f, 1f), Color.gray, new Color(0.9f, 0.9f, 0.9f, 1f)); } } public class ConfigFilesEditor : IDisposable { private enum FileEditState { None, CreatingFolder, CreatingFile, RenamingFile } private static readonly string _trashBinDirectory = Path.Combine(Paths.CachePath, "ConfigManagerTrashBin"); private static readonly string[] _directories = new string[3] { Paths.ConfigPath, Paths.PluginPath, _trashBinDirectory }; private static readonly HashSet<string> _editableExtensions = new HashSet<string>(StringComparer.OrdinalIgnoreCase) { ".json", ".yaml", ".yml", ".cfg" }; private readonly Dictionary<string, bool> _folderStates = new Dictionary<string, bool>(); private Vector2 _scrollPosition; private string _fileContent; private string _originalFileContent; private Vector2 _textScrollPosition; private Rect _windowRect = new Rect(ConfigurationManager._windowPositionTextEditor.Value, ConfigurationManager._windowSizeTextEditor.Value); private bool _windowGeometryDirty; private bool _windowGeometrySaveFailed; private Vector2? _pendingWindowSize; private const int WindowId = -680; private const string SearchBoxName = "searchBoxEditor"; private const int DirectoryOffset = 20; private const string TextEditorControlName = "textEditorTextField"; private bool _focusSearchBox; private bool _focusTextArea; private string _searchString; private string _errorText; private string _activeFile; private string _activeDirectory; private string _newItemName; private string _newItemErrorText; private FileEditState _fileNameState; private bool _isOpen; private bool _fileTreeDirty; private bool _watchingEnabled = true; private int _directoryDepth; private readonly Dictionary<string, string[]> _cachedFileTree = new Dictionary<string, string[]>(); private readonly Dictionary<string, string[]> _cachedDirectories = new Dictionary<string, string[]>(); private readonly Dictionary<string, bool> _validFilesThisDraw = new Dictionary<string, bool>(); private readonly Dictionary<string, bool> _validDirectoriesThisDraw = new Dictionary<string, bool>(); private readonly HashSet<string> _pluginConfigPaths = new HashSet<string>(StringComparer.Ordinal); private FileSystemWatcher[] _watchers = Array.Empty<FileSystemWatcher>(); private string SearchString { get { return _searchString; } set { if (value == null) { value = string.Empty; } _searchString = value; } } public bool IsOpen { get { return _isOpen; } set { if (_isOpen != value) { if (!value) { FlushWindowGeometry(); } _isOpen = value; InvalidateFileTree(); UpdateWatcherState(); } } } private void SetFileEditState(FileEditState newState) { _fileNameState = newState; _newItemErrorText = string.Empty; _newItemName = string.Empty; } internal void ResetWindowGeometry() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) _windowRect = new Rect(ConfigurationManager._windowPositionTextEditor.Value, ConfigurationManager._windowSizeTextEditor.Value); _windowGeometryDirty = false; _windowGeometrySaveFailed = false; _pendingWindowSize = null; } internal void FlushWindowGeometry() { if (!_windowGeometryDirty) { return; } try { SaveCurrentSizeAndPosition(); } catch (Exception ex) { _windowGeometrySaveFailed = true; ConfigurationManager.LogWarning("Could not save file editor geometry: " + ex.Message); } } public void OnGUI() { //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0058: 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_001c: 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_00b4: Expected O, but got Unknown //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) if (IsOpen) { if (!_windowGeometryDirty) { ((Rect)(ref _windowRect)).size = ConfigurationManager._windowSizeTextEditor.Value; ((Rect)(ref _windowRect)).position = ConfigurationManager._windowPositionTextEditor.Value; } Color backgroundColor = GUI.backgroundColor; GUI.backgroundColor = ConfigurationManager.Palette.WindowBackground; Rect windowRect = GUI.Window(-680, _windowRect, new WindowFunction(DrawWindow), Utility.IsNullOrWhiteSpace(_activeFile) ? "Configuration Files Editor" : ("..." + _activeFile.Replace(Path.GetDirectoryName(Paths.BepInExRootPath) ?? string.Empty, "")), ConfigurationManagerStyles.GetWindowStyle()); if (_pendingWindowSize.HasValue) { ((Rect)(ref windowRect)).size = _pendingWindowSize.Value; _pendingWindowSize = null; } _windowRect = windowRect; if (((Rect)(ref _windowRect)).position != ConfigurationManager._windowPositionTextEditor.Value) { _windowGeometryDirty = true; } bool mouseButton = UnityInput.Current.GetMouseButton(0); if (mouseButton) { _windowGeometrySaveFailed = false; } if (_windowGeometryDirty && !mouseButton && !_windowGeometrySaveFailed) { FlushWindowGeometry(); } GUI.backgroundColor = backgroundColor; } } internal void SaveCurrentSizeAndPosition() { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) Vector2 size = new Vector2(Mathf.Clamp(((Rect)(ref _windowRect)).size.x, 1000f / ConfigurationManager.instance.ScaleFactor, ConfigurationManager.instance.ScreenWidth), Mathf.Clamp(((Rect)(ref _windowRect)).size.y, 600f / ConfigurationManager.instance.ScaleFactor, ConfigurationManager.instance.ScreenHeight)); Vector2 position = new Vector2(Mathf.Clamp(((Rect)(ref _windowRect)).position.x, 0f, ConfigurationManager.instance.ScreenWidth - ConfigurationManager._windowSize.Value.x / 4f), Mathf.Clamp(((Rect)(ref _windowRect)).position.y, 0f, ConfigurationManager.instance.ScreenHeight - 40f)); ConfigurationManager.SaveWindowConfigChanges(((BaseUnityPlugin)ConfigurationManager.instance).Config, delegate { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) ConfigurationManager._windowSizeTextEditor.Value = size; ConfigurationManager._windowPositionTextEditor.Value = position; }); _windowRect = new Rect(position, size); _windowGeometryDirty = false; _windowGeometrySaveFailed = false; _pendingWindowSize = null; } private void DrawSearchBox() { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); GUILayout.Label("Search:", ConfigurationManagerStyles.GetLabelStyle(), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(ConfigurationManagerStyles.GetLabelStyle().CalcSize(new GUIContent("Search:")).x + 4f) }); GUI.SetNextControlName("searchBoxEditor"); SearchString = GUILayout.TextField(SearchString, ConfigurationManagerStyles.GetTextStyle(), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) }); if (_focusSearchBox) { GUI.FocusWindow(-680); GUI.FocusControl("searchBoxEditor"); _focusSearchBox = false; } Color backgroundColor = GUI.backgroundColor; GUI.backgroundColor = ConfigurationManager.Palette.Widget; if (GUILayout.Button("Clear", ConfigurationManagerStyles.GetButtonStyle(), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(false) })) { SearchString = string.Empty; } GUI.backgroundColor = backgroundColor; GUILayout.EndHorizontal(); } private void DrawContentButtons() { GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); GUI.enabled = !Utility.IsNullOrWhiteSpace(_activeFile) && _fileContent != _originalFileContent; if (GUILayout.Button("Save", ConfigurationManagerStyles.GetButtonStyle(), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(false) })) { SaveActiveFile(); } GUI.enabled = true; GUILayout.Label(_errorText, ConfigurationManagerStyles.GetLabelStyle(isDefaultValue: false), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) }); GUILayout.Label("Font size: ", ConfigurationManagerStyles.GetLabelStyle(), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(false) }); if (int.TryParse(GUILayout.TextField(StringExtensionMethods.ToFastString(ConfigurationManager._textEditorFontSize.Value), ConfigurationManagerStyles.GetTextStyle((float)ConfigurationManager._textEditorFontSize.Value, (float)(int)((ConfigEntryBase)ConfigurationManager._textEditorFontSize).DefaultValue), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(30f) }), out var result)) { ConfigurationManager._textEditorFontSize.Value = Mathf.Clamp(result, 8, 36); } ConfigurationManager._textEditorWordWrap.Value = GUILayout.Toggle(ConfigurationManager._textEditorWordWrap.Value, "Word wrap", ConfigurationManagerStyles.GetToggleStyle(), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(false) }); if (GUILayout.Button("Close", ConfigurationManagerStyles.GetButtonStyle(), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(false) })) { IsOpen = false; } GUILayout.EndHorizontal(); } private void DrawWindow(int windowID) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_01ae: Unknown result type (might be due to invalid IL or missing references) //IL_01d3: Unknown result type (might be due to invalid IL or missing references) //IL_01f2: Unknown result type (might be due to invalid IL or missing references) //IL_01f9: Unknown result type (might be due to invalid IL or missing references) //IL_01fe: Unknown result type (might be due to invalid IL or missing references) //IL_01e5: Unknown result type (might be due to invalid IL or missing references) //IL_0263: Unknown result type (might be due to invalid IL or missing references) //IL_0274: Unknown result type (might be due to invalid IL or missing references) ConfigurationManagerStyles.DrawWindowBackgroundDimming(((Rect)(ref _windowRect)).size); GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); Color backgroundColor = GUI.backgroundColor; GUI.backgroundColor = ConfigurationManager.Palette.EntryBackground; GUILayout.BeginVertical(ConfigurationManagerStyles.GetBackgroundStyle(), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.MaxWidth(GetFileListWidth()) }); DrawSearchBox(); _scrollPosition = GUILayout.BeginScrollView(_scrollPosition, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(((Rect)(ref _windowRect)).width * 0.3f) }); _directoryDepth = 0; PrepareFileTreeDraw(); DrawDirectories(_directories); GUILayout.EndScrollView(); DrawDirectoriesMenu(); GUILayout.EndVertical(); GUILayout.BeginVertical(ConfigurationManagerStyles.GetBackgroundStyle(), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.MaxWidth(((Rect)(ref _windowRect)).width * 0.7f) }); DrawContentButtons(); _textScrollPosition = GUILayout.BeginScrollView(_textScrollPosition, Array.Empty<GUILayoutOption>()); GUI.enabled = File.Exists(_activeFile); GUI.SetNextControlName("textEditorTextField"); _fileContent = GUILayout.TextArea(_fileContent, ConfigurationManagerStyles.GetFileEditorTextArea(), (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.ExpandHeight(true), GUILayout.ExpandWidth(true) }); if (_focusTextArea || GUI.GetNameOfFocusedControl() == "textEditorTextField") { GUI.FocusWindow(-680); GUI.FocusControl("textEditorTextField"); _focusTextArea = false; } GUI.enabled = true; GUILayout.EndScrollView(); if (ConfigurationManager._showFullName.Value) { GUILayout.TextField(_activeFile, ConfigurationManagerStyles.GetTextStyle(), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) }); } GUILayout.EndVertical(); GUI.backgroundColor = backgroundColor; GUILayout.EndHorizontal(); GUI.DragWindow(new Rect(0f, 0f, ((Rect)(ref _windowRect)).width, 20f)); if (!SettingFieldDrawer.DrawCurrentDropdown()) { ConfigurationManager.DrawTooltip(_windowRect); } _windowRect = Utils.ResizeWindow(windowID, _windowRect, out var sizeChanged); if (sizeChanged) { ((Rect)(ref _windowRect)).size = new Vector2(Mathf.Clamp(((Rect)(ref _windowRect)).width, 1000f / ConfigurationManager.instance.ScaleFactor, ConfigurationManager.instance.ScreenWidth), Mathf.Clamp(((Rect)(ref _windowRect)).height, 600f / ConfigurationManager.instance.ScaleFactor, ConfigurationManager.instance.ScreenHeight)); _pendingWindowSize = ((Rect)(ref _windowRect)).size; _windowGeometryDirty = true; } } private float GetFileListWidth() { return ((Rect)(ref _windowRect)).width * 0.3f; } private void DrawDirectory(string path) { _directoryDepth++; DrawDirectories(GetDirectories(path)); if (path == _activeDirectory && _fileNameState == FileEditState.CreatingFolder) { DrawFileNameField(); } DrawFiles(path); _directoryDepth--; } private void DrawDirectories(IEnumerable<string> directories) { foreach (string directory in directories) { if ((ConfigurationManager._showTrashBin.Value || !(directory == _trashBinDirectory)) && (ConfigurationManager._showEmptyFolders.Value || DirectoryContainsValidFiles(directory))) { if (!_folderStates.ContainsKey(directory)) { _folderStates[directory] = false; } bool num = _folderStates[directory]; bool flag = (_folderStates[directory] = GUILayout.Toggle(_folderStates[directory], Path.GetFileName(directory), ConfigurationManagerStyles.GetDirectoryStyle(directory == _activeDirectory), Array.Empty<GUILayoutOption>())); if (num != flag && _folderStates[directory]) { _activeDirectory = directory; SetFileEditState(FileEditState.None); } if (_folderStates[directory]) { GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); GUILayout.Space(20f); GUILayout.BeginVertical(Array.Empty<GUILayoutOption>()); DrawDirectory(directory); GUILayout.EndVertical(); GUILayout.EndHorizontal(); } } } } private void DrawFileNameField() { GUILayout.BeginVertical(Array.Empty<GUILayoutOption>()); GUILayout.BeginHorizontal((GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.MaxWidth(GetFileListWidth() - (float)(20 * (_directoryDepth + 1)) - 5f) }); if (_fileNameState == FileEditState.CreatingFolder || _fileNameState == FileEditState.CreatingFile) { GUILayout.Label((_fileNameState == FileEditState.CreatingFolder) ? "Folder:" : "File:", ConfigurationManagerStyles.GetLabelStyle(), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(false) }); } _newItemName = GUILayout.TextField(_newItemName, ConfigurationManagerStyles.GetFileNameFieldStyle(), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) }); if (GUILayout.Button("OK", ConfigurationManagerStyles.GetButtonStyle(), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(false) })) { if (_fileNameState == FileEditState.CreatingFolder || _fileNameState == FileEditState.CreatingFile) { CreateNewItem(_newItemName, _fileNameState == FileEditState.CreatingFolder); } else if (_fileNameState == FileEditState.RenamingFile) { RenameActiveFile(); } } GUILayout.EndHorizontal(); if (!Utility.IsNullOrWhiteSpace(_newItemErrorText)) { GUILayout.Label(_newItemErrorText, ConfigurationManagerStyles.GetFileNameErrorStyle(), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) }); } GUILayout.EndVertical(); } private void RenameActiveFile() { if (_newItemName == Path.GetFileName(_activeFile)) { SetFileEditState(FileEditState.None); return; } string directoryName = Path.GetDirectoryName(_activeFile); if (directoryName == null) { return; } if (!TryGetSafeChildPath(directoryName, _newItemName, out var path)) { _newItemErrorText = "Invalid file name"; return; } if (File.Exists(path) || Directory.Exists(path)) { _newItemErrorText = "File already exists"; return; } try { File.Move(_activeFile, path); InvalidateFileTree(); _activeFile = path; SetFileEditState(FileEditState.None); } catch (Exception ex) { _newItemErrorText = ex.Message; } } private void MoveActiveFileToTrash() { if (Utility.IsNullOrWhiteSpace(_activeFile)) { return; } try { Directory.CreateDirectory(_trashBinDirectory); string text = Path.Combine(_trashBinDirectory, Path.GetFileName(_activeFile)); if (File.Exists(text)) { text = Path.Combine(_trashBinDirectory, $"{Path.GetFileNameWithoutExtension(text)}_{DateTime.UtcNow:yyyyMMdd_HHmmss}_{Guid.NewGuid():N}{Path.GetExtension(text)}"); } File.Move(_activeFile, text); InvalidateFileTree(); _activeFile = string.Empty; _fileContent = string.Empty; _originalFileContent = string.Empty; SetFileEditState(FileEditState.None); } catch (Exception ex) { _newItemErrorText = ex.Message; } } public ConfigFilesEditor() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) InitializeFileWatcher(); } private void InitializeFileWatcher() { _watchers = new FileSystemWatcher[2] { new FileSystemWatcher(Paths.ConfigPath), new FileSystemWatcher(Paths.PluginPath) }; FileSystemWatcher[] watchers = _watchers; foreach (FileSystemWatcher obj in watchers) { obj.IncludeSubdirectories = true; obj.SynchronizingObject = ThreadingHelper.SynchronizingObject; obj.Changed += delegate { InvalidateFileTree(); }; obj.Created += delegate { InvalidateFileTree(); }; obj.Deleted += delegate { InvalidateFileTree(); }; obj.Renamed += delegate { InvalidateFileTree(); }; } } private void InvalidateFileTree() { _fileTreeDirty = true; } internal void SetWatching(bool enabled) { _watchingEnabled = enabled; InvalidateFileTree(); UpdateWatcherState(); } private void UpdateWatcherState() { FileSystemWatcher[] watchers = _watchers; for (int i = 0; i < watchers.Length; i++) { watchers[i].EnableRaisingEvents = _watchingEnabled && IsOpen; } } private void ClearInvalidatedFileTree() { if (_fileTreeDirty) { _cachedFileTree.Clear(); _cachedDirectories.Clear(); _validFilesThisDraw.Clear(); _validDirectoriesThisDraw.Clear(); _fileTreeDirty = false; } } private void PrepareFileTreeDraw() { ClearInvalidatedFileTree(); _validFilesThisDraw.Clear(); _validDirectoriesThisDraw.Clear(); _pluginConfigPaths.Clear(); foreach (PluginInfo value in Chainloader.PluginInfos.Values) { BaseUnityPlugin instance = value.Instance; object obj; if (instance == null) { obj = null; } else { ConfigFile config = instance.Config; obj = ((config != null) ? config.ConfigFilePath : null); } string text = (string)obj; if (text != null) { _pluginConfigPaths.Add(text); } } } private string[] GetFiles(string path) { ClearInvalidatedFileTree(); if (_cachedFileTree.TryGetValue(path, out var value)) { return value; } string[] array; try { array = (Directory.Exists(path) ? Directory.GetFiles(path) : Array.Empty<string>()); } catch (Exception ex) when (ex is IOException || ex is UnauthorizedAccessException) { ConfigurationManager.LogWarning("Could not read files from " + path + ": " + ex.Message); array = Array.Empty<string>(); } _cachedFileTree[path] = array; return array; } private string[] GetDirectories(string path) { ClearInvalidatedFileTree(); if (_cachedDirectories.TryGetValue(path, out var value)) { return value; } string[] array; try { array = (Directory.Exists(path) ? (from directory in Directory.GetDirectories(path) where (File.GetAttributes(directory) & FileAttributes.ReparsePoint) == 0 select directory).ToArray() : Array.Empty<string>()); } catch (Exception ex) when (ex is IOException || ex is UnauthorizedAccessException) { ConfigurationManager.LogWarning("Could not read directories from " + path + ": " + ex.Message); array = Array.Empty<string>(); } _cachedDirectories[path] = array; return array; } private void DrawFiles(string path) { bool flag = false; string[] files = GetFiles(path); foreach (string text in files) { if (IsValidFile(text)) { if (text == _activeFile && _fileNameState == FileEditState.RenamingFile) { DrawFileNameField(); } else if (GUILayout.Button(Path.GetFileName(text), ConfigurationManagerStyles.GetFileStyle(text == _activeFile), Array.Empty<GUILayoutOption>())) { LoadFileToEditor(text); } if (path == _activeDirectory && text == _activeFile && _fileNameState == FileEditState.CreatingFile) { DrawFileNameField(); flag = true; } } } if (!flag && path == _activeDirectory && _fileNameState == FileEditState.CreatingFile) { DrawFileNameField(); } } private bool IsValidFile(string file) { ClearInvalidatedFileTree(); if (_validFilesThisDraw.TryGetValue(file, out var value)) { return value; } value = EvaluateFileVisibility(file); _validFilesThisDraw[file] = value; return value; } private bool EvaluateFileVisibility(string file) { string fileName = Path.GetFileName(file); if (fileName == "manifest.json") { return false; } try { if ((File.GetAttributes(file) & FileAttributes.ReparsePoint) != FileAttributes.None) { return false; } } catch (Exception ex) when (ex is IOException || ex is UnauthorizedAccessException) { return false; } if (string.Equals(fileName, "ConfigManager.hiddensettings.txt", StringComparison.OrdinalIgnoreCase)) { if (!Utility.IsNullOrWhiteSpace(SearchString)) { return fileName.IndexOf(SearchString, StringComparison.OrdinalIgnoreCase) > -1; } return true; } if (_pluginConfigPaths.Contains(file)) { return false; } string extension = Path.GetExtension(file); if (_editableExtensions.Contains(extension)) { if (!Utility.IsNullOrWhiteSpace(SearchString)) { return fileName.IndexOf(SearchString, StringComparison.OrdinalIgnoreCase) > -1; } return true; } return false; } private bool DirectoryContainsValidFiles(string path) { ClearInvalidatedFileTree(); if (_validDirectoriesThisDraw.TryGetValue(path, out var value)) { return value; } value = GetFiles(path).Any(IsValidFile) || GetDirectories(path).Any(DirectoryContainsValidFiles); _validDirectoriesThisDraw[path] = value; return value; } private void LoadFileToEditor(string filePath) { try { _fileContent = File.ReadAllText(filePath); _originalFileContent = _fileContent; _activeFile = filePath; _activeDirectory = Path.GetDirectoryName(filePath); _errorText = string.Empty; SetFileEditState(FileEditState.None); _focusTextArea = true; } catch (Exception ex) when (ex is IOException || ex is UnauthorizedAccessException) { ConfigurationManager.LogError("Failed to load file " + filePath + ": " + ex.Message); _errorText = "Failed to load file"; _fileContent = ex.Message; _originalFileContent = string.Empty; _activeFile = string.Empty; } } private void DrawDirectoriesMenu() { //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Expected O, but got Unknown //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Expected O, but got Unknown GUILayout.BeginVertical(Array.Empty<GUILayoutOption>()); GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); if (GUILayout.Button("New folder", ConfigurationManagerStyles.GetButtonStyle(), Array.Empty<GUILayoutOption>())) { SetFileEditState(FileEditState.CreatingFolder); } if (GUILayout.Button("New file", ConfigurationManagerStyles.GetButtonStyle(), Array.Empty<GUILayoutOption>())) { SetFileEditState(FileEditState.CreatingFile); } if (GUILayout.Button("Rename", ConfigurationManagerStyles.GetButtonStyle(), Array.Empty<GUILayoutOption>())) { SetFileEditState(FileEditState.RenamingFile); _newItemName = Path.GetFileName(_activeFile); } if (GUILayout.Button(new GUIContent("Delete", "File will be moved into Trash Bin"), ConfigurationManagerStyles.GetButtonStyle(), Array.Empty<GUILayoutOption>())) { MoveActiveFileToTrash(); } GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); ConfigurationManager._showEmptyFolders.Value = GUILayout.Toggle(ConfigurationManager._showEmptyFolders.Value, "Show empty folders", ConfigurationManagerStyles.GetToggleStyle(), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) }); GUILayout.FlexibleSpace(); ConfigurationManager._showFullName.Value = GUILayout.Toggle(ConfigurationManager._showFullName.Value, new GUIContent("Show file name", "Show full name of active file"), ConfigurationManagerStyles.GetToggleStyle(), Array.Empty<GUILayoutOption>()); ConfigurationManager._showTrashBin.Value = GUILayout.Toggle(ConfigurationManager._showTrashBin.Value, "Show Trash Bin", ConfigurationManagerStyles.GetToggleStyle(), Array.Empty<GUILayoutOption>()); GUILayout.EndHorizontal(); GUILayout.EndVertical(); } private void CreateNewItem(string itemName, bool isFolder) { if (string.IsNullOrWhiteSpace(itemName) || string.IsNullOrEmpty(_activeDirectory)) { return; } if (!TryGetSafeChildPath(_activeDirectory, itemName, out var path)) { _newItemErrorText = "Invalid file or folder name"; return; } if (File.Exists(path) || Directory.Exists(path)) { _newItemErrorText = "File already exists"; return; } try { if (isFolder) { Directory.CreateDirectory(path); InvalidateFileTree(); ConfigurationManager._showEmptyFolders.Value = true; _activeDirectory = path; _activeFile = string.Empty; } else { using (new FileStream(path, FileMode.CreateNew, FileAccess.Write, FileShare.None)) { } InvalidateFileTree(); LoadFileToEditor(path); } SetFileEditState(FileEditState.None); } catch (Exception ex) { _newItemErrorText = ex.Message; } } private void SaveActiveFile() { string createdPath = null; string createdPath2 = null; bool keepBackup = false; try { if (Utility.IsNullOrWhiteSpace(_activeFile) || !File.Exists(_activeFile)) { _errorText = "The active file no longer exists"; return; } using (FileStream fileStream = new FileStream(_activeFile, FileMode.Open, FileAccess.ReadWrite, FileShare.None)) { string a; using (StreamReader streamReader = new StreamReader(fileStream, Encoding.UTF8, detectEncodingFromByteOrderMarks: true, 1024, leaveOpen: true)) { a = streamReader.ReadToEnd(); } if (!string.Equals(a, _originalFileContent, StringComparison.Ordinal)) { _errorText = "The file changed outside ConfigManager. Reload it before saving."; return; } using FileStream fileStream2 = CreateSaveFile(_activeFile, ".tmp", out createdPath); using FileStream fileStream3 = CreateSaveFile(_activeFile, ".bak", out createdPath2); using (StreamWriter streamWriter = new StreamWriter(fileStream2, new UTF8Encoding(encoderShouldEmitUTF8Identifier: false), 1024, leaveOpen: true)) { streamWriter.Write(_fileContent); streamWriter.Flush(); } fileStream2.Flush(flushToDisk: true); fileStream.Position = 0L; fileStream.CopyTo(fileStream3); fileStream3.Flush(flushToDisk: true); CommitStagedContent(fileStream, fileStream2, fileStream3, out keepBackup); } _originalFileContent = _fileContent; _errorText = string.Empty; } catch (Exception ex) when (ex is IOException || ex is UnauthorizedAccessException) { _errorText = ex.Message; if (keepBackup) { _errorText = _errorText + Environment.NewLine + "Original file backup: " + createdPath2; } } finally { DeleteSaveFile(createdPath); if (!keepBackup) { DeleteSaveFile(createdPath2); } } } private static FileStream CreateSaveFile(string activeFile, string extension, out string createdPath) { string text = Path.Combine(Path.GetDirectoryName(activeFile), ".configmanager-save-" + Guid.NewGuid().ToString("N") + extension); FileStream result = new FileStream(text, FileMode.CreateNew, FileAccess.ReadWrite, FileShare.None); createdPath = text; return result; } private static void CommitStagedContent(Stream destination, Stream staged, Stream backup, out bool keepBackup) { keepBackup = true; try { CopyCompleteContent(staged, destination); keepBackup = false; } catch (Exception ex) when (ex is IOException || ex is UnauthorizedAccessException) { try { CopyCompleteContent(backup, destination); keepBackup = false; } catch (Exception ex2) when (ex2 is IOException || ex2 is UnauthorizedAccessException) { throw new IOException("Saving failed (" + ex.Message + ") and restoring the original failed (" + ex2.Message + ").", new AggregateException(ex, ex2)); } throw; } } private static void CopyCompleteContent(Stream source, Stream destination) { source.Position = 0L; destination.Position = 0L; source.CopyTo(destination); destination.SetLength(destination.Position); if (destination is FileStream fileStream) { fileStream.Flush(flushToDisk: true); } else { destination.Flush(); } } private void DeleteSaveFile(string path) { if (path == null) { return; } try { File.Delete(path); } catch (Exception ex) when (ex is IOException || ex is UnauthorizedAccessException) { string text = "Could not remove temporary save file " + path + ": " + ex.Message; _errorText = (string.IsNullOrEmpty(_errorText) ? text : (_errorText + Environment.NewLine + text)); } } private static bool TryGetSafeChildPath(string directory, string itemName, out string path) { path = null; if (Utility.IsNullOrWhiteSpace(directory) || Utility.IsNullOrWhiteSpace(itemName) || Path.IsPathRooted(itemName)) { return false; } string text = itemName.Trim(); if (text.IndexOfAny(Path.GetInvalidFileNameChars()) >= 0 || text.IndexOf(Path.DirectorySeparatorChar) >= 0 || text.IndexOf(Path.AltDirectorySeparatorChar) >= 0 || text.IndexOf('/') >= 0 || text.IndexOf('\\') >= 0) { return false; } try { string text2 = Path.GetFullPath(directory).TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar); if (!IsPathInsideEditorRoots(text2)) { return false; } string fullPath = Path.GetFullPath(Path.Combine(text2, text)); string b = Path.GetDirectoryName(fullPath)?.TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar); if (!string.Equals(text2, b, GetPathComparison())) { return false; } path = fullPath; return true; } catch (Exception ex) when (ex is ArgumentException || ex is NotSupportedException || ex is PathTooLongException) { return false; } } private static bool IsPathInsideEditorRoots(string path) { string[] directories = _directories; for (int i = 0; i < directories.Length; i++) { string text = Path.GetFullPath(directories[i]).TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar); if (string.Equals(path, text, GetPathComparison()) || path.StartsWith(text + Path.DirectorySeparatorChar, GetPathComparison())) { return true; } } return false; } private static StringComparison GetPathComparison() { if (Path.DirectorySeparatorChar != '\\') { return StringComparison.Ordinal; } return StringComparison.OrdinalIgnoreCase; } public void Dispose() { FlushWindowGeometry(); FileSystemWatcher[] watchers = _watchers; for (int i = 0; i < watchers.Length; i++) { watchers[i].Dispose(); } _watchers = Array.Empty<FileSystemWatcher>(); } } internal sealed class ConfigSettingEntry : SettingEntryBase { private sealed class DynamicAttributeValue { private readonly object source; private readonly MemberInfo member; private bool failureLogged; internal bool IsReadOnly { get; } internal bool? Value { get; private set; } internal DynamicAttributeValue(bool isReadOnly, object source, MemberInfo member, bool? initialValue, bool readFailed) { IsReadOnly = isReadOnly; this.source = source; this.member = member; Value = (readFailed && isReadOnly) | initialValue; if (readFailed) { LogFailure(); } } internal void Refresh() { if (member == null) { return; } try { Value = ((((member is PropertyInfo propertyInfo) ? propertyInfo.GetValue(source, null) : ((FieldInfo)member).GetValue(source)) is bool value) ? new bool?(value) : ((bool?)null)); } catch (Exception) { LogFailure(); } } private void LogFailure() { if (!failureLogged) { failureLogged = true; ConfigurationManager.LogWarning("Could not refresh " + member.Name + " from " + source.GetType().FullName + "; retaining its previous state."); } } } private readonly List<DynamicAttributeValue> attributeValues = new List<DynamicAttributeValue>(); private ConfigDescription attributeDescription; private object[] attributeTags; private object[] attributeSources; public ConfigEntryBase Entry { get; } internal bool HasDynamicAttributes { get; private set; } public override Type SettingType => Entry.SettingType; public ConfigSettingEntry(ConfigEntryBase entry, BaseUnityPlugin owner) { Entry = entry; CacheAttributeSources(); DispName = entry.Definition.Key; base.Category = entry.Definition.Section; ConfigDescription description = entry.Description; base.Description = ((description != null) ? description.Description : null); TypeConverter converter = TomlTypeConverter.GetConverter(entry.SettingType); if (converter != null) { base.ObjToStr = (object o) => converter.ConvertToString(o, entry.SettingType); base.StrToObj = (string s) => converter.ConvertToObject(s, entry.SettingType); } ConfigDescription description2 = entry.Description; AcceptableValueBase val = ((description2 != null) ? description2.AcceptableValues : null); if (val != null) { GetAcceptableValues(val); } base.DefaultValue = entry.DefaultValue; SetFromAttributes(attributeSources, owner); ApplyAttributeValues(); ConsumeVisibilityChange(); } internal override void TrackAttributeValue(string name, object source, MemberInfo member, object value, bool readFailed = false) { if (!(name != "Browsable") || !(name != "ReadOnly")) { bool flag = (member is PropertyInfo propertyInfo && propertyInfo.GetIndexParameters().Length == 0 && propertyInfo.GetGetMethod() != null && !propertyInfo.GetGetMethod().IsStatic && IsBoolean(propertyInfo.PropertyType)) || (member is FieldInfo { IsStatic: false } fieldInfo && IsBoolean(fieldInfo.FieldType)); if (flag || value is bool) { attributeValues.Add(new DynamicAttributeValue(name == "ReadOnly", source, flag ? member : null, (value is bool value2) ? new bool?(value2) : ((bool?)null), readFailed)); HasDynamicAttributes |= flag; } } } private static bool IsBoolean(Type type) { if (!(type == typeof(bool))) { return type == typeof(bool?); } return true; } private void CacheAttributeSources() { attributeDescription = Entry.Description; ConfigDescription obj = attributeDescription; attributeTags = ((obj != null) ? obj.Tags : null); attributeSources = ((attributeTags == null || attributeTags.Length == 0) ? Array.Empty<object>() : ((object[])attributeTags.Clone())); } internal override bool HaveAttributeSourcesChanged() { ConfigDescription description = Entry.Description; object[] array = ((description != null) ? description.Tags : null); if (description != attributeDescription || array != attributeTags) { return true; } int num = ((array != null) ? array.Length : 0); if (num != attributeSources.Length) { return true; } for (int i = 0; i < num; i++) { if (array[i] != attributeSources[i]) { return true; } } return false; } internal override bool RefreshDynamicAttributes() { if (HaveAttributeSourcesChanged()) { CacheAttributeSources(); attributeValues.Clear(); HasDynamicAttributes = false; ReadAttributeTags(attributeSources, dynamicOnly: true); } else { if (!HasDynamicAttributes) { return false; } foreach (DynamicAttributeValue attributeValue in attributeValues) { attributeValue.Refresh(); } } return ApplyAttributeValues(); } private bool ApplyAttributeValues() { bool? browsable = null; bool? readOnly = null; foreach (DynamicAttributeValue attributeValue in attributeValues) { if (attributeValue.Value.HasValue) { if (attributeValue.IsReadOnly) { readOnly = attributeValue.Value; } else { browsable = attributeValue.Value; } } } return ApplyDynamicAttributes(browsable, readOnly); } private void GetAcceptableValues(AcceptableValueBase values) { Type type = ((object)values).GetType(); PropertyInfo property = type.GetProperty("AcceptableValues", BindingFlags.Instance | BindingFlags.Public); if (property != null) { base.AcceptableValues = ((IEnumerable)property.GetValue(values, null)).Cast<object>().ToArray(); return; } PropertyInfo property2 = type.GetProperty("MinValue", BindingFlags.Instance | BindingFlags.Public); PropertyInfo property3 = type.GetProperty("MaxValue", BindingFlags.Instance | BindingFlags.Public); if (property2 != null && property3 != null) { base.AcceptableValueRange = new KeyValuePair<object, object>(property2.GetValue(values, null), property3.GetValue(values, null)); } } public override object Get() { if (!PathOfValheimanCompatibility.TryGetValue(this, out var value)) { return Entry.BoxedValue; } return value; } protected override void SetValue(object newVal) { if (!PathOfValheimanCompatibility.ShouldBlockSet(this)) { Entry.BoxedValue = newVal; } } internal bool ShouldBeHidden() { return ConfigurationManager.IsSettingHidden(base.PluginInfo.GUID + "=" + Entry.Definition.Section + "=" + Entry.Definition.Key); } } internal static class PathOfValheimanCompatibility { private delegate bool TryValueDelegate(ConfigEntryBase entry, out object value); private const string PluginGuid = "treextr.pathofvalheiman"; private const string ProviderTypeName = "PassiveTree.ConfigManagerWorldSettings"; private static TryValueDelegate _tryValue; private static Func<ConfigEntryBase, bool, bool> _locked; private static Func<bool> _isClient; private static bool _nativeGet; private static bool _nativeSet; private static bool _faulted; internal static void Initialize() { Reset(); if (Chainloader.PluginInfos.TryGetValue("treextr.pathofvalheiman", out var value) && !((Object)(object)value.Instance == (Object)null)) { Bind(((object)value.Instance).GetType().Assembly); } } internal static bool Bind(Assembly assembly) { Reset(); try { Type type = assembly.GetType("PassiveTree.ConfigManagerWorldSettings", throwOnError: true); Type type2 = assembly.GetType("PassiveTree.DifficultyAdmin", throwOnError: true); MethodInfo methodInfo = RequireMethod(type, "TryValue", typeof(ConfigEntryBase), typeof(object).MakeByRefType()); if (!methodInfo.GetParameters()[1].IsOut) { throw new MissingMethodException(type.FullName, "TryValue(ConfigEntryBase, out object)"); } MethodInfo method = RequireMethod(type, "Locked", typeof(ConfigEntryBase), typeof(bool)); MethodInfo method2 = RequireMethod(type2, "get_IsClient"); _tryValue = (TryValueDelegate)Delegate.CreateDelegate(typeof(TryValueDelegate), methodInfo); _locked = (Func<ConfigEntryBase, bool, bool>)Delegate.CreateDelegate(typeof(Func<ConfigEntryBase, bool, bool>), method); _isClient = (Func<bool>)Delegate.CreateDelegate(typeof(Func<bool>), method2); _nativeGet = HasNativePrefix(assembly, typeof(ConfigSettingEntry).GetMethod("Get"), "Get"); _nativeSet = HasNativePrefix(assembly, typeof(ConfigSettingEntry).GetMethod("SetValue", BindingFlags.Instance | BindingFlags.NonPublic), "Set"); ConfigurationManager.LogInfo((_nativeGet && _nativeSet) ? "Path of Valheiman configuration compatibility enabled; existing value/write patches retained and editor locks connected." : "Path of Valheiman configuration compatibility enabled; missing value/write patches and editor locks are handled by ConfigManager.", always: true); return true; } catch (Exception exception) { Fail(exception); return false; } } internal static void Reset() { _tryValue = null; _locked = null; _isClient = null; _nativeGet = false; _nativeSet = false; _faulted = false; } internal static bool TryGetValue(ConfigSettingEntry setting, out object value) { value = null; if (!IsPathOfValheiman(setting) || _nativeGet || _tryValue == null) { return false; } try { return _tryValue(setting.Entry, out value); } catch (Exception exception) { value = null; Fail(exception); return false; } } internal static bool IsLocked(ConfigSettingEntry setting) { if (!IsPathOfValheiman(setting)) { return false; } if (_faulted) { return true; } if (_locked == null) { return false; } try { return _locked(setting.Entry, _isClient()); } catch (Exception exception) { Fail(exception); return true; } } internal static bool ShouldBlockSet(ConfigSettingEntry setting) { if (!_nativeSet || _faulted) { return IsLocked(setting); } return false; } private static bool IsPathOfValheiman(ConfigSettingEntry setting) { object a; if (setting == null) { a = null; } else { BepInPlugin pluginInfo = setting.PluginInfo; a = ((pluginInfo != null) ? pluginInfo.GUID : null); } return string.Equals((string?)a, "treextr.pathofvalheiman", StringComparison.Ordinal); } private static MethodInfo RequireMethod(Type type, string name, params Type[] arguments) { MethodInfo method = type.GetMethod(name, BindingFlags.DeclaredOnly | BindingFlags.Static | BindingFlags.Public, null, arguments, null); if (method == null || method.ReturnType != typeof(bool) || method.ContainsGenericParameters) { throw new MissingMethodException(type.FullName, name); } ParameterInfo[] parameters = method.GetParameters(); for (int i = 0; i < parameters.Length; i++) { if (parameters[i].ParameterType != arguments[i]) { throw new MissingMethodException(type.FullName, name); } } return method; } private static bool HasNativePrefix(Assembly assembly, MethodBase target, string nestedType) { Patches val = ((target == null) ? null : Harmony.GetPatchInfo(target)); if (val == null) { return false; } foreach (Patch prefix in val.Prefixes) { MethodInfo patchMethod = prefix.PatchMethod; if (prefix.owner == "treextr.pathofvalheiman" && patchMethod?.DeclaringType?.Assembly == assembly && patchMethod.Name == "Prefix" && patchMethod.DeclaringType.FullName == "PassiveTree.ConfigManagerWorldSettings+" + nestedType) { return true; } } return false; } private static void Fail(Exception exception) { _tryValue = null; _locked = null; _isClient = null; if (!_faulted) { _faulted = true; ConfigurationManager.LogWarning("Path of Valheiman configuration integration failed; its settings are read-only in ConfigManager until restart to preserve its write restrictions. " + exception.GetType().Name + ": " + exception.Message); } } } public sealed class ExternalSetting { public string Category { get; } public string Name { get; } public string Description { get; } public Type SettingType { get; } public object DefaultValue { get; } public bool ReadOnly => Setter == null; internal Func<object> Getter { get; } internal Action<object> Setter { get; } public ExternalSetting(string category, string name, string description, Type settingType, object defaultValue, Func<object> getter, Action<object> setter) { if (string.IsNullOrWhiteSpace(category)) { throw new ArgumentException("A category is required.", "category"); } if (string.IsNullOrWhiteSpace(name)) { throw new ArgumentException("A setting name is required.", "name"); } SettingType = settingType ?? throw new ArgumentNullException("settingType"); if (!Accepts(settingType, defaultValue)) { throw new ArgumentException("Default value does not match the setting type.", "defaultValue"); } Category = category; Name = name; Description = description ?? string.Empty; DefaultValue = defaultValue; Getter = getter ?? throw new ArgumentNullException("getter"); Setter = setter; } internal static bool Accepts(Type type, object value) { if (value != null) { return type.IsInstanceOfType(value); } if (type.IsValueType) { return Nullable.GetUnderlyingType(type) != null; } return true; } } internal sealed class ExternalEnumCache { private readonly ExternalSettingEntry _entry; private readonly Dictionary<object, GUIContent> _labels = new Dictionary<object, GUIContent>(); private object _currentValue; private GUIContent _currentContent; internal bool IsEligible { get; } internal bool IsFlags { get; } internal IList Values { get; } internal GUIContent[] Contents { get; } internal long[] FlagMasks { get; } internal GUIContent[] FlagContents { get; } internal GUIContent DefaultContent { get; } internal Action<int> SelectionChanged { get; } internal ExternalEnumCache(ExternalSettingEntry entry) { _entry = entry; Type settingType = entry.SettingType; if (!settingType.IsEnum) { return; } IsFlags = settingType.IsDefined(typeof(FlagsAttribute), inherit: false); FieldInfo[] fields = settingType.GetFields(BindingFlags.Static | BindingFlags.Public); for (int i = 0; i < fields.Length; i++) { foreach (CustomAttributeData customAttributesDatum in fields[i].GetCustomAttributesData()) { if (customAttributesDatum.AttributeType != typeof(DescriptionAttribute) && typeof(DescriptionAttribute).IsAssignableFrom(customAttributesDatum.AttributeType)) { return; } } } Values = Enum.GetValues(settingType); Contents = (GUIContent[])(object)new GUIContent[Values.Count]; for (int j = 0; j < Values.Count; j++) { object obj = Values[j]; GUIContent val = SettingFieldDrawer.ObjectToGuiContent(obj); Contents[j] = val; _labels[obj] = val; } if (IsFlags) { List<long> list = new List<long>(); List<GUIContent> list2 = new List<GUIContent>(); for (int k = 0; k < Values.Count; k++) { long num = Convert.ToInt64(Values[k]); if (num != 0L) { list.Add(num); list2.Add(Contents[k]); } } FlagMasks = list.ToArray(); FlagContents = list2.ToArray(); } DefaultContent = ContentFor(entry.DefaultValue); SelectionChanged = Select; IsEligible = true; } private GUIContent ContentFor(object value) { if (!_labels.TryGetValue(value, out var value2)) { return SettingFieldDrawer.ObjectToGuiContent(value); } return value2; } internal GUIContent GetCurrentContent() { object obj = _entry.Get(); if (_currentContent == null || !object.Equals(_currentValue, obj)) { _currentValue = obj; _currentContent = ContentFor(obj); } return _currentContent; } private void Select(int index) { if (index >= 0 && index < Values.Count) { _entry.Set(Values[index]); } } internal object ChangeFlag(object current, int index, bool enabled) { long num = Convert.ToInt64(current); long num2 = FlagMasks[index]; return Enum.ToObject(_entry.SettingType, enabled ? (num | num2) : (num & ~num2)); } internal void SetFlag(int index, bool enabled) { if (index >= 0 && index < FlagMasks.Length) { _entry.Set(ChangeFlag(_entry.Get(), index, enabled)); } } } internal sealed class ExternalSettingEntry : SettingEntryBase { private Func<object> _getter; private Action<object> _setter; private object _lastValue; private string _getError; private string _setError; private string _previewValue; private string _previewText; private ExternalNumericEditor _numericEditor; public override Type SettingType { get; } internal bool IsActive => Volatile.Read(in _getter) != null; internal string ErrorText => _setError ?? _getError; internal bool UsesTextEditor { get { if (!(SettingType == typeof(string))) { if (!SettingType.IsEnum && SettingType != typeof(bool)) { if (!SettingType.IsPrimitive) { return SettingType == typeof(decimal); } return true; } return false; } return true; } } internal bool UsesInlineNumericEditor { get { if (!SettingType.IsEnum && Type.GetTypeCode(SettingType) >= TypeCode.SByte) { return Type.GetTypeCode(SettingType) <= TypeCode.Decimal; } return false; } } internal ExternalNumericEditor NumericEditor => _numericEditor ?? (_numericEditor = new ExternalNumericEditor(this)); internal ExternalSettingEntry(BepInPlugin owner, ExternalSetting setting) { base.PluginInfo = owner; base.Category = setting.Category; DispName = setting.Name; base.Description = setting.Description; SettingType = setting.SettingType; base.DefaultValue = setting.DefaultValue; base.ReadOnly = setting.ReadOnly; _lastValue = base.DefaultValue; _getter = setting.Getter; _setter = setting.Setter; } internal void ClearSetError() { _setError = null; } public override object Get() { Func<object> func = Volatile.Read(in _getter); if (func == null) { return _lastValue; } try { object obj = func(); if (!ExternalSetting.Accepts(SettingType, obj)) { throw new InvalidOperationException("Getter returned a value of the wrong type."); } _lastValue = obj; _getError = null; } catch (Exception ex) { _getError = "Could not read setting: " + ex.Message; } return _lastValue; } protected override void SetValue(object newVal) { TrySet(newVal); } internal bool TrySet(object value) { Action<object> action = Volatile.Read(in _setter); if (action == null) { _setError = (IsActive ? "This setting is read-only." : "This setting is no longer registered."); return false; } try { if (!ExternalSetting.Accepts(SettingType, value)) { throw new ArgumentException("Value does not match the setting type."); } action(value); _setError = null; return true; } catch (Exception ex) { _setError = "Could not apply setting: " + ex.Message; return false; } } internal bool TrySetText(string text) { if (Volatile.Read(in _setter) == null) { return TrySet(null); } object value; try { value = ((SettingType == typeof(string)) ? text : TypeDescriptor.GetConverter(SettingType).ConvertFromInvariantString(text)); } catch (Exception ex) { _setError = "Invalid value: " + ex.Message; return false; } return TrySet(value); } internal string FormatValue(object value) { object obj; if (!(value is IFormattable formattable)) { obj = value?.ToString(); if (obj == null) { return string.Empty; } } else { obj = formattable.ToString(null, CultureInfo.InvariantCulture); } return (string)obj; } internal string GetPreviewText() { string text = FormatValue(Get()); if (!string.Equals(text, _previewValue, StringComparison.Ordinal)) { _previewValue = text; int num = text.IndexOfAny(new char[2] { '\r', '\n' }); int num2 = Math.Min((num < 0) ? text.Length : num, 100); _previewText = text.Substring(0, num2) + ((num2 < text.Length) ? " ..." : string.Empty); } return _previewText ?? string.Empty; } internal bool ShouldBeHidden() { return ConfigurationManager.IsSettingHidden(base.PluginInfo.GUID + "=" + base.Category + "=" + DispName); } internal void Deactivate() { Interlocked.Exchange(ref _getter, null); Interlocked.Exchange(ref _setter, null); } } internal sealed class ExternalNumericEditor { private static int _nextControlId; private readonly ExternalSettingEntry _entry; private object _displayValue; private bool _hasDisplayValue; internal string ControlName { get; } internal string Text { get; private set; } = string.Empty; internal bool IsFocused { get; private set; } internal bool HasPendingText { get; private set; } internal bool IsActive => _entry.IsActive; internal ExternalNumericEditor(ExternalSettingEntry entry) { _entry = entry; ControlName = "ExternalNumber" + Interlocked.Increment(ref _nextControlId).ToString(CultureInfo.InvariantCulture); } internal void Refresh() { if (!IsFocused && !HasPendingText) { ReadValue(); } } private void ReadValue() { object obj = _entry.Get(); if (!_hasDisplayValue || !object.Equals(obj, _displayValue)) { _displayValue = obj; _hasDisplayValue = true; Text = _entry.FormatValue(obj); } } internal void HandleInput(string text, bool focused, bool enter, bool escape) { bool flag = IsFocused && !focused; IsFocused = focused; if (escape) { Cancel(); return; } if (!string.Equals(Text, text, StringComparison.Ordinal)) { Text = text; HasPendingText = true; } if (enter || flag) { if (HasPendingText) { Commit(); } else if (flag) { Refresh(); } } } private void Commit() { if (HasPendingText && IsActive && _entry.TrySetText(Text)) { HasPendingText = false; _hasDisplayValue = false; ReadValue(); } } internal void Cancel() { IsFocused = false; HasPendingText = false; _entry.ClearSetError(); _hasDisplayValue = false; ReadValue(); } internal void Reset() { if (_entry.TrySet(_entry.DefaultValue)) { Cancel(); } } } internal static class ExternalSettingsRegistry { private sealed class Registration : IDisposable { private readonly string _guid; internal readonly ExternalSettingEntry[] Entries; internal Registration(string guid, ExternalSettingEntry[] entries) { _guid = guid; Entries = entries; } internal void Deactivate() { ExternalSettingEntry[] entries = Entries; for (int i = 0; i < entries.Length; i++) { entries[i].Deactivate(); } } public void Dispose() { lock (Sync) { if (Registrations.TryGetValue(_guid, out var value) && value == this) { Registrations.Remove(_guid); Deactivate(); Interlocked.Increment(ref _revision); } } } } private static readonly object Sync = new object(); private static readonly Dictionary<string, Registration> Registrations = new Dictionary<string, Registration>(StringComparer.Ordinal); private static long _revision; internal static long Revision => Interlocked.Read(in _revision); internal static IDisposable Register(string guid, string name, string version, IEnumerable<ExternalSetting> settings) { //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Expected O, but got Unknown if (string.IsNullOrWhiteSpace(guid)) { throw new ArgumentException("An owner GUID is required.", "guid"); } if (string.IsNullOrWhiteSpace(name)) { throw new ArgumentException("An owner name is required.", "name"); } if (!Version.TryParse(version, out Version _)) { throw new ArgumentException("A valid version is required.", "version"); } if (settings == null) { throw new ArgumentNullException("settings"); } BepInPlugin owner = new BepInPlugin(guid, name, version); HashSet<Tuple<string, string>> hashSet = new HashSet<Tuple<string, string>>(); List<ExternalSettingEntry> list = new List<ExternalSettingEntry>(); foreach (ExternalSetting setting in settings) { if (setting == null) { throw new ArgumentException("Settings cannot contain null.", "settings"); } if (!hashSet.Add(Tuple.Create(setting.Category, setting.Name))) { throw new ArgumentException("Setting category/name pairs must be unique.", "settings"); } list.Add(new ExternalSettingEntry(owner, setting)); } Registration registration = new Registration(guid, list.ToArray()); lock (Sync) { if (Registrations.TryGetValue(guid, out var value)) { value.Deactivate(); } Registrations[guid] = registration; Interlocked.Increment(ref _revision); return registration; } } internal static SettingEntryBase[] Snapshot() { lock (Sync) { return Registrations.OrderBy<KeyValuePair<string, Registration>, string>((KeyValuePair<string, Registration> pair) => pair.Key, StringComparer.Ordinal).SelectMany((KeyValuePair<string, Registration> pair) => pair.Value.Entries).Cast<SettingEntryBase>() .ToArray(); } } } internal static class HiddenSettingsParser { internal static bool TryParseLine(string rawLine, out string setting) { setting = null; if (rawLine == null) { return false; } string text = rawLine.Trim(); if (text.Length == 0 || text.StartsWith("#", StringComparison.Ordinal)) { return false; } int num = text.IndexOf('='); int num2 = ((num < 0) ? (-1) : text.IndexOf('=', num + 1)); if (num <= 0 || num2 <= num + 1 || num2 == text.Length - 1) { return false; } string text2 = text.Substring(0, num).Trim(); string text3 = text.Substring(num + 1, num2 - num - 1).Trim(); string text4 = text.Substring(num2 + 1).Trim(); if (text2.Length == 0 || text3.Length == 0 || text4.Length == 0) { return false; } setting = text2 + "=" + text3 + "=" + text4; return true; } } internal class SettingEditWindow { private sealed class ColorCacheEntry { public Color Last; public Texture2D Tex; } private Rect _windowRect = new Rect(ConfigurationManager._windowPositionEditSetting.Value, ConfigurationManager._windowSizeEditSetting.Value); private bool _windowGeometryDirty; private bool _windowGeometrySaveFailed; private Vector2? _pendingWindowSize; private const int WindowId = -6800; private const string NewItemFieldControlName = "StringListNewItemField"; private SettingEntryBase setting; private bool _editingReadOnly; private bool _editingLocked; private bool _drawLocked; private bool _drawingWindow; private static SettingEntryBase _currentKeyboardShortcutToSet; private SettingFieldDrawer.ShortcutCaptureState _shortcutCapture; private SettingEntryBase _capturedShortcutSetting; private bool _shortcutCaptureDrawn; private static IEnumerable<KeyCode> _keysToCheck; private ColorCacheEntry _colorPreview; private Vector2 _scrollPosition = Vector2.zero; private Vector2 _scrollPositionEnum = Vector2.zero; private int listIndex = -1; private IList listEnum; private GUIContent[] _enumContent; private Action drawerFunction; private string errorText; private object valueToSet; private readonly SettingFieldDrawer.RangeTextEditor rangeTextEditor = new SettingFieldDrawer.RangeTextEditor("CM_Range_Edit"); private string errorOnSetting; private string _externalText; private bool _externalTextEdited; private readonly List<string> vectorParts = new List<string>(); private readonly List<float> vectorFloats = new List<float>(); private readonly List<float> vectorDefault = new List<float>(); private string colorAsHEX; private List<string> separatedStringDefault = new List<string>(); private List<string> separatedString = new List<string>(); private string separator; private int editStringView; private string newItem; private ConfigEntryBase dummyCustomDrawerConfigEntry; private bool _isOpen; private static readonly Dictionary<Type, string> typeMappings = new Dictionary<Type, string> { { typeof(int), "Integer" }, { typeof(float), "Float" }, { typeof(double), "Double" }, { typeof(decimal), "Decimal" }, { typeof(bool), "Boolean" }, { typeof(string), "String" }, { typeof(long), "Long" }, { typeof(short), "Short" }, { typeof(byte), "Byte" }, { typeof(sbyte), "Signed Byte" }, { typeof(uint), "Unsigned Integer" }, { typeof(ulong), "Unsigned Long" }, { typeof(ushort), "Unsigned Short" }, { typeof(char), "Character" }, { typeof(DateTime), "DateTime" }, { typeof(TimeSpan), "TimeSpan" }, { typeof(Guid), "GUID" }, { typeof(KeyValuePair<, >), "Map<Key, Value>" }, { typeof(object), "Object" } }; private readonly Dictionary<Type, bool> _canCovertCache = new Dictionary<Type, bool>(); public Dictionary<Type, Action> SettingDrawHandlers { get; } private bool IsStringList { get { if (setting != null && setting.SettingType != null) { return typeof(IList<string>).IsAssignableFrom(setting.SettingType); } return false; } } public bool IsOpen { get { return _isOpen; } set { if (_isOpen && !value) { FlushWindowGeometry(); } _isOpen = value; if (!value) { ClearCache(); _currentKeyboardShortcutToSet = null; } } } internal bool IsRecordingKeyboardShortcut => _shortcutCapture?.IsActive ?? false; public SettingEditWindow() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) SettingDrawHandlers = new Dictionary<Type, Action> { { typeof(bool), DrawBoolField }, { typeof(KeyboardShortcut), DrawKeyboardShortcut }, { typeof(KeyCode), DrawKeyCode }, { typeof(Color), DrawColor }, { typeof(Vector2), DrawVector }, { typeof(Vector3), DrawVector }, { typeof(Vector4), DrawVector }, { typeof(Quaternion), DrawVector } }; } public void EditSetting(SettingEntryBase setting) { if (SettingFieldDrawer.CanEditSetting(setting)) { SettingFieldDrawer.CancelKeyboardShortcutCapture(); CancelKeyboardShortcutCapture(); if (this.setting == setting && IsOpen) { IsOpen = false; return; } this.setting = setting; InitializeWindow(); IsOpen = true; } } internal void ResetWindowGeometry() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) _windowRect = new Rect(ConfigurationManager._windowPositionEditSetting.Value, ConfigurationManager._windowSizeEditSetting.Value); _windowGeometryDirty = false; _windowGeometrySaveFailed = false; _pendingWindowSize = null; } internal void FlushWindowGeometry() { if (!_windowGeometryDirty) { return; } try { SaveCurrentSizeAndPosition(); } catch (Exception ex) { _windowGeometrySaveFailed = true; ConfigurationManager.LogWarning("Could not save setting editor geometry: " + ex.Message); } } internal void CloseUnregisteredExternalSetting() { if (setting is ExternalSettingEntry { IsActive: false }) { Dispose(); } } internal bool RefreshEditingState() { setting?.RefreshDynamicAttributes(); return UpdateEditingState(); } private bool UpdateEditingState() { if (setting == null) { return false; } if (setting.Browsable == false || setting is ExternalSettingEntry { IsActive: false }) { IsOpen = false; valueToSet = null; dummyCustomDrawerConfigEntry = null; _externalText = null; _externalTextEdited = false; return false; } bool valueOrDefault = setting.ReadOnly == true; bool flag = valueOrDefault || (setting is ConfigSettingEntry configSettingEntry && PathOfValheimanCompatibility.IsLocked(configSettingEntry)); if (_editingReadOnly != valueOrDefault) { InitializeWindow(); } else if (_editingLocked != flag) { _editingLocked = flag; ClearCache(); } return true; } private bool CanEditSetting() { bool flag = SettingFieldDrawer.CanEditSetting(setting); return UpdateEditingState() && flag; } private bool CanEditSettingForDrawing() { bool result = CanEditSetting(); EnsureDrawingState(); return result; } private void EnsureDrawingState() { if (_drawingWindow && (!IsOpen || _drawLocked != _editingLocked)) { GUIUtility.ExitGUI(); } } internal void Dispose() { IsOpen = false; setting = null; drawerFunction = null; valueToSet = null; listEnum = null; _enumContent = null; dummyCustomDrawerConfigEntry = null; _externalText = null; _externalTextEdited = false; _currentKeyboardShortcutToSet = null; } public void OnGUI() { //IL_00e9: 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) //IL_002e: Invalid comparison between Unknown and I4 //IL_0083: 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_0091: 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_0079: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Expected O, but got Unknown //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) if (!IsOpen) { return; } setting.RefreshDisplayAttributes(Time.frameCount); if (UpdateEditingState()) { if ((int)Event.current.type == 8) { _drawLocked = _editingLocked; } else if (_drawLocked != _editingLocked) { GUIUtility.ExitGUI(); } if (!_windowGeometryDirty) { ((Rect)(ref _windowRect)).size = ConfigurationManager._windowSizeEditSetting.Value; ((Rect)(ref _windowRect)).position = ConfigurationManager._windowPositionEditSetting.Value; } Color backgroundColor = GUI.backgroundColor; GUI.backgroundColor = ConfigurationManager.Palette.WindowBackground; Rect windowRect; try { windowRect = GUI.Window(-6800, _windowRect, new WindowFunction(DrawWindow), $"{setting.PluginInfo.Name} {setting.PluginInfo.Version}", ConfigurationManagerStyles.GetWindowStyle()); } finally { GUI.backgroundColor = backgroundColor; } if (_pendingWindowSize.HasValue) { ((Rect)(ref windowRect)).size = _pendingWindowSize.Value; _pendingWindowSize = null; } _windowRect = windowRect; if (((Rect)(ref _windowRect)).position != ConfigurationManager._windowPositionEditSetting.Value) { _windowGeometryDirty = true; } bool mouseButton = UnityInput.Current.GetMouseButton(0); if (mouseButton) { _windowGeometrySaveFailed = false; } if (_windowGeometryDirty && !mouseButton && !_windowGeometrySaveFailed) { FlushWindowGeometry(); } } } private void UpdateStringList() { if (Utility.IsNullOrWhiteSpace(separator)) { separator = ","; } if (setting.SettingType != typeof(string) && !IsStringList) { return; } separatedString.Clear(); if (IsStringList) { try { separatedString.AddRange(valueToSet as IList<string>); } catch { separatedString.AddRange((valueToSet?.ToString() ?? string.Empty).Split(new string[1] { separator }, StringSplitOptions.None)); } } else { separatedString.AddRange((valueToSet?.ToString() ?? string.Empty).Split(new string[1] { separator }, StringSplitOptions.None)); } separatedStringDefault.Clear(); if (setting.DefaultValue == null) { return; } if (IsStringList) { try { separatedStringDefault.AddRange((setting.DefaultValue as IList<string>).Select((string s) => s.Trim())); return; } catch { separatedStringDefault.AddRange(from s in setting.DefaultValue.ToString().Split(new string[1] { separator }, StringSplitOptions.None) select s.Trim()); return; } } separatedStringDefault.AddRange(from s in setting.DefaultValue.ToString().Split(new string[1] { separator }, StringSplitOptions.None) select s.Trim()); } private void InitializeWindow() { //IL_0099: 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_011c: 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) //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Unknown result type (might be due to invalid IL or missing references) //IL_025b: Unknown result type (might be due to invalid IL or missing references) //IL_0265: Expected O, but got Unknown ClearCache(); _editingReadOnly = setting.ReadOnly == true; _editingLocked = _editingReadOnly || (setting is ConfigSettingEntry configSettingEntry && PathOfValheimanCompatibility.IsLocked(configSettingEntry)); listEnum = null; _enumContent = null; listIndex = -1; drawerFunction = null; valueToSet = ((setting.SettingType == typeof(Color)) ? ((object)Utils.RoundColorToHEX((Color)setting.Get())) : setting.Get()); _externalText = (setting as ExternalSettingEntry)?.FormatValue(valueToSet); _externalTextEdited = false; errorText = string.Empty; errorOnSetting = string.Empty; colorAsHEX = ((setting.SettingType == typeof(Color)) ? ("#" + ColorUtility.ToHtmlStringRGBA((Color)valueToSet)) : string.Empty); separator = ","; separatedString.Clear(); newItem = string.Empty; editStringView = 0; _scrollPosition = Vector2.zero; _scrollPositionEnum = Vector2.zero; dummyCustomDrawerConfigEntry = null; if (!_editingReadOnly && setting is ConfigSettingEntry configSettingEntry2 && (setting.CustomDrawer != null || setting.CustomHotkeyDrawer != null)) { ConstructorInfo constructorInfo = AccessTools.Constructor(typeof(ConfigEntry<>).MakeGenericType(configSettingEntry2.Entry.SettingType), new Type[4] { typeof(ConfigFile), typeof(ConfigDefinition), configSettingEntry2.Entry.SettingType, typeof(ConfigDescription) }, false); dummyCustomDrawerConfigEntry = (ConfigEntryBase)constructorInfo.Invoke(new object[4] { configSettingEntry2.Entry.ConfigFile, configSettingEntry2.Entry.Definition, configSettingEntry2.Entry.DefaultValue, configSettingEntry2.Entry.Description }); dummyCustomDrawerConfigEntry.BoxedValue = configSettingEntry2.Get(); } if (setting.AcceptableValueRange.Key != null) { drawerFunction = DrawRangeField; } else if (setting.AcceptableValues != null && setting.AcceptableValues.Length != 0 && setting.SettingType.IsInstanceOfType(setting.AcceptableValues.FirstOrDefault((object x) => x != null))) { SetAcceptableValuesDrawer(); } else if (setting.SettingType.IsEnum && setting.SettingType != typeof(KeyCode)) { ExternalEnumCache externalEnumCache = ((setting is ExternalSettingEntry externalSettingEntry) ? SettingFieldDrawer.GetExternalEnumCache(externalSettingEntry) : null); if (externalEnumCache != null && externalEnumCache.IsEligible) { listEnum = externalEnumCache.Values; _enumContent = externalEnumCache.Contents; } else { listEnum = Enum.GetValues(setting.SettingType); } if ((externalEnumCache != null && externalEnumCache.IsEligible) ? externalEnumCache.IsFlags : setting.SettingType.GetCustomAttributes(typeof(FlagsAttribute), inherit: false).Any()) { drawerFunction = DrawFlagsField; } else { drawerFunction = DrawEnumListField; } } else { SettingDrawHandlers.TryGetValue(setting.SettingType, out drawerFunction); } if (setting.SettingType == typeof(KeyCode) && listEnum == null) { listEnum = Enum.GetValues(setting.SettingType); } if (_enumContent == null && listEnum != null && setting.SettingType.IsEnum) { try { if (listEnum.Cast<object>().All(HasStaticEnumLabel)) { _enumContent = listEnum.Cast<object>().Select(SettingFieldDrawer.ObjectToGuiContent).ToArray(); } } catch { } } InitListIndex(); InitVectorParts(); if (!(setting is ExternalSettingEntry { UsesTextEditor: not false })) { UpdateStringList(); } } private static bool HasStaticEnumLabel(object value) { if (!(value is Enum)) { return false; } MemberInfo memberInfo = value.GetType().GetMember(value.ToString()).FirstOrDefault(); if (!(memberInfo == null)) { return memberInfo.GetCustomAttributesData().All((CustomAttributeData attribute) => attribute.AttributeType == typeof(DescriptionAttribute) || !typeof(DescriptionAttribute).IsAssignableFrom(attribute.AttributeType)); } return true; } private void InitListIndex() { listIndex = ((listEnum == null) ? (-1) : listEnum.IndexOf(valueToSet)); } private void InitVectorParts() { //IL_0049: 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_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_0157: Unknown result type (might be due to invalid IL or missing references) vectorParts.Clear(); vectorFloats.Clear(); vectorDefault.Clear(); if (setting.SettingType == typeof(Vector2)) { FillVectorList<Vector2>(vectorFloats, (Vector2)valueToSet); FillVectorList<Vector2>(vectorDefault, (Vector2)setting.DefaultValue); } else if (setting.SettingType == typeof(Vector3)) { FillVectorList<Vector3>(vectorFloats, (Vector3)valueToSet); FillVectorList<Vector3>(vectorDefault, (Vector3)setting.DefaultValue); } else if (setting.SettingType == typeof(Vector4)) { FillVectorList<Vector4>(vectorFloats, (Vector4)valueToSet); FillVectorList<Vector4>(vectorDefault, (Vector4)setting.DefaultValue); } else if (setting.SettingType == typeof(Quaternion)) { FillVectorList<Quaternion>(vectorFloats, (Quaternion)valueToSet); FillVectorList<Quaternion>(vectorDefault, (Quaternion)setting.DefaultValue); } vectorParts.AddRange(vectorFloats.Select((float f) => f.ToString())); } private void SetAcceptableValuesDrawer() { if (setting.SettingType == typeof(KeyCode)) { listEnum = ((setting.AcceptableValues.Length > 1) ? setting.AcceptableValues : Enum.GetValues(setting.SettingType)); drawerFunction = DrawKeyCode; } else { listEnum = setting.AcceptableValues; drawerFunction = DrawEnumListField; } } internal void SaveCurrentSizeAndPosition() { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) Vector2 size = new Vector2(Mathf.Clamp(((Rect)(ref _windowRect)).size.x, 200f, ConfigurationManager.instance.ScreenWidth / 2f), Mathf.Clamp(((Rect)(ref _windowRect)).size.y, 200f, ConfigurationManager.instance.ScreenHeight * 0.9f)); Vector2 position = new Vector2(Mathf.Clamp(((Rect)(ref _windowRect)).position.x, 0f, ConfigurationManager.instance.ScreenWidth - ConfigurationManager._windowSize.Value.x / 4f), Mathf.Clamp(((Rect)(ref _windowRect)).position.y, 0f, ConfigurationManager.instance.ScreenHeight - 40f)); ConfigurationManager.SaveWindowConfigChanges(((BaseUnityPlugin)ConfigurationManager.instance).Config, delegate { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) ConfigurationManager._windowSizeEditSetting.Value = size; ConfigurationManager._windowPositionEditSetting.Value = position; }); _windowRect = new Rect(position, size); _windowGeometryDirty = false; _windowGeometrySaveFailed = false; _pendingWindowSize = null; } private void DrawWindow(int windowID) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) _shortcutCaptureDrawn = false; _drawingWindow = true; bool flag = false; bool enabled = GUI.enabled; Color backgroundColor = GUI.backgroundColor; SettingFieldDrawer.RangeTextEditor.BeginWindowEvent(); try { ConfigurationManagerStyles.DrawWindowBackgroundDimming(((Rect)(ref _windowRect)).size); DrawWindowContents(windowID); flag = true; } finally { try { if (flag) { FinishUndrawnRangeText(); } } finally { if (flag && IsRecordingKeyboardShortcut && !_shortcutCaptureDrawn) { CancelKeyboardShortcutCapture(); } SettingFieldDrawer.RangeTextEditor.EndWindowEvent(); _drawingWindow = false; GUI.enabled = enabled; GUI.backgroundColor = backgroundColor; } } } private void FinishUndrawnRangeText() { if (rangeTextEditor.FinishIfUndrawn(out var committed)) { ApplyRangeText(committed); } } private void ApplyRangeText(string text) { if (CanEditSetting() && setting.AcceptableValueRange.Key != null) { float minimum = (float)Convert.ToDouble(setting.AcceptableValueRange.Key, CultureInfo.InvariantCulture); float maximum = (float)Convert.ToDouble(setting.AcceptableValueRange.Value, CultureInfo.InvariantCulture); if (SettingFieldDrawer.TryParseRangeText(text, minimum, maximum, setting.SettingType, out var value)) { valueToSet = value; } } } private void DrawWindowContents(int windowID) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Expected O, but got Unknown //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_01be: Unknown result type (might be due to invalid IL or missing references) //IL_0199: Unknown result type (might be due to invalid IL or missing references) //IL_019e: Unknown result type (might be due to invalid IL or missing references) //IL_01e5: Expected O, but got Unknown //IL_01c5: Unknown result type (might be due to invalid IL or missing references) //IL_0225: Unknown result type (might be due to invalid IL or missing references) //IL_022a: Unknown result type (might be due to invalid IL or missing references) //IL_024c: Unknown result type (might be due to invalid IL or missing references) //IL_02fb: Unknown result type (might be due to invalid IL or missing references) //IL_031b: Unknown result type (might be due to invalid IL or missing references) //IL_0245: Unknown result type (might be due to invalid IL or missing references) //IL_033a: Unknown result type (might be due to invalid IL or missing references) //IL_0341: Unknown result type (might be due to invalid IL or missing references) //IL_0346: Unknown result type (might be due to invalid IL or missing references) //IL_032d: Unknown result type (might be due to invalid IL or missing references) //IL_039e: Unknown result type (might be due to invalid IL or missing references) //IL_03af: Unknown result type (might be due to invalid IL or missing references) Color backgroundColor = GUI.backgroundColor; GUI.backgroundColor = ConfigurationManager.Palette.EntryBackground; GUILayout.BeginVertical(ConfigurationManagerStyles.GetSettingWindowBackgroundStyle(), Array.Empty<GUILayoutOption>()); GUILayout.Space(1f); GUILayout.Label("<b>" + setting.Category + "</b>", ConfigurationManagerStyles.GetLabelStyle(), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) }); DrawDelimiterLine(); GUILayout.Space(1f); GUILayout.BeginHorizontal((GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandHeight(false) }); GUILayout.Label(setting.DispName + " ", ConfigurationManagerStyles.GetLabelStyle(), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(false) }); GUILayout.Label("(" + GetTypeRepresentation(setting.SettingType) + ")", ConfigurationManagerStyles.GetLabelStyleInfo(), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) }); GUILayout.EndHorizontal(); GUILayout.Label(setting.Description, ConfigurationManagerStyles.GetLabelStyle(isDefaultValue: false), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) }); if (setting.DefaultValue != null) { GUIStyle labelStyle = ConfigurationManagerStyles.GetLabelStyle(); GUIContent val = new GUIContent("Default: "); float num = labelStyle.CalcSize(val).x + 3f; GUILayout.BeginHorizontal((GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandHeight(false) }); GUILayout.Label("Default: ", labelStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(num) }); GUILayout.Label((GUIContent)((setting.DefaultValue is KeyboardShortcut shortcut) ? ((object)SettingFieldDrawer.GetKeyboardShortcutContent(shortcut)) : ((object)new GUIContent(GetValueRepresentation(setting.DefaultValue, setting.SettingType)))), ConfigurationManagerStyles.GetLabelStyleInfo(), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) }); GUILayout.EndHorizontal(); } DrawDelimiterLine(); GUILayout.Space(5f); bool enabled = GUI.enabled; try { if (_drawLocked) { GUI.enabled = false; object obj = setting.Get(); GUILayout.Label((GUIContent)((obj is KeyboardShortcut shortcut2) ? ((object)SettingFieldDrawer.GetKeyboardShortcutContent(shortcut2)) : ((object)new GUIContent(obj?.ToString() ?? string.Empty))), ConfigurationManagerStyles.GetLabelStyle(), Array.Empty<GUILayoutOption>()); } else { DrawSettingValue(); } EnsureDrawingState(); } finally { if (_drawLocked || !ComboBox.IsShown()) { GUI.enabled = enabled; } } if (!Utility.IsNullOrWhiteSpace(errorOnSetting)) { GUILayout.Label(errorOnSetting, ConfigurationManagerStyles.GetLabelStyle(), Array.Empty<GUILayoutOption>()); } else if (setting is ExternalSettingEntry externalSettingEntry && !string.IsNullOrEmpty(externalSettingEntr