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 Risk Of Options Extender v1.0.0
RiskOfOptionsExtender.dll
Decompiled 17 hours ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text.RegularExpressions; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using Microsoft.CodeAnalysis; using MonoMod.RuntimeDetour; using RiskOfOptions; using RiskOfOptions.Components.Options; using RiskOfOptions.Components.Panel; using RiskOfOptions.Components.RuntimePrefabs; using RiskOfOptions.Containers; using RiskOfOptions.Lib; using RiskOfOptions.OptionConfigs; using RiskOfOptions.Options; using RiskOfOptions.Resources; using RiskOfOptionsExtender.Discovery; using RiskOfOptionsExtender.Generation; using RiskOfOptionsExtender.Resilience; using RiskOfOptionsExtender.Settings; using RiskOfOptionsExtender.UI; using RiskOfOptionsExtender.UI.CategoryPicking; using RiskOfOptionsExtender.UI.Features; using RiskOfOptionsExtender.UI.ModList; using RiskOfOptionsExtender.UI.OptionRows; using RoR2; using RoR2.UI; using TMPro; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: IgnoresAccessChecksTo("RiskOfOptions")] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace RiskOfOptionsExtender { [BepInPlugin("com.Delfofthebla.RiskOfOptionsExtender", "RiskOfOptionsExtender", "1.0.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class RiskOfOptionsExtenderPlugin : BaseUnityPlugin { public const string Guid = "com.Delfofthebla.RiskOfOptionsExtender"; public const string Name = "RiskOfOptionsExtender"; public const string Version = "1.0.0"; internal static ManualLogSource Log { get; private set; } private void Awake() { Log = ((BaseUnityPlugin)this).Logger; new FeatureGuard("config file discovery").Run("start watching for config files", ConfigFileRegistry.Install); ExtenderSettings extenderSettings = new ExtenderSettings(((BaseUnityPlugin)this).Config); OptionGeneration.Initialize(((BaseUnityPlugin)this).Info, extenderSettings); new FeatureGuard("this mod's own options page").Run("add this mod's options to the menu", extenderSettings.AddToMenu); PanelHooks.Install(extenderSettings); } } } namespace RiskOfOptionsExtender.UI { internal static class ComponentExtensions { public static T GetOrAddComponent<T>(this GameObject gameObject) where T : Component { T component = gameObject.GetComponent<T>(); if (!Object.op_Implicit((Object)(object)component)) { return gameObject.AddComponent<T>(); } return component; } public static T GetRequiredComponent<T>(this GameObject gameObject) where T : Component { T component = gameObject.GetComponent<T>(); if (!Object.op_Implicit((Object)(object)component)) { throw new IncompatibilityException("\"" + ((Object)gameObject).name + "\" has no " + typeof(T).Name + "."); } return component; } public static T GetRequiredComponent<T>(this Component owner) where T : Component { return owner.gameObject.GetRequiredComponent<T>(); } public static T GetRequiredComponentInChildren<T>(this GameObject gameObject) where T : Component { T componentInChildren = gameObject.GetComponentInChildren<T>(true); if (!Object.op_Implicit((Object)(object)componentInChildren)) { throw new IncompatibilityException("\"" + ((Object)gameObject).name + "\" has no " + typeof(T).Name + " in its children."); } return componentInChildren; } public static Transform FindRequired(this Transform parent, string path) { Transform val = parent.Find(path); if (!Object.op_Implicit((Object)(object)val)) { throw new IncompatibilityException("\"" + ((Object)parent).name + "\" has no \"" + path + "\" child."); } return val; } } internal static class HeaderNavigationExtensions { public static MPButton SelectedButton(this HGHeaderNavigationController navigation) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) int currentHeaderIndex = navigation.currentHeaderIndex; List<Header> headers = navigation.headers; if (currentHeaderIndex < 0 || currentHeaderIndex >= headers.Count) { return null; } return headers[currentHeaderIndex].headerButton; } } internal sealed class PanelBackground { private static readonly string[] LayerNames = new string[2] { "BlurPanel", "ImagePanel" }; private readonly GameObject[] _layers; private PanelBackground(GameObject[] layers) { _layers = layers; } public static PanelBackground Of(Transform panelScrollView) { return new PanelBackground(LayerNames.Select((string name) => ((Component)panelScrollView.FindRequired(name)).gameObject).ToArray()); } public void CopyInto(RectTransform target) { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Expected O, but got Unknown for (int i = 0; i < _layers.Length; i++) { GameObject obj = Object.Instantiate<GameObject>(_layers[i], (Transform)(object)target); ((Object)obj).name = ((Object)_layers[i]).name; obj.transform.SetSiblingIndex(i); RectTransformExtensions.Stretch((RectTransform)obj.transform, Vector2.zero, Vector2.zero); obj.GetOrAddComponent<LayoutElement>().ignoreLayout = true; } } } internal abstract class PointerTarget : MonoBehaviour, IPointerDownHandler, IEventSystemHandler, IPointerClickHandler, IPointerEnterHandler, IPointerExitHandler { protected bool IsHovered { get; private set; } public void OnPointerDown(PointerEventData eventData) { } public void OnPointerClick(PointerEventData eventData) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) if ((int)eventData.button == 0) { OnLeftClick(); } } public void OnPointerEnter(PointerEventData eventData) { IsHovered = true; Refresh(); } public void OnPointerExit(PointerEventData eventData) { IsHovered = false; Refresh(); } protected abstract void OnLeftClick(); protected abstract void Refresh(); } internal readonly struct RectLayout { private readonly Vector2 _anchorMin; private readonly Vector2 _anchorMax; private readonly Vector2 _pivot; private readonly Vector2 _offsetMin; private readonly Vector2 _offsetMax; private RectLayout(RectTransform rect) { //IL_0002: 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_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: 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_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) _anchorMin = rect.anchorMin; _anchorMax = rect.anchorMax; _pivot = rect.pivot; _offsetMin = rect.offsetMin; _offsetMax = rect.offsetMax; } public static RectLayout Of(RectTransform rect) { return new RectLayout(rect); } public void ApplyTo(RectTransform rect) { //IL_0002: 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_001a: 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_0032: Unknown result type (might be due to invalid IL or missing references) rect.anchorMin = _anchorMin; rect.anchorMax = _anchorMax; rect.pivot = _pivot; rect.offsetMin = _offsetMin; rect.offsetMax = _offsetMax; } } internal static class RectTransformExtensions { private const int BottomLeftCorner = 0; private const int TopRightCorner = 2; private static readonly Vector3[] _corners = (Vector3[])(object)new Vector3[4]; public static void Stretch(this RectTransform rect, Vector2 insetMin, Vector2 insetMax) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) rect.anchorMin = Vector2.zero; rect.anchorMax = Vector2.one; rect.pivot = new Vector2(0.5f, 0.5f); rect.offsetMin = insetMin; rect.offsetMax = -insetMax; } public static void AnchorAt(this RectTransform rect, Vector2 anchor, Vector2 pivot) { //IL_0001: 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_000f: Unknown result type (might be due to invalid IL or missing references) rect.anchorMin = anchor; rect.anchorMax = anchor; rect.pivot = pivot; } public static Vector3 WorldBottomLeft(this RectTransform rect) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) rect.GetWorldCorners(_corners); return _corners[0]; } public static Vector3 WorldTopRight(this RectTransform rect) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) rect.GetWorldCorners(_corners); return _corners[2]; } } internal static class Sprites { private const string PinStarResource = "RiskOfOptionsExtender.PinStar.png"; private static Sprite _pinStar; public static Sprite PinStar { get { if (!Object.op_Implicit((Object)(object)_pinStar)) { _pinStar = FromPng(ReadResource("RiskOfOptionsExtender.PinStar.png")); } return _pinStar; } } public static Sprite FromPng(byte[] png) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Expected O, but got Unknown //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false); if (!ImageConversion.LoadImage(val, png)) { return null; } return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f)); } private static byte[] ReadResource(string name) { using Stream stream = typeof(Sprites).Assembly.GetManifestResourceStream(name); using MemoryStream memoryStream = new MemoryStream(); stream.CopyTo(memoryStream); return memoryStream.ToArray(); } } internal sealed class SuppressedRaycasts { private readonly List<Graphic> _graphics; private SuppressedRaycasts(List<Graphic> graphics) { _graphics = graphics; } public static SuppressedRaycasts Under(GameObject root, params GameObject[] except) { List<Graphic> list = (from graphic in root.GetComponentsInChildren<Graphic>(true) where graphic.raycastTarget && !except.Contains(((Component)graphic).gameObject) select graphic).ToList(); foreach (Graphic item in list) { item.raycastTarget = false; } return new SuppressedRaycasts(list); } public void Restore() { foreach (Graphic graphic in _graphics) { if (Object.op_Implicit((Object)(object)graphic)) { graphic.raycastTarget = true; } } _graphics.Clear(); } } internal static class UiButtons { public static GameObject Clone(GameObject template, Transform parent, string name, UnityAction onClick) { template.GetRequiredComponentInChildren<HGButton>(); GameObject val = Object.Instantiate<GameObject>(template, parent); ((Object)val).name = name; val.SetActive(true); LanguageTextMeshController[] componentsInChildren = val.GetComponentsInChildren<LanguageTextMeshController>(true); for (int i = 0; i < componentsInChildren.Length; i++) { Object.DestroyImmediate((Object)(object)componentsInChildren[i]); } HGButton componentInChildren = val.GetComponentInChildren<HGButton>(true); ((MPButton)componentInChildren).disablePointerClick = false; ((UnityEventBase)((Button)componentInChildren).onClick).RemoveAllListeners(); ((UnityEvent)((Button)componentInChildren).onClick).AddListener(onClick); return val; } } internal static class UiText { public static HGTextMeshProUGUI Create(string name, Transform parent, TMP_Text styleSource, float fontSize, Color color) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_002a: 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_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Expected O, but got Unknown //IL_0076: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name, new Type[1] { typeof(RectTransform) }) { layer = ((Component)parent).gameObject.layer }; val.transform.SetParent(parent, false); RectTransformExtensions.Stretch((RectTransform)val.transform, Vector2.zero, Vector2.zero); HGTextMeshProUGUI obj = val.AddComponent<HGTextMeshProUGUI>(); ((TMP_Text)obj).font = styleSource.font; ((TMP_Text)obj).fontSharedMaterial = styleSource.fontSharedMaterial; ((TMP_Text)obj).fontSize = fontSize; ((Graphic)obj).color = color; ((TMP_Text)obj).alignment = (TextAlignmentOptions)4097; ((TMP_Text)obj).enableWordWrapping = false; ((Graphic)obj).raycastTarget = false; return obj; } } } namespace RiskOfOptionsExtender.UI.OptionRows { internal static class ModSettingExtensions { public static TMP_Text NameText(this ModSetting row) { if (!Object.op_Implicit((Object)(object)row.nameLabel)) { return null; } TMP_Text component = ((Component)row.nameLabel).GetComponent<TMP_Text>(); if (!Object.op_Implicit((Object)(object)component)) { return ((Component)row.nameLabel).GetComponentInChildren<TMP_Text>(true); } return component; } public static bool IsRestartRequired(this ModSetting row) { if (string.IsNullOrEmpty(row.settingToken)) { return false; } try { return ModSettingsManager.OptionCollection.GetOption(row.settingToken).GetConfig().restartRequired; } catch (KeyNotFoundException) { return false; } } } internal sealed class OptionRowFitter : MonoBehaviour { private const float GapBeforeControl = 12f; private const float CheckboxRightInset = 12f; private static readonly HashSet<string> DecorationNames = new HashSet<string> { "BaseOutline", "HoverOutline", "Mod Settings Indicator" }; private static readonly HashSet<OptionRowFitter> _liveFitters = new HashSet<OptionRowFitter>(); private RectTransform _row; private RectTransform _label; private TMP_Text _text; private Image _checkbox; private FeatureGuard _guard; private bool _fitted; private OriginalRowState _original; private RectTransform _movedCheckboxContainer; private Vector2 _checkboxContainerOriginalPosition; private LayoutElement _addedLayoutElement; public static void RevertAll() { foreach (OptionRowFitter item in new List<OptionRowFitter>(_liveFitters)) { item.Revert(); } } public static void AttachToRows(ModOptionPanelController panelController, FeatureGuard guard) { ModSetting[] modSettings = panelController._modSettings; foreach (ModSetting val in modSettings) { if (Object.op_Implicit((Object)(object)val) && !Object.op_Implicit((Object)(object)((Component)val).GetComponent<OptionRowFitter>())) { AttachTo(val, guard); } } } private static void AttachTo(ModSetting row, FeatureGuard guard) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Expected O, but got Unknown TMP_Text val = row.NameText(); if (Object.op_Implicit((Object)(object)val)) { OptionRowFitter optionRowFitter = ((Component)row).gameObject.AddComponent<OptionRowFitter>(); optionRowFitter._row = (RectTransform)((Component)row).transform; optionRowFitter._text = val; optionRowFitter._label = val.rectTransform; optionRowFitter._checkbox = ((ModSettingsBool)(((row is ModSettingsBool) ? row : null)?)).checkBox; optionRowFitter._guard = guard; _liveFitters.Add(optionRowFitter); } } private void OnDestroy() { _liveFitters.Remove(this); } private void Revert() { if (_fitted) { RestoreRow(); } Object.Destroy((Object)(object)this); } private void RestoreRow() { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Expected O, but got Unknown _original.RestoreLabel(_label, _text); if (Object.op_Implicit((Object)(object)_movedCheckboxContainer)) { _movedCheckboxContainer.anchoredPosition = _checkboxContainerOriginalPosition; } LayoutElement layoutElement = default(LayoutElement); if (Object.op_Implicit((Object)(object)_addedLayoutElement)) { Object.Destroy((Object)(object)_addedLayoutElement); } else if (((Component)_row).TryGetComponent<LayoutElement>(ref layoutElement)) { _original.RestoreHeight(layoutElement); } LayoutRebuilder.MarkLayoutForRebuild((RectTransform)((Transform)_row).parent); } private void LateUpdate() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) Rect rect = _row.rect; if (!(((Rect)(ref rect)).width < 1f)) { ((Behaviour)this).enabled = false; _guard.Run("fit an option row", Fit); } } private void Fit() { //IL_003d: Unknown result type (might be due to invalid IL or missing references) _original = OriginalRowState.Capture(_row, _label, _text); _fitted = true; if (Object.op_Implicit((Object)(object)_checkbox)) { AlignCheckboxWithOtherControls(); } if (_label.anchorMax.x > 0.5f) { EndLabelBeforeControls(); } FitText(); } private void AlignCheckboxWithOtherControls() { //IL_0011: 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_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_006d: 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_007d: Unknown result type (might be due to invalid IL or missing references) float x = ((Transform)_row).InverseTransformPoint(((Graphic)_checkbox).rectTransform.WorldTopRight()).x; Rect rect = _row.rect; float num = ((Rect)(ref rect)).xMax - 12f - x; RectTransform val = ChildOfRowContaining(((Component)_checkbox).transform); if (Object.op_Implicit((Object)(object)val)) { _checkboxContainerOriginalPosition = val.anchoredPosition; _movedCheckboxContainer = val; val.anchoredPosition += new Vector2(num, 0f); } } private RectTransform ChildOfRowContaining(Transform descendant) { Transform val = descendant; while (Object.op_Implicit((Object)(object)val) && (Object)(object)val.parent != (Object)(object)_row) { val = val.parent; } return (RectTransform)(object)((val is RectTransform) ? val : null); } private void EndLabelBeforeControls() { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Expected O, but got Unknown //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_00de: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) float num = float.MaxValue; foreach (Transform item in (Transform)_row) { Transform val = item; if (!((Object)(object)val == (Object)(object)_label) && ((Component)val).gameObject.activeInHierarchy && !DecorationNames.Contains(((Object)val).name)) { Graphic[] componentsInChildren = ((Component)val).GetComponentsInChildren<Graphic>(); foreach (Graphic val2 in componentsInChildren) { num = Mathf.Min(num, ((Transform)_row).InverseTransformPoint(val2.rectTransform.WorldBottomLeft()).x); } } } if (num != float.MaxValue) { Rect rect = _row.rect; float num2 = ((Rect)(ref rect)).xMax + _label.offsetMax.x; float num3 = num - 12f; if (num3 < num2) { _label.offsetMax = new Vector2(_label.offsetMax.x - (num2 - num3), _label.offsetMax.y); } } } private void FitText() { //IL_003b: 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_004d: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) _text.enableAutoSizing = false; _text.enableWordWrapping = true; _text.overflowMode = (TextOverflowModes)0; TMP_Text text = _text; string text2 = _text.text; Rect rect = _label.rect; float y = text.GetPreferredValues(text2, ((Rect)(ref rect)).width, 0f).y; rect = _label.rect; float num = y - ((Rect)(ref rect)).height; if (num > 0f) { GrowRow(num); } } private void GrowRow(float extraHeight) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Expected O, but got Unknown LayoutElement val = default(LayoutElement); if (!((Component)_row).TryGetComponent<LayoutElement>(ref val)) { val = (_addedLayoutElement = ((Component)_row).gameObject.AddComponent<LayoutElement>()); } Rect rect = _row.rect; float num = ((Rect)(ref rect)).height + extraHeight; val.minHeight = Mathf.Max(val.minHeight, num); val.preferredHeight = Mathf.Max(val.preferredHeight, num); LayoutRebuilder.MarkLayoutForRebuild((RectTransform)((Transform)_row).parent); } } internal readonly struct OriginalRowState { private readonly Vector2 _labelOffsetMax; private readonly bool _wordWrapping; private readonly TextOverflowModes _overflowMode; private readonly bool _autoSizing; private readonly float _minHeight; private readonly float _preferredHeight; private OriginalRowState(RectTransform row, RectTransform label, TMP_Text text) { //IL_0002: 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_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) _labelOffsetMax = label.offsetMax; _wordWrapping = text.enableWordWrapping; _overflowMode = text.overflowMode; _autoSizing = text.enableAutoSizing; _minHeight = 0f; _preferredHeight = 0f; LayoutElement val = default(LayoutElement); if (((Component)row).TryGetComponent<LayoutElement>(ref val)) { _minHeight = val.minHeight; _preferredHeight = val.preferredHeight; } } public static OriginalRowState Capture(RectTransform row, RectTransform label, TMP_Text text) { return new OriginalRowState(row, label, text); } public void RestoreLabel(RectTransform label, TMP_Text text) { //IL_0002: 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) label.offsetMax = _labelOffsetMax; text.enableWordWrapping = _wordWrapping; text.overflowMode = _overflowMode; text.enableAutoSizing = _autoSizing; } public void RestoreHeight(LayoutElement layoutElement) { layoutElement.minHeight = _minHeight; layoutElement.preferredHeight = _preferredHeight; } } internal sealed class RestartIcon : MonoBehaviour { private const float Size = 26f; private const float Gap = 6f; private const string SpritePath = "assets/RiskOfOptions/ror2RestartSymbol.png"; private static readonly Color Tint = new Color(1f, 0.5f, 0.5f, 0.85f); private static readonly HashSet<RestartIcon> _liveIcons = new HashSet<RestartIcon>(); private static Sprite _sprite; private RectTransform _label; public static void AddToRows(ModOptionPanelController panelController) { ModSetting[] modSettings = panelController._modSettings; foreach (ModSetting val in modSettings) { if (Object.op_Implicit((Object)(object)val) && val.IsRestartRequired() && !Object.op_Implicit((Object)(object)((Component)val).GetComponentInChildren<RestartIcon>(true))) { AddTo(val); } } } public static void RemoveAll() { foreach (RestartIcon item in _liveIcons.ToList()) { item.Remove(); } } private static void AddTo(ModSetting row) { //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0070: 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_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Expected O, but got Unknown //IL_009c: 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_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00da: 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) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) TMP_Text val = row.NameText(); if (Object.op_Implicit((Object)(object)val)) { Sprite sprite = LoadSprite(); RectTransform rectTransform = val.rectTransform; GameObject val2 = new GameObject("Restart Required Icon", new Type[3] { typeof(RectTransform), typeof(CanvasRenderer), typeof(Image) }) { layer = ((Component)row).gameObject.layer }; RectTransform val3 = (RectTransform)val2.transform; ((Transform)val3).SetParent((Transform)(object)rectTransform, false); RectTransformExtensions.AnchorAt(val3, new Vector2(0f, 0.5f), new Vector2(0f, 0.5f)); val3.sizeDelta = new Vector2(26f, 26f); val3.anchoredPosition = new Vector2(-32f, 0f); Image component = val2.GetComponent<Image>(); component.sprite = sprite; component.preserveAspect = true; ((Graphic)component).color = Tint; ((Graphic)component).raycastTarget = false; RestartIcon restartIcon = val2.AddComponent<RestartIcon>(); restartIcon._label = rectTransform; _liveIcons.Add(restartIcon); rectTransform.offsetMin += new Vector2(32f, 0f); } } private static Sprite LoadSprite() { if (!Object.op_Implicit((Object)(object)_sprite)) { _sprite = Assets.Load<Sprite>("assets/RiskOfOptions/ror2RestartSymbol.png"); } if (!Object.op_Implicit((Object)(object)_sprite)) { throw new IncompatibilityException("Risk Of Options has no \"assets/RiskOfOptions/ror2RestartSymbol.png\" sprite."); } return _sprite; } private void Remove() { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)_label)) { RectTransform label = _label; label.offsetMin -= new Vector2(32f, 0f); } Object.Destroy((Object)(object)((Component)this).gameObject); } private void OnDestroy() { _liveIcons.Remove(this); } } internal static class RestartNotes { private const string RiskOfOptionsTokenPrefix = "RISK_OF_OPTIONS"; private const string Note = "<color=#FF8080>Requires a restart to take effect.</color>"; private static readonly Dictionary<string, string> _originalDescriptions = new Dictionary<string, string>(); public static void Apply() { foreach (OptionCollection item in ModSettingsManager.OptionCollection) { foreach (BaseOption item2 in RegisteredEntries.OptionsOf(item)) { if (item2.GetConfig().restartRequired) { string descriptionToken = item2.GetDescriptionToken(); if (descriptionToken.StartsWith("RISK_OF_OPTIONS", StringComparison.Ordinal)) { string text = item2.Description ?? ""; _originalDescriptions[descriptionToken] = text; LanguageApi.Add(descriptionToken, (text.Length == 0) ? "<color=#FF8080>Requires a restart to take effect.</color>" : (text + "\n\n<color=#FF8080>Requires a restart to take effect.</color>")); } } } } } public static void Remove() { foreach (KeyValuePair<string, string> originalDescription in _originalDescriptions) { LanguageApi.Add(originalDescription.Key, originalDescription.Value); } _originalDescriptions.Clear(); } } } namespace RiskOfOptionsExtender.UI.ModList { internal sealed class ModListEntry(ModListButton button, Header header, string displayName, bool isEmpty) { public ModListButton Button { get; } = button; public Header Header { get; } = header; public string DisplayName { get; } = displayName; public bool IsEmpty { get; } = isEmpty; public string ModGuid => Button.modGuid; } internal sealed class ModListGuards(FeatureGuard organizer, FeatureGuard toolbar, FeatureGuard pins) { public FeatureGuard Organizer { get; } = organizer; public FeatureGuard Toolbar { get; } = toolbar; public FeatureGuard Pins { get; } = pins; } internal sealed class ModListOrganizer : MonoBehaviour { private static readonly Regex RichTextTag = new Regex("<.*?>", RegexOptions.Compiled); private static readonly HashSet<ModListOrganizer> _liveOrganizers = new HashSet<ModListOrganizer>(); private readonly List<ModListEntry> _entries = new List<ModListEntry>(); private readonly List<PinToggle> _pins = new List<PinToggle>(); private ModOptionsPanelPrefab _panel; private HGHeaderNavigationController _navigation; private List<Header> _originalHeaders; private ExtenderSettings _settings; private ModListGuards _guards; private ModListToolbar _toolbar; private SuppressedRaycasts _highlightRaycasts; private bool _tweaksShown; private string _filter = ""; public static void AttachOrRefresh(ModOptionPanelController panelController, ExtenderSettings settings, ModListGuards guards) { ModOptionsPanelPrefab panel = panelController._panel; if (panel != null && Object.op_Implicit((Object)(object)panel.ModListPanel)) { ModListOrganizer modListOrganizer = panel.ModListPanel.GetComponent<ModListOrganizer>(); if (!Object.op_Implicit((Object)(object)modListOrganizer)) { modListOrganizer = Create(panel, settings, guards); } modListOrganizer.Refresh(); } } public static void Release(ModOptionPanelController panelController) { ModOptionsPanelPrefab panel = panelController._panel; if (panel != null && Object.op_Implicit((Object)(object)panel.ModListPanel)) { ModListOrganizer component = panel.ModListPanel.GetComponent<ModListOrganizer>(); if (Object.op_Implicit((Object)(object)component)) { component.ReleaseList(); } } } public static void RemoveAllToolbars() { foreach (ModListOrganizer item in _liveOrganizers.ToList()) { item.RemoveToolbar(); item.ReorderGuarded(); } } public static void RemoveAllPins() { foreach (ModListOrganizer item in _liveOrganizers.ToList()) { item.RemovePins(); } } public bool IsPinned(string modGuid) { return _settings.PinnedMods.Contains(modGuid); } public void TogglePin(string modGuid) { _settings.PinnedMods.Toggle(modGuid); ReorderGuarded(); } private static ModListOrganizer Create(ModOptionsPanelPrefab panel, ExtenderSettings settings, ModListGuards guards) { HGHeaderNavigationController requiredComponent = panel.ModListPanel.GetRequiredComponent<HGHeaderNavigationController>(); List<Header> list = requiredComponent.headers.ToList(); List<ModListEntry> collection = list.Where((Header header) => header.headerButton is ModListButton).Select(EntryOf).ToList(); ModListOrganizer modListOrganizer = panel.ModListPanel.AddComponent<ModListOrganizer>(); modListOrganizer._panel = panel; modListOrganizer._navigation = requiredComponent; modListOrganizer._originalHeaders = list; modListOrganizer._entries.AddRange(collection); modListOrganizer._settings = settings; modListOrganizer._guards = guards; _liveOrganizers.Add(modListOrganizer); settings.SortOrder.SettingChanged += modListOrganizer.OnSortOrderChanged; return modListOrganizer; } private static ModListEntry EntryOf(Header header) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown //IL_001e: Unknown result type (might be due to invalid IL or missing references) ModListButton val = (ModListButton)header.headerButton; OptionCollection collection = ModSettingsManager.OptionCollection[val.modGuid]; return new ModListEntry(val, header, DisplayNameOf(collection), RegisteredEntries.CountOptions(collection) == 0); } private void Refresh() { if (_settings.ModListTweaks.Value) { ShowTweaks(); } else { HideTweaks(); } Reorder(); } private void ShowTweaks() { _tweaksShown = true; _guards.Toolbar.Run("add the mod list search and sort bar", AddToolbar); _guards.Pins.Run("add the mod list pin stars", AddPins); } private void HideTweaks() { _tweaksShown = false; RemoveToolbar(); RemovePins(); } private void AddToolbar() { if (!Object.op_Implicit((Object)(object)_toolbar)) { _toolbar = ModListToolbar.Create(_panel, _settings.SortOrder, SetFilter); } } private void AddPins() { if (_pins.Count > 0) { return; } _highlightRaycasts = SuppressSelectionHighlightRaycasts(); foreach (ModListEntry entry in _entries) { _pins.Add(PinToggle.AddTo(entry.Button, this)); } } private void RemoveToolbar() { if (Object.op_Implicit((Object)(object)_toolbar)) { _toolbar.Remove(); } _toolbar = null; _filter = ""; } private void RemovePins() { foreach (PinToggle pin in _pins) { if (Object.op_Implicit((Object)(object)pin)) { pin.Remove(); } } _pins.Clear(); _highlightRaycasts?.Restore(); _highlightRaycasts = null; } private SuppressedRaycasts SuppressSelectionHighlightRaycasts() { GameObject headerHighlightObject = _navigation.headerHighlightObject; if (!Object.op_Implicit((Object)(object)headerHighlightObject)) { return null; } return SuppressedRaycasts.Under(headerHighlightObject); } private void ReleaseList() { HideTweaks(); MPButton selectedButton = _navigation.SelectedButton(); for (int i = 0; i < _entries.Count; i++) { ((Component)_entries[i].Button).gameObject.SetActive(true); ((Component)_entries[i].Button).transform.SetSiblingIndex(i); } _navigation.headers = _originalHeaders; _navigation.currentHeaderIndex = _originalHeaders.FindIndex((Header header) => (Object)(object)header.headerButton == (Object)(object)selectedButton); Object.Destroy((Object)(object)this); } private void SetFilter(string filter) { _filter = filter?.Trim() ?? ""; ReorderGuarded(); } private void ReorderGuarded() { _guards.Organizer.Run("organize the mod list", Reorder); } private void Reorder() { MPButton selectedButton = _navigation.SelectedButton(); List<ModListEntry> list = SortEntries(_entries.Where(IsVisible)).ToList(); HashSet<ModListEntry> hashSet = new HashSet<ModListEntry>(list); foreach (ModListEntry entry in _entries) { ((Component)entry.Button).gameObject.SetActive(hashSet.Contains(entry)); } for (int i = 0; i < list.Count; i++) { ((Component)list[i].Button).transform.SetSiblingIndex(i); } _navigation.headers = list.Select((ModListEntry entry) => entry.Header).ToList(); _navigation.currentHeaderIndex = list.FindIndex((ModListEntry entry) => (Object)(object)entry.Button == (Object)(object)selectedButton); } private void OnEnable() { if (Object.op_Implicit((Object)(object)_navigation)) { ReorderGuarded(); } } private void OnDestroy() { _liveOrganizers.Remove(this); if (_settings != null) { _settings.SortOrder.SettingChanged -= OnSortOrderChanged; } } private void OnSortOrderChanged(object sender, EventArgs args) { ReorderGuarded(); } private IEnumerable<ModListEntry> SortEntries(IEnumerable<ModListEntry> entries) { if (!_tweaksShown) { return entries; } IOrderedEnumerable<ModListEntry> source = entries.OrderByDescending((ModListEntry entry) => IsPinned(entry.ModGuid)); if (_settings.SortOrder.Value != ModSortOrder.ReverseAlphabetical) { return source.ThenBy<ModListEntry, string>((ModListEntry entry) => entry.DisplayName, StringComparer.CurrentCultureIgnoreCase); } return source.ThenByDescending<ModListEntry, string>((ModListEntry entry) => entry.DisplayName, StringComparer.CurrentCultureIgnoreCase); } private bool IsVisible(ModListEntry entry) { if (entry.IsEmpty && _settings.HideEmptyMods.Value) { return false; } if (_filter.Length != 0 && entry.DisplayName.IndexOf(_filter, StringComparison.CurrentCultureIgnoreCase) < 0) { return entry.ModGuid.IndexOf(_filter, StringComparison.OrdinalIgnoreCase) >= 0; } return true; } private static string DisplayNameOf(OptionCollection collection) { return RichTextTag.Replace(Language.GetString(collection.NameToken), "").Trim(); } } internal sealed class ModListToolbar : MonoBehaviour { private const float Height = 64f; private const float Gap = 8f; private const float SortButtonWidth = 96f; private ConfigEntry<ModSortOrder> _sortOrder; private TMP_Text _sortLabel; private RectTransform _scrollView; public static ModListToolbar Create(ModOptionsPanelPrefab panel, ConfigEntry<ModSortOrder> sortOrder, UnityAction<string> onSearchChanged) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Expected O, but got Unknown RectTransform val = (RectTransform)panel.ModListPanel.transform.FindRequired("Scroll View"); PanelBackground background = PanelBackground.Of((Transform)(object)val); TMP_Text requiredComponentInChildren = panel.ModListButton.GetRequiredComponentInChildren<TMP_Text>(); GameObject val2 = new GameObject("Mod List Toolbar", new Type[1] { typeof(RectTransform) }); try { ModListToolbar modListToolbar = val2.AddComponent<ModListToolbar>(); modListToolbar.Build(panel, val, background, requiredComponentInChildren, sortOrder, onSearchChanged); return modListToolbar; } catch { Object.Destroy((Object)(object)val2); throw; } } public void Remove() { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)_scrollView)) { RectTransform scrollView = _scrollView; scrollView.offsetMax += new Vector2(0f, 72f); } Object.Destroy((Object)(object)((Component)this).gameObject); } private void Build(ModOptionsPanelPrefab panel, RectTransform scrollView, PanelBackground background, TMP_Text styleSource, ConfigEntry<ModSortOrder> sortOrder, UnityAction<string> onSearchChanged) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Expected O, but got Unknown //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0087: 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_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Expected O, but got Unknown //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_0137: 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) Transform transform = panel.ModListPanel.transform; ((Component)this).gameObject.layer = ((Component)transform).gameObject.layer; RectTransform val = (RectTransform)((Component)this).transform; ((Transform)val).SetParent(transform, false); val.anchorMin = new Vector2(0f, 1f); val.anchorMax = Vector2.one; val.pivot = new Vector2(0.5f, 1f); val.sizeDelta = new Vector2(0f, 64f); val.anchoredPosition = new Vector2(0f, scrollView.offsetMax.y); background.CopyInto(val); HorizontalLayoutGroup obj = ((Component)this).gameObject.AddComponent<HorizontalLayoutGroup>(); ((LayoutGroup)obj).padding = new RectOffset(8, 8, 8, 8); ((HorizontalOrVerticalLayoutGroup)obj).spacing = 8f; ((HorizontalOrVerticalLayoutGroup)obj).childControlWidth = true; ((HorizontalOrVerticalLayoutGroup)obj).childControlHeight = true; ((HorizontalOrVerticalLayoutGroup)obj).childForceExpandWidth = false; ((HorizontalOrVerticalLayoutGroup)obj).childForceExpandHeight = true; SearchField.Create((Transform)(object)val, styleSource, onSearchChanged); CreateSortButton(panel, val); _sortOrder = sortOrder; _sortOrder.SettingChanged += OnSortOrderChanged; RefreshSortLabel(); _scrollView = scrollView; RectTransform scrollView2 = _scrollView; scrollView2.offsetMax -= new Vector2(0f, 72f); } private void CreateSortButton(ModOptionsPanelPrefab panel, RectTransform toolbar) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected O, but got Unknown GameObject gameObject = UiButtons.Clone(panel.CategoryLeftButton, (Transform)(object)toolbar, "Sort Order Button", new UnityAction(CycleSortOrder)); LayoutElement orAddComponent = gameObject.GetOrAddComponent<LayoutElement>(); orAddComponent.minWidth = 96f; orAddComponent.preferredWidth = 96f; _sortLabel = gameObject.GetRequiredComponentInChildren<TMP_Text>(); _sortLabel.fontSize = 24f; _sortLabel.alignment = (TextAlignmentOptions)514; } private void OnDestroy() { if (_sortOrder != null) { _sortOrder.SettingChanged -= OnSortOrderChanged; } } private void OnSortOrderChanged(object sender, EventArgs args) { RefreshSortLabel(); } private void CycleSortOrder() { _sortOrder.Value = ((_sortOrder.Value == ModSortOrder.Alphabetical) ? ModSortOrder.ReverseAlphabetical : ModSortOrder.Alphabetical); } private void RefreshSortLabel() { if (Object.op_Implicit((Object)(object)_sortLabel)) { _sortLabel.text = ((_sortOrder.Value == ModSortOrder.Alphabetical) ? "A-Z" : "Z-A"); } } } internal sealed class PinToggle : PointerTarget { private const float Size = 28f; private const float RightInset = 12f; private static readonly Color PinnedColor = new Color(1f, 0.78f, 0.25f, 1f); private static readonly Color UnpinnedColor = new Color(1f, 1f, 1f, 0.2f); private static readonly Color HoveredColor = new Color(1f, 1f, 1f, 0.6f); private SuppressedRaycasts _rowRaycasts; private RectTransform _label; private Image _image; private string _modGuid; private ModListOrganizer _organizer; public static PinToggle AddTo(ModListButton button, ModListOrganizer organizer) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Expected O, but got Unknown //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Expected O, but got Unknown //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_0077: 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_0091: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Expected O, but got Unknown //IL_009b: 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_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Unknown result type (might be due to invalid IL or missing references) RectTransform val = (RectTransform)((Component)button).transform.FindRequired("ButtonText"); GameObject val2 = new GameObject("Pin Toggle", new Type[3] { typeof(RectTransform), typeof(CanvasRenderer), typeof(Image) }); val2.layer = ((Component)button).gameObject.layer; RectTransform val3 = (RectTransform)val2.transform; ((Transform)val3).SetParent(((Component)button).transform, false); RectTransformExtensions.AnchorAt(val3, new Vector2(1f, 0.5f), new Vector2(1f, 0.5f)); val3.sizeDelta = new Vector2(28f, 28f); val3.anchoredPosition = new Vector2(-12f, 0f); PinToggle pinToggle = val2.AddComponent<PinToggle>(); pinToggle._image = val2.GetComponent<Image>(); pinToggle._image.sprite = Sprites.PinStar; pinToggle._image.preserveAspect = true; pinToggle._modGuid = button.modGuid; pinToggle._organizer = organizer; pinToggle._label = val; pinToggle._rowRaycasts = SuppressedRaycasts.Under(((Component)button).gameObject, ((Component)button).gameObject, val2); pinToggle.Refresh(); val.offsetMax -= new Vector2(40f, 0f); return pinToggle; } public void Remove() { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)_label)) { RectTransform label = _label; label.offsetMax += new Vector2(40f, 0f); } _rowRaycasts?.Restore(); Object.Destroy((Object)(object)((Component)this).gameObject); } protected override void OnLeftClick() { _organizer.TogglePin(_modGuid); Refresh(); } protected override void Refresh() { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) if (_organizer.IsPinned(_modGuid)) { ((Graphic)_image).color = PinnedColor; } else { ((Graphic)_image).color = (base.IsHovered ? HoveredColor : UnpinnedColor); } } } internal static class SearchField { private const float FontSize = 22f; private static readonly Color Background = new Color(0f, 0f, 0f, 0.45f); private static readonly Color PlaceholderColor = new Color(1f, 1f, 1f, 0.4f); public static TMP_InputField Create(Transform parent, TMP_Text styleSource, UnityAction<string> onChanged) { //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Expected O, but got Unknown //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Expected O, but got Unknown //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_018f: Unknown result type (might be due to invalid IL or missing references) //IL_019d: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("Search Field", new Type[4] { typeof(RectTransform), typeof(CanvasRenderer), typeof(Image), typeof(LayoutElement) }); val.SetActive(false); val.layer = ((Component)parent).gameObject.layer; val.transform.SetParent(parent, false); ((Graphic)val.GetComponent<Image>()).color = Background; LayoutElement component = val.GetComponent<LayoutElement>(); component.flexibleWidth = 1f; component.minWidth = 64f; GameObject val2 = new GameObject("Text Area", new Type[2] { typeof(RectTransform), typeof(RectMask2D) }) { layer = val.layer }; val2.transform.SetParent(val.transform, false); RectTransform val3 = (RectTransform)val2.transform; val3.Stretch(new Vector2(12f, 4f), new Vector2(12f, 4f)); HGTextMeshProUGUI val4 = UiText.Create("Text", (Transform)(object)val3, styleSource, 22f, Color.white); HGTextMeshProUGUI val5 = UiText.Create("Placeholder", (Transform)(object)val3, styleSource, 22f, PlaceholderColor); ((TMP_Text)val5).text = "Search mods..."; ((TMP_Text)val5).fontStyle = (FontStyles)2; TMP_InputField obj = val.AddComponent<TMP_InputField>(); obj.textViewport = val3; obj.textComponent = (TMP_Text)(object)val4; obj.placeholder = (Graphic)(object)val5; obj.fontAsset = ((TMP_Text)val4).font; obj.pointSize = 22f; obj.lineType = (LineType)0; obj.richText = false; Navigation navigation = default(Navigation); ((Navigation)(ref navigation)).mode = (Mode)0; ((Selectable)obj).navigation = navigation; ((UnityEvent<string>)(object)obj.onValueChanged).AddListener(onChanged); val.SetActive(true); return obj; } } } namespace RiskOfOptionsExtender.UI.Features { internal sealed class CategoryPickerFeature(ExtenderSettings settings) : PanelFeature("the All Tabs picker") { protected override bool IsEnabled => settings.OptionPageTweaks.Value; protected override Hook CreateHook() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Expected O, but got Unknown return new Hook((MethodBase)PanelMethods.LoadModOptions, (Delegate)new Action<Action<ModOptionPanelController, string>, ModOptionPanelController, string>(ShowPickerAfterModLoaded)); } protected override void ApplyToOpenPanels() { foreach (ModOptionPanelController item in LivePanels.All) { string text = LivePanels.OpenModGuid(item); if (text != null) { CategoryPicker.ShowFor(item, text, base.Guard); } } } protected override void RemoveFromOpenPanels() { CategoryPicker.RemoveAll(); } private void ShowPickerAfterModLoaded(Action<ModOptionPanelController, string> orig, ModOptionPanelController self, string modGuid) { orig(self, modGuid); LivePanels.Register(self); base.Guard.Run("show the All Tabs picker", delegate { CategoryPicker.ShowFor(self, modGuid, base.Guard); }); } } internal static class LivePanels { private static readonly List<ModOptionPanelController> _panels = new List<ModOptionPanelController>(); public static IReadOnlyList<ModOptionPanelController> All { get { _panels.RemoveAll((ModOptionPanelController panel) => !Object.op_Implicit((Object)(object)panel)); return _panels.ToArray(); } } public static void Register(ModOptionPanelController panel) { if (!_panels.Contains(panel)) { _panels.Add(panel); } } public static string OpenModGuid(ModOptionPanelController panel) { ModOptionsPanelPrefab panel2 = panel._panel; if (panel2 == null || !Object.op_Implicit((Object)(object)panel2.CategoryHeader) || !panel2.CategoryHeader.activeSelf) { return null; } MPButton obj = panel2.ModListPanel.GetRequiredComponent<HGHeaderNavigationController>().SelectedButton(); return ((ModListButton)(((obj is ModListButton) ? obj : null)?)).modGuid; } } internal sealed class ModListFeature : PanelFeature { private readonly ExtenderSettings _settings; private readonly ModListGuards _guards; protected override bool IsEnabled { get { if (!_settings.ModListTweaks.Value) { return _settings.HideEmptyMods.Value; } return true; } } public ModListFeature(ExtenderSettings settings) : base("the mod list organizer") { _settings = settings; _guards = new ModListGuards(base.Guard, new FeatureGuard("the mod list search and sort bar", ModListOrganizer.RemoveAllToolbars), new FeatureGuard("the mod list pin stars", ModListOrganizer.RemoveAllPins)); } protected override Hook CreateHook() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Expected O, but got Unknown return new Hook((MethodBase)PanelMethods.Start, (Delegate)new Action<Action<ModOptionPanelController>, ModOptionPanelController>(OrganizeAfterPanelStart)); } protected override void ApplyToOpenPanels() { foreach (ModOptionPanelController item in LivePanels.All) { ModListOrganizer.AttachOrRefresh(item, _settings, _guards); } } protected override void RemoveFromOpenPanels() { foreach (ModOptionPanelController item in LivePanels.All) { ModListOrganizer.Release(item); } } private void OrganizeAfterPanelStart(Action<ModOptionPanelController> orig, ModOptionPanelController self) { orig(self); LivePanels.Register(self); base.Guard.Run("organize the mod list", delegate { ModListOrganizer.AttachOrRefresh(self, _settings, _guards); }); } } internal abstract class PanelFeature { private readonly string _name; private Hook _hook; protected FeatureGuard Guard { get; } protected abstract bool IsEnabled { get; } protected PanelFeature(string name) { _name = name; Guard = new FeatureGuard(name, TurnOff); } public void Sync() { if (IsEnabled) { Guard.Run("turn on " + _name, TurnOn); } else { Guard.Run("turn off " + _name, TurnOff); } } protected abstract Hook CreateHook(); protected abstract void ApplyToOpenPanels(); protected abstract void RemoveFromOpenPanels(); private void TurnOn() { if (_hook == null) { _hook = CreateHook(); } ApplyToOpenPanels(); } private void TurnOff() { Hook hook = _hook; if (hook != null) { hook.Dispose(); } _hook = null; RemoveFromOpenPanels(); } } internal static class PanelHooks { private static Hook _startHook; public static void Install(ExtenderSettings settings) { new FeatureGuard("filling in missing options").Run("hook the settings panel's Start", InstallStartHook); SyncWith(new ConfigEntry<bool>[2] { settings.ModListTweaks, settings.HideEmptyMods }, new ModListFeature(settings)); SyncWith(new ConfigEntry<bool>[1] { settings.OptionPageTweaks }, new RowFittingFeature(settings), new RestartIconFeature(settings), new RestartNotesFeature(settings), new CategoryPickerFeature(settings)); } private static void SyncWith(ConfigEntry<bool>[] settings, params PanelFeature[] features) { for (int i = 0; i < settings.Length; i++) { settings[i].SettingChanged += delegate { SyncAll(features); }; } SyncAll(features); } private static void SyncAll(PanelFeature[] features) { for (int i = 0; i < features.Length; i++) { features[i].Sync(); } } private static void InstallStartHook() { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Expected O, but got Unknown _startHook = new Hook((MethodBase)PanelMethods.Start, (Delegate)new Action<Action<ModOptionPanelController>, ModOptionPanelController>(BeforePanelStart)); } private static void BeforePanelStart(Action<ModOptionPanelController> orig, ModOptionPanelController self) { LivePanels.Register(self); OptionGeneration.Run(); orig(self); } } internal static class PanelMethods { private const BindingFlags AnyInstanceMethod = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; public static MethodInfo Start => Find("Start"); public static MethodInfo LoadModOptions => Find("LoadModOptionsFromOptionCollection", typeof(string)); public static MethodInfo LoadCategory => Find("LoadOptionListFromCategory", typeof(string), typeof(int)); private static MethodInfo Find(string name, params Type[] parameterTypes) { return typeof(ModOptionPanelController).GetMethod(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, parameterTypes, null) ?? throw new IncompatibilityException("ModOptionPanelController." + name + "(" + string.Join(", ", (IEnumerable<Type>)parameterTypes) + ") no longer exists."); } } internal sealed class RestartIconFeature(ExtenderSettings settings) : PanelFeature("the restart icons") { protected override bool IsEnabled => settings.OptionPageTweaks.Value; protected override Hook CreateHook() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Expected O, but got Unknown return new Hook((MethodBase)PanelMethods.LoadCategory, (Delegate)new Action<Action<ModOptionPanelController, string, int>, ModOptionPanelController, string, int>(AddIconsAfterCategoryLoaded)); } protected override void ApplyToOpenPanels() { foreach (ModOptionPanelController item in LivePanels.All) { RestartIcon.AddToRows(item); } } protected override void RemoveFromOpenPanels() { RestartIcon.RemoveAll(); } private void AddIconsAfterCategoryLoaded(Action<ModOptionPanelController, string, int> orig, ModOptionPanelController self, string modGuid, int categoryIndex) { orig(self, modGuid, categoryIndex); LivePanels.Register(self); base.Guard.Run("add restart icons", delegate { RestartIcon.AddToRows(self); }); } } internal sealed class RestartNotesFeature(ExtenderSettings settings) : PanelFeature("the restart notes") { protected override bool IsEnabled => settings.OptionPageTweaks.Value; protected override Hook CreateHook() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Expected O, but got Unknown return new Hook((MethodBase)PanelMethods.Start, (Delegate)new Action<Action<ModOptionPanelController>, ModOptionPanelController>(AddNotesAfterPanelStart)); } protected override void ApplyToOpenPanels() { RestartNotes.Apply(); } protected override void RemoveFromOpenPanels() { RestartNotes.Remove(); } private void AddNotesAfterPanelStart(Action<ModOptionPanelController> orig, ModOptionPanelController self) { orig(self); LivePanels.Register(self); base.Guard.Run("add restart notes", RestartNotes.Apply); } } internal sealed class RowFittingFeature(ExtenderSettings settings) : PanelFeature("full option names and aligned checkboxes") { protected override bool IsEnabled => settings.OptionPageTweaks.Value; protected override Hook CreateHook() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Expected O, but got Unknown return new Hook((MethodBase)PanelMethods.LoadCategory, (Delegate)new Action<Action<ModOptionPanelController, string, int>, ModOptionPanelController, string, int>(FitRowsAfterCategoryLoaded)); } protected override void ApplyToOpenPanels() { foreach (ModOptionPanelController item in LivePanels.All) { OptionRowFitter.AttachToRows(item, base.Guard); } } protected override void RemoveFromOpenPanels() { OptionRowFitter.RevertAll(); } private void FitRowsAfterCategoryLoaded(Action<ModOptionPanelController, string, int> orig, ModOptionPanelController self, string modGuid, int categoryIndex) { orig(self, modGuid, categoryIndex); LivePanels.Register(self); base.Guard.Run("fit option rows", delegate { OptionRowFitter.AttachToRows(self, base.Guard); }); } } } namespace RiskOfOptionsExtender.UI.CategoryPicking { internal sealed class CategoryPicker : MonoBehaviour { private const int TabsPerPage = 4; private const int PickerButtonSlots = 1; private const float MaxTabWidth = 200f; private const float Margin = 12f; private const float ArrowSize = 64f; private const float RightArrowCenterFromEdge = 60f; private const float RightArrowAreaWidth = 104f; private const float LeftOfTabsFixedWidth = 100f; private const float TabHeightShareOfViewport = 0.6f; private static readonly HashSet<CategoryPicker> _livePickers = new HashSet<CategoryPicker>(); private RectTransform _scrollView; private RectTransform _viewport; private RectTransform _leftArrow; private CategoryScrollRect _tabs; private HGHeaderNavigationController _tabNavigation; private RectTransform _button; private TMP_Text _buttonLabel; private CategoryPickerPopup _popup; private FeatureGuard _guard; private OptionCollection _collection; private bool _layoutPending; private RectLayout _viewportLayout; private RectLayout _leftArrowLayout; public static void ShowFor(ModOptionPanelController panelController, string modGuid, FeatureGuard guard) { CategoryPicker orCreate = GetOrCreate(panelController._panel, guard); OptionCollection val = ModSettingsManager.OptionCollection[modGuid]; if (val.CategoryCount > 4) { orCreate.Show(val); } else { orCreate.Hide(); } } public static void RemoveAll() { foreach (CategoryPicker item in _livePickers.ToList()) { item.Remove(); } } private static CategoryPicker GetOrCreate(ModOptionsPanelPrefab panel, FeatureGuard guard) { CategoryPicker component = panel.CategoryHeader.GetComponent<CategoryPicker>(); if (Object.op_Implicit((Object)(object)component)) { return component; } component = panel.CategoryHeader.AddComponent<CategoryPicker>(); try { component.Initialize(panel, guard); } catch { component.DestroyCreatedObjects(); throw; } _livePickers.Add(component); return component; } private void Initialize(ModOptionsPanelPrefab panel, FeatureGuard guard) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Expected O, but got Unknown //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Expected O, but got Unknown //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Expected O, but got Unknown _guard = guard; _scrollView = (RectTransform)panel.CategoryHeader.transform.FindRequired("Scroll View"); _viewport = (RectTransform)((Transform)(object)_scrollView).FindRequired("Viewport"); _leftArrow = (RectTransform)panel.CategoryLeftButton.transform; _tabs = ((Component)(object)_scrollView).GetRequiredComponent<CategoryScrollRect>(); _tabNavigation = ((Component)(object)_tabs.categoryTransform).GetRequiredComponent<HGHeaderNavigationController>(); _viewportLayout = RectLayout.Of(_viewport); _leftArrowLayout = RectLayout.Of(_leftArrow); CreateButton(panel); Transform panelScrollView = panel.ModListPanel.transform.FindRequired("Scroll View"); _popup = CategoryPickerPopup.Create(panel.CategoryHeader.transform, _button, _buttonLabel, panelScrollView, SelectCategory); } private void CreateButton(ModOptionsPanelPrefab panel) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Expected O, but got Unknown //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) GameObject val = UiButtons.Clone(panel.CategoryHeaderButton, (Transform)(object)_scrollView, "Category Picker Button", new UnityAction(TogglePopup)); val.SetActive(false); _button = (RectTransform)val.transform; _button.AnchorAt(new Vector2(0f, 0.5f), new Vector2(0f, 0.5f)); _button.anchoredPosition = new Vector2(12f, 0f); RectTransform button = _button; Rect rect = _viewport.rect; button.sizeDelta = new Vector2(200f, ((Rect)(ref rect)).height * 0.6f); _buttonLabel = val.GetRequiredComponentInChildren<TMP_Text>(); } private void Show(OptionCollection collection) { _collection = collection; _popup.Close(); _buttonLabel.text = $"All Tabs ({collection.CategoryCount})"; ((Component)_button).gameObject.SetActive(true); _layoutPending = !TryFitPageOfTabs(); } private void Hide() { _collection = null; _layoutPending = false; _popup.Close(); ((Component)_button).gameObject.SetActive(false); _viewportLayout.ApplyTo(_viewport); _leftArrowLayout.ApplyTo(_leftArrow); foreach (GameObject categoryButton in _tabs.categoryButtons) { SetPreferredWidth(categoryButton, 200f); } } private void Remove() { Hide(); DestroyCreatedObjects(); } private void DestroyCreatedObjects() { if (Object.op_Implicit((Object)(object)_popup)) { Object.Destroy((Object)(object)((Component)_popup).gameObject); } if (Object.op_Implicit((Object)(object)_button)) { Object.Destroy((Object)(object)((Component)_button).gameObject); } Object.Destroy((Object)(object)this); } private void OnDestroy() { _livePickers.Remove(this); } private void LateUpdate() { if (_layoutPending) { _guard.Run("lay out the category tabs", delegate { _layoutPending = !TryFitPageOfTabs(); }); } } private bool TryFitPageOfTabs() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Expected O, but got Unknown //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00da: 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_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_014e: 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) Rect rect = _scrollView.rect; float width = ((Rect)(ref rect)).width; if (width < 1f || _tabs.categoryButtons.Count == 0) { return false; } RectTransform val = (RectTransform)_tabs.categoryTransform; HorizontalLayoutGroup component = ((Component)val).GetComponent<HorizontalLayoutGroup>(); float num = (Object.op_Implicit((Object)(object)component) ? (3f * ((HorizontalOrVerticalLayoutGroup)component).spacing + (float)((LayoutGroup)component).padding.horizontal) : 0f); float num2 = width - 100f - 104f - num; float num3 = Mathf.Min(200f, num2 / 5f); float num4 = 12f + num3 + 12f; float num5 = num4 + 64f + 12f; PlaceLeftArrowAt(num4); _viewport.anchorMin = new Vector2(0f, _viewport.anchorMin.y); _viewport.anchorMax = new Vector2(0f, _viewport.anchorMax.y); _viewport.offsetMin = new Vector2(num5, _viewport.offsetMin.y); _viewport.offsetMax = new Vector2(num5 + 4f * num3 + num, _viewport.offsetMax.y); foreach (GameObject categoryButton in _tabs.categoryButtons) { SetPreferredWidth(categoryButton, num3); } LayoutRebuilder.ForceRebuildLayoutImmediate(val); _tabs.SetPage(_tabs._currentPage, true); _button.sizeDelta = new Vector2(num3, TabHeight()); return true; } private void PlaceLeftArrowAt(float left) { //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_0036: 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_0057: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) _leftArrow.anchorMin = new Vector2(0f, _leftArrow.anchorMin.y); _leftArrow.anchorMax = new Vector2(0f, _leftArrow.anchorMax.y); _leftArrow.anchoredPosition = new Vector2(left + _leftArrow.pivot.x * 64f, _leftArrow.anchoredPosition.y); } private float TabHeight() { //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_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) Rect rect = ((RectTransform)_tabs.categoryButtons[0].transform).rect; float height = ((Rect)(ref rect)).height; if (!(height >= 1f)) { rect = _viewport.rect; return ((Rect)(ref rect)).height * 0.6f; } return height; } private static void SetPreferredWidth(GameObject tab, float width) { if (Object.op_Implicit((Object)(object)tab)) { LayoutElement component = tab.GetComponent<LayoutElement>(); if (Object.op_Implicit((Object)(object)component)) { component.preferredWidth = width; } } } private void OnDisable() { if (Object.op_Implicit((Object)(object)_popup)) { _popup.Close(); } } private void TogglePopup() { if (_popup.IsOpen) { _popup.Close(); } else if (_collection != null) { _guard.Run("open the All Tabs picker", delegate { _popup.Open(PickerChoices.For(_collection), Mathf.Max(0, _tabNavigation.currentHeaderIndex)); }); } } private void SelectCategory(int categoryIndex) { _popup.Close(); if (categoryIndex < _tabs.categoryButtons.Count) { _guard.Run("switch tabs from the All Tabs picker", delegate { SwitchTo(categoryIndex); }); } } private void SwitchTo(int categoryIndex) { ((UnityEvent)((Button)_tabs.categoryButtons[categoryIndex].GetRequiredComponentInChildren<HGButton>()).onClick).Invoke(); _tabs.SetPage(categoryIndex / 4, false); } } internal sealed class CategoryPickerPopup : MonoBehaviour { private const float Width = 360f; private const float MaxHeight = 520f; private const float Padding = 6f; private const float Spacing = 2f; private const float ScrollbarWidth = 24f; private const float GapBelowButton = 4f; private const int SortingOrder = 30000; private readonly List<PickerItem> _items = new List<PickerItem>(); private RectTransform _rect; private RectTransform _content; private ScrollRect _scroll; private Canvas _canvas; private PopupBlocker _blocker; private RectTransform _anchorButton; private TMP_Text _styleSource; private Action<int> _onSelected; public bool IsOpen => ((Component)this).gameObject.activeSelf; public static CategoryPickerPopup Create(Transform parent, RectTransform anchorButton, TMP_Text styleSource, Transform panelScrollView, Action<int> onSelected) { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) PanelBackground background = PanelBackground.Of(panelScrollView); GameObject gameObject = ((Component)panelScrollView.FindRequired("Scrollbar Vertical")).gameObject; GameObject val = new GameObject("Category Picker Popup", new Type[1] { typeof(RectTransform) }); val.SetActive(false); val.layer = ((Component)parent).gameObject.layer; val.transform.SetParent(parent, false); CategoryPickerPopup categoryPickerPopup = val.AddComponent<CategoryPickerPopup>(); categoryPickerPopup._anchorButton = anchorButton; categoryPickerPopup._styleSource = styleSource; categoryPickerPopup._onSelected = onSelected; categoryPickerPopup.Build(background, gameObject); return categoryPickerPopup; } public void Open(IReadOnlyList<PickerChoice> choices, int currentCategory) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) RebuildItems(choices); ((Component)this).gameObject.SetActive(true); DrawAboveSiblingCanvases(); _rect.sizeDelta = new Vector2(360f, Mathf.Min(ContentHeight(choices), 520f)); PlaceBelowButton(); MarkCurrent(currentCategory); ScrollToCurrent(choices, currentCategory); } public void Close() { ((Component)this).gameObject.SetActive(false); } public void MarkCurrent(int categoryIndex) { foreach (PickerItem item in _items) { item.SetCurrent(item.CategoryIndex == categoryIndex); } } private void DrawAboveSiblingCanvases() { _canvas.overrideSorting = true; _canvas.sortingOrder = 30000; _blocker.DrawBelow(30000); } private void Build(PanelBackground background, GameObject scrollbarTemplate) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown //IL_0021: 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_0062: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Expected O, but got Unknown //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Expected O, but got Unknown //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Expected O, but got Unknown //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_01ad: Unknown result type (might be due to invalid IL or missing references) //IL_01bd: Unknown result type (might be due to invalid IL or missing references) _rect = (RectTransform)((Component)this).transform; _rect.AnchorAt(new Vector2(0.5f, 0.5f), new Vector2(0f, 1f)); _canvas = ((Component)this).gameObject.AddComponent<Canvas>(); ((Component)this).gameObject.AddComponent<GraphicRaycaster>(); ((Graphic)((Component)this).gameObject.AddComponent<Image>()).color = Color.clear; background.CopyInto(_rect); _blocker = PopupBlocker.Create((Transform)(object)_rect, Close); RectTransform val = (RectTransform)new GameObject("Viewport", new Type[2] { typeof(RectTransform), typeof(RectMask2D) }) { layer = ((Component)this).gameObject.layer }.transform; ((Transform)val).SetParent((Transform)(object)_rect, false); val.Stretch(new Vector2(6f, 6f), new Vector2(30f, 6f)); GameObject val2 = new GameObject("Content", new Type[3] { typeof(RectTransform), typeof(VerticalLayoutGroup), typeof(ContentSizeFitter) }); val2.layer = ((Component)this).gameObject.layer; _content = (RectTransform)val2.transform; ((Transform)_content).SetParent((Transform)(object)val, false); _content.anchorMin = new Vector2(0f, 1f); _content.anchorMax = Vector2.one; _content.pivot = new Vector2(0.5f, 1f); _content.sizeDelta = Vector2.zero; VerticalLayoutGroup component = val2.GetComponent<VerticalLayoutGroup>(); ((HorizontalOrVerticalLayoutGroup)component).spacing = 2f; ((HorizontalOrVerticalLayoutGroup)component).childControlWidth = true; ((HorizontalOrVerticalLayoutGroup)component).childControlHeight = true; ((HorizontalOrVerticalLayoutGroup)component).childForceExpandWidth = true; ((HorizontalOrVerticalLayoutGroup)component).childForceExpandHeight = false; val2.GetComponent<ContentSizeFitter>().verticalFit = (FitMode)2; _scroll = ((Component)this).gameObject.AddComponent<ScrollRect>(); _scroll.viewport = val; _scroll.content = _content; _scroll.horizontal = false; _scroll.movementType = (MovementType)2; _scroll.inertia = false; _scroll.scrollSensitivity = 40f; AddScrollbar(scrollbarTemplate); } private void AddScrollbar(GameObject scrollbarTemplate) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_002e: 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_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_004e: 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_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) GameObject val = Object.Instantiate<GameObject>(scrollbarTemplate, (Transform)(object)_rect); ((Object)val).name = "Scrollbar"; RectTransform val2 = (RectTransform)val.transform; val2.anchorMin = new Vector2(1f, 0f); val2.anchorMax = Vector2.one; val2.pivot = new Vector2(1f, 0.5f); val2.offsetMin = new Vector2(-27f, 6f); val2.offsetMax = new Vector2(-3f, -6f); _scroll.verticalScrollbar = val.GetComponent<Scrollbar>(); _scroll.verticalScrollbarVisibility = (ScrollbarVisibility)1; } private void RebuildItems(IReadOnlyList<PickerChoice> choices) { _items.Clear(); for (int num = ((Transform)_content).childCount - 1; num >= 0; num--) { Object.DestroyImmediate((Object)(object)((Component)((Transform)_content).GetChild(num)).gameObject); } foreach (PickerChoice choice in choices) { if (choice.IsHeader) { PickerItem.CreateHeader((Transform)(object)_content, _styleSource, choice.Text); } else { _items.Add(PickerItem.CreateCategory((Transform)(object)_content, _styleSource, choice.Text, choice.CategoryIndex, _onSelected)); } } } private void PlaceBelowButton() { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_002c: 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) ((Transform)_rect).position = _anchorButton.WorldBottomLeft(); RectTransform rect = _rect; rect.anchoredPosition -= new Vector2(0f, 4f); } private void ScrollToCurrent(IReadOnlyList<PickerChoice> choices, int currentCategory) { //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) float num = 0f; foreach (PickerChoice choice in choices) { if (!choice.IsHeader && choice.CategoryIndex == currentCategory) { break; } num += PickerItem.HeightOf(choice) + 2f; } Canvas.ForceUpdateCanvases(); Rect rect = _content.rect; float height = ((Rect)(ref rect)).height; rect = _scroll.viewport.rect; float num2 = height - ((Rect)(ref rect)).height; _scroll.verticalNormalizedPosition = ((num2 <= 0f) ? 1f : (1f - Mathf.Clamp01(num / num2))); } private static float ContentHeight(IReadOnlyList<PickerChoice> choices) { float num = 12f + 2f * (float)Math.Max(0, choices.Count - 1); foreach (PickerChoice choice in choices) { num += PickerItem.HeightOf(choice); } return num; } private void Update() { if (Input.GetKeyDown((KeyCode)27)) { Close(); } } } internal readonly struct PickerChoice { public string Text { get; } public int CategoryIndex { get; } public bool IsHeader { get; } private PickerChoice(string text, int categoryIndex, bool isHeader) { Text = text; CategoryIndex = categoryIndex; IsHeader = isHeader; } public static PickerChoice Header(string text) { return new PickerChoice(text, -1, isHeader: true); } public static PickerChoice Category(string text, int categoryIndex) { return new PickerChoice(text, categoryIndex, isHeader: false); } } internal static class PickerChoices { public static List<PickerChoice> For(OptionCollection collection) { List<string> list = (from index in Enumerable.Range(0, collection.CategoryCount) select CategoryGroups.FileLabelOf(collection.ModGuid, collection[index].name) ?? collection.ModName).ToList(); bool flag = list.Distinct().Count() > 1; List<PickerChoice> list2 = new List<PickerChoice>(); string text = null; for (int num = 0; num < collection.CategoryCount; num++) { if (flag && list[num] != text) { text = list[num]; list2.Add(PickerChoice.Header(text)); } list2.Add(PickerChoice.Category(Language.GetString(collection[num].NameToken), num)); } return list2; } } internal sealed class PickerItem : PointerTarget { private const float CategoryHeight = 40f; private const float HeaderHeight = 32f; private const float CategoryFontSize = 22f; private const float HeaderFontSize = 18f; private const float CategoryIndent = 24f; private const float HeaderIndent = 10f; private static readonly Color IdleColor = new Color(1f, 1f, 1f, 0f); private static readonly Color HoveredColor = new Color(1f, 1f, 1f, 0.1f); private static readonly Color CurrentColor = new Color(1f, 1f, 1f, 0.2f); private static readonly Color HeaderTextColor = new Color(0.6f, 0.6f, 0.6f, 1f); private Image _background; private Action<int> _onSelected; private bool _current; public int CategoryIndex { get; private set; } public static float HeightOf(PickerChoice choice) { if (!choice.IsHeader) { return 40f; } return 32f; } public static void CreateHeader(Transform parent, TMP_Text styleSource, string text) { //IL_0022: 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) GameObject val = CreateRow("Group Header", parent, 32f); HGTextMeshProUGUI obj = UiText.Create("Text", val.transform, styleSource, 18f, HeaderTextColor); ((TMP_Text)obj).rectTransform.offsetMin = new Vector2(10f, 0f); ((TMP_Text)obj).text = text; } public static PickerItem CreateCategory(Transform parent, TMP_Text styleSource, string text, int categoryIndex, Action<int> onSelected) { //IL_0022: 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) GameObject val = CreateRow("Category", parent, 40f); HGTextMeshProUGUI obj = UiText.Create("Text", val.transform, styleSource, 22f, Color.white); ((TMP_Text)obj).rectTransform.offsetMin = new Vector2(24f, 0f); ((TMP_Text)obj).overflowMode = (TextOverflowModes)1; ((TMP_Text)obj).text = text; PickerItem pickerItem = val.AddComponent<PickerItem>(); pickerItem._background = val.GetComponent<Image>(); pickerItem._onSelected = onSelected; pickerItem.CategoryIndex = categoryIndex; pickerItem.Refresh(); return pickerItem; } public void SetCurrent(bool current) { _current = current; Refresh(); } protected override void OnLeftClick() { _onSelected(CategoryIndex); } protected override void Refresh() { //IL_000e: 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_0027: Unknown result type (might be due to invalid IL or missing references) if (_current) { ((Graphic)_background).color = CurrentColor; } else { ((Graphic)_background).color = (base.IsHovered ? HoveredColor : IdleColor); } } private static GameObject CreateRow(string name, Transform parent, float height) { //IL_003b: 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_0051: 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_0064: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Expected O, but got Unknown GameObject val = new GameObject(name, new Type[4] { typeof(RectTransform), typeof(CanvasRenderer), typeof(Image), typeof(LayoutElement) }) { layer = ((Component)parent).gameObject.layer }; val.transform.SetParent(parent, false); ((Graphic)val.GetComponent<Image>()).color = IdleColor; LayoutElement component = val.GetComponent<LayoutElement>(); component.minHeight = height; component.preferredHeight = height; return val; } } internal sealed class PopupBlocker : MonoBehaviour, IPointerDownHandler, IEventSystemHandler, IPointerClickHandler { private const float CoverSize = 20000f; private Canvas _canvas; private Action _onPressed; public static PopupBlocker Create(Transform popup, Action onPressed) { //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Expected O, but got Unknown //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Expected O, but got Unknown //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("Click Blocker", new Type[5] { typeof(RectTransform), typeof(Canvas), typeof(GraphicRaycaster), typeof(CanvasRenderer), typeof(Image) }); val.layer = ((Component)popup).gameObject.layer; RectTransform val2 = (RectTransform)val.transform; ((Transform)val2).SetParent(popup, false); ((Transform)val2).SetAsFirstSibling(); RectTransformExtensions.AnchorAt(val2, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f)); val2.sizeDelta = new Vector2(20000f, 20000f); ((Graphic)val.GetComponent<Image>()).color = Color.clear; PopupBlocker popupBlocker = val.AddComponent<PopupBlocker>(); popupBlocker._canvas = val.GetComponent<Canvas>(); popupBlocker._onPressed = onPressed; return popupBlocker; } public void DrawBelow(int popupSortingOrder) { _canvas.overrideSorting = true; _canvas.sortingOrder = popupSortingOrder - 1; } public void OnPointerDown(PointerEventData eventData) { _onPressed(); } public void OnPointerClick(PointerEventData eventData) { } } } namespace RiskOfOptionsExtender.Settings { internal sealed class ExtenderSettings { public const string FillInSection = "Fill In Missing Options"; private const string ModListSection = "Mod List"; private const string VisualTweaksSection = "Visual Tweaks"; public ConfigEntry<ModSortOrder> SortOrder { get; } public ConfigEntry<bool> HideEmptyMods { get; } public GuidListSetting PinnedMods { get; } public ConfigEntry<bool> ModListTweaks { get; } public ConfigEntry<bool> OptionPageTweaks { get; } public ConfigEntry<bool> NeverFillIn { get; } public GuidListSetting SkippedMods { get; } public ExtenderSettings(ConfigFile config) { SortOrder = config.Bind<ModSortOrder>("Mod List", "Sort Order", ModSortOrder.Alphabetical, "Order of the mod list. Pinned mods always come first."); HideEmptyMods = config.Bind<bool>("Mod List", "Hide Empty Mods", true, "Hide mods that have no options to show."); PinnedMods = new GuidListSetting(config.Bind<string>("Mod List", "Pinned Mods", "", "GUIDs of pinned mods, separated by commas. Pin mods with the star on their row in the mod list.")); ModListTweaks = config.Bind<bool>("Visual Tweaks", "Mod List Tweaks", true, "Search box, A-Z / Z-A sorting and pinning in the mod list. When off, this mod leaves Risk Of Options' mod list alone."); OptionPageTweaks = config.Bind<bool>("Visual Tweaks", "Option Page Tweaks", true, "Restart markers, full setting names, aligned checkboxes and the All Tabs picker on mod option pages. When off, this mod leaves Risk Of Options' option pages alone."); NeverFillIn = config.Bind<bool>("Fill In Missing Options", "Never Fill In Missing Options", false, "Don't add the options mods leave out of this menu, for any mod."); SkippedMods = new GuidListSetting(config.Bind<string>("Fill In Missing Options", "Skipped Mods", "", "GUIDs of mods whose missing options are not added, separated by commas. Set with the \"Skip\" checkboxes in this mod's page.")); RemoveUnboundEntries(config); } public bool ShouldFillIn(PluginInfo plugin) { if (!NeverFillIn.Value) { return !SkippedMods.Contains(plugin.Metadata.GUID); } return false; } public void AddToMenu() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected O, but got Unknown //IL_0022: Expected O, but got Unknown //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Expected O, but got Unknown //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Expected O, but got Unknown //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Expected O, but got Unknown //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Expected O, but got Unknown //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Expected O, but got Unknown //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Expected O, but got Unknown AddOwnOption((BaseOption)new ChoiceOption((ConfigEntryBase)(object)SortOrder, new ChoiceConfig { checkIfDisabled = (IsDisabledDelegate)(() => !ModListTweaks.Value) })); AddOwnOption((BaseOption)new CheckBoxOption(HideEmptyMods)); AddOwnOption((BaseOption)new CheckBoxOption(ModListTweaks)); AddOwnOption((BaseOption)new CheckBoxOption(OptionPageTweaks)); AddOwnOption((BaseOption)new CheckBoxOption(NeverFillIn, new CheckBoxConfig { restartRequired = true })); } public static void AddOwnOption(BaseOption option) { ModSettingsManager.AddOption(option, "com.Delfofthebla.RiskOfOptionsExtender", "RiskOfOptionsExtender"); } private static void RemoveUnboundEntries(ConfigFile config) { if (typeof(ConfigFile).GetProperty("OrphanedEntries", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(config) is Dictionary<ConfigDefinition, string> { Count: not 0 } dictionary) { dictionary.Clear(); config.Save(); } } } internal sealed class GuidListSetting { private readonly ConfigEntry<string> _entry; private HashSet<string> _guids; public event Action Changed; public GuidListSetting(ConfigEntry<string> entry) { _entry = entry; _guids = Parse(entry.Value); entry.SettingChanged += OnEntryChanged; } public bool Contains(string guid) { return _guids.Contains(guid); } public void Set(string guid, bool included) { if (included) { _guids.Add(guid); } else { _guids.Remove(guid); } Save(); } public void Toggle(string guid) { Set(guid, !Contains(guid)); } private void Save() { _entry.Value = string.Join(",", _guids.OrderBy<string, string>((string guid) => guid, StringComparer.Ordinal)); } private void OnEntryChanged(object sender, EventArgs args) { _guids = Parse(_entry.Value); this.Changed?.Invoke(); } private static HashSet<string> Parse(string commaSeparated) { HashSet<string> hashSet = new HashSet<string>(); foreach (string item in from guid in commaSeparated.Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries) select guid.Trim()) { hashSet.Add(item); } return hashSet; } } internal enum ModSortOrder { Alphabetical, ReverseAlphabetical } internal sealed class SkipToggles(ExtenderSettings settings) { private const string Section = "Skip"; private readonly HashSet<string> _guidsWithToggle = new HashSet<string>(); private ConfigFile _file; private int _nextKey; public void AddFor(IEnumerable<PluginInfo> plugins) { foreach (PluginInfo item in plugins.Where((PluginInfo plugin) => !_guidsWithToggle.Contains(plugin.Metadata.GUID)).OrderBy<PluginInfo, string>((PluginInfo plugin) => plugin.Metadata.Name, StringComparer.CurrentCultureIgnoreCase)) { Add(item); } } private void Add(PluginInfo plugin) { //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Expected O, but got Unknown //IL_012a: Expected O, but got Unknown //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Expected O, but got Unknown string guid = plugin.Metadata.GUID; string name = plugin.Metadata.Name; if (_file == null) { _file = UnsavedConfigFiles.Create("SkipToggles"); } string text = _nextKey++.ToString(CultureInfo.InvariantCulture); ConfigEntry<bool> toggle = _file.Bind<bool>("Skip", text, false, "Don't add the options \"" + name + "\" leaves out of this menu."); toggle.Value = settings.SkippedMods.Contains(guid); toggle.SettingChanged += delegate { settings.SkippedMods.Set(guid, toggle.Value); }; settings.SkippedMods.Changed += delegate { toggle.Value = settings.SkippedMods.Contains(guid); }; _guidsWithToggle.Add(guid); CheckBoxConfig val = new CheckBoxConfig { name = "Skip " + name, category = "Fill In Missing Options", restartRequired = true, checkIfDisabled = (IsDisabledDelegate)(() => settings.NeverFillIn.Value) }; ExtenderSettings.AddOwnOption((BaseOption)new CheckBoxOption(toggle, val)); } } } namespace RiskOfOptionsExtender.Resilience { internal sealed class FeatureGuard(string featureName, Action onTripped = null) { private bool _tripped; public v
patchers/RiskOfOptionsExtender.Patcher.dll
Decompiled 17 hours agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using Microsoft.CodeAnalysis; using Mono.Cecil; using MonoMod.RuntimeDetour; using RiskOfOptionsExtender.Discovery; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyVersion("0.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace RiskOfOptionsExtender.Discovery { internal static class ConfigFileWatch { private static readonly List<(ConfigFile File, string OwnerGuid, Assembly CreatingAssembly)> _origins = new List<(ConfigFile, string, Assembly)>(); private static readonly object _lock = new object(); private static Hook _constructorHook; private static ManualLogSource _log; public static bool IsInstalled => _constructorHook != null; public static IReadOnlyList<(ConfigFile File, string OwnerGuid, Assembly CreatingAssembly)> Origins { get { lock (_lock) { return _origins.ToArray(); } } } public static void Install() { //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Expected O, but got Unknown _constructorHook = new Hook((MethodBase)(typeof(ConfigFile).GetConstructor(new Type[3] { typeof(string), typeof(bool), typeof(BepInPlugin) }) ?? throw new MissingMethodException("BepInEx's ConfigFile(string, bool, BepInPlugin) constructor no longer exists.")), (Delegate)new Action<Action<ConfigFile, string, bool, BepInPlugin>, ConfigFile, string, bool, BepInPlugin>(RecordOrigin)); } private static void RecordOrigin(Action<ConfigFile, string, bool, BepInPlugin> orig, ConfigFile self, string configPath, bool saveOnInit, BepInPlugin ownerMetadata) { orig(self, configPath, saveOnInit, ownerMetadata); try { (ConfigFile, string, Assembly) item = (self, (ownerMetadata != null) ? ownerMetadata.GUID : null, FindCreatingAssembly()); lock (_lock) { _origins.Add(item); } } catch (Exception arg) { if (_log == null) { _log = Logger.CreateLogSource("ConfigFileWatch"); } _log.LogDebug((object)$"Could not record who created {configPath}: {arg}"); } } private static Assembly FindCreatingAssembly() { StackFrame[] array = new StackTrace(2, fNeedFileInfo: false).GetFrames() ?? Array.Empty<StackFrame>(); for (int i = 0; i < array.Length; i++) { Assembly assembly = array[i].GetMethod()?.DeclaringType?.Assembly; if (assembly != null && !IsInfrastructure(assembly)) { return assembly; } } return null; } private static bool IsInfrastructure(Assembly assembly) { if (assembly == typeof(ConfigFile).Assembly || assembly == typeof(object).Assembly || assembly == typeof(ConfigFileWatch).Assembly) { return true; } string name = assembly.GetName().Name; if (!name.StartsWith("MonoMod", StringComparison.Ordinal)) { return name.StartsWith("0Harmony", StringComparison.Ordinal); } return true; } } } namespace RiskOfOptionsExtender.Patcher { public static class RiskOfOptionsExtenderPatcher { public static IEnumerable<string> TargetDLLs { get; } = Array.Empty<string>(); public static bool IsWatching => ConfigFileWatch.IsInstalled; public static IReadOnlyList<(ConfigFile File, string OwnerGuid, Assembly CreatingAssembly)> ConfigFileOrigins => ConfigFileWatch.Origins; public static void Initialize() { ConfigFileWatch.Install(); } public static void Patch(AssemblyDefinition assembly) { } } }