diff --git a/BSIPA-ModList/UI/ViewControllers/MarkdownView.cs b/BSIPA-ModList/UI/ViewControllers/MarkdownView.cs index 60ff1ce8..08d8adc2 100644 --- a/BSIPA-ModList/UI/ViewControllers/MarkdownView.cs +++ b/BSIPA-ModList/UI/ViewControllers/MarkdownView.cs @@ -250,10 +250,10 @@ namespace BSIPA_ModList.UI.ViewControllers } scrView = gameObject.AddComponent(); - scrView.SetPrivateField("_pageUpButton", pageUp); - scrView.SetPrivateField("_pageDownButton", pageDown); - scrView.SetPrivateField("_contentRectTransform", content); - scrView.SetPrivateField("_viewport", viewport); + scrView.SetField("_pageUpButton", pageUp); + scrView.SetField("_pageDownButton", pageDown); + scrView.SetField("_contentRectTransform", content); + scrView.SetField("_viewport", viewport); gameObject.SetActive(true); } diff --git a/BSIPA-ModList/UI/ViewControllers/ModInfoViewController.cs b/BSIPA-ModList/UI/ViewControllers/ModInfoViewController.cs index 1127022f..0bcbbe12 100644 --- a/BSIPA-ModList/UI/ViewControllers/ModInfoViewController.cs +++ b/BSIPA-ModList/UI/ViewControllers/ModInfoViewController.cs @@ -59,7 +59,7 @@ namespace BSIPA_ModList.UI flowController = mlfc; if (rowTransformOriginal == null) - rowTransformOriginal = MenuButtonUI.Instance.GetPrivateField("menuButtonsOriginal"); + rowTransformOriginal = MenuButtonUI.Instance.GetField("menuButtonsOriginal"); // i also have no clue why this is necessary rectTransform.anchorMin = new Vector2(0f, 0f); diff --git a/BSIPA-ModList/UI/WarningUI.cs b/BSIPA-ModList/UI/WarningUI.cs index 77457776..75a549e0 100644 --- a/BSIPA-ModList/UI/WarningUI.cs +++ b/BSIPA-ModList/UI/WarningUI.cs @@ -81,7 +81,7 @@ namespace BSIPA_ModList.UI if (_mainFlow == null) { _mainFlow = FindObjectOfType(); - _warningDialog = _mainFlow.GetPrivateField("_simpleDialogPromptViewController"); + _warningDialog = _mainFlow.GetField("_simpleDialogPromptViewController"); } _warningsQueue.Clear(); @@ -147,12 +147,12 @@ namespace BSIPA_ModList.UI (warning.IgnoredDependencies.Length > 0 ? $"\nIgnored:\n{string.Join("\n", warning.IgnoredDependencies)}" : "") + (warning.DisabledDependencies.Length > 0 ? $"\nDisabled:\n{string.Join("\n", warning.DisabledDependencies)}" : "") , "Okay", WarningDialogDidFinish); - _mainFlow.InvokePrivateMethod("PresentViewController", _warningDialog, null, true); + _mainFlow.InvokeMethod("PresentViewController", _warningDialog, null, true); } private static void WarningDialogDidFinish(int button) { - _mainFlow.InvokePrivateMethod("DismissViewController", _warningDialog, null, (_warningsQueue.Count > 0)); + _mainFlow.InvokeMethod("DismissViewController", _warningDialog, null, (_warningsQueue.Count > 0)); if (_warningsQueue.Count > 0) { diff --git a/IPA.Loader/Utilities/ReflectionUtil.cs b/IPA.Loader/Utilities/ReflectionUtil.cs index 922be878..451437bf 100644 --- a/IPA.Loader/Utilities/ReflectionUtil.cs +++ b/IPA.Loader/Utilities/ReflectionUtil.cs @@ -10,25 +10,38 @@ namespace IPA.Utilities public static class ReflectionUtil { /// - /// Sets a (potentially) private field on the target object. + /// Sets a field on the target object. /// /// the object instance /// the field to set /// the value to set it to - public static void SetPrivateField(this object obj, string fieldName, object value) + public static void SetField(this object obj, string fieldName, object value) { var prop = obj.GetType().GetField(fieldName, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance); prop?.SetValue(obj, value); } + + /// + /// Sets a field on the target object, as gotten from . + /// + /// the type to get the field from + /// the object instance + /// the field to set + /// the value to set it to + public static void SetField(this T obj, string fieldName, object value) where T : class + { + var prop = typeof(T).GetField(fieldName, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance); + prop?.SetValue(obj, value); + } /// - /// Gets the value of a (potentially) private field. + /// Gets the value of a field. /// - /// the type of te field (result casted) + /// the type of the field (result casted) /// the object instance to pull from /// the name of the field to read /// the value of the field - public static T GetPrivateField(this object obj, string fieldName) + public static T GetField(this object obj, string fieldName) { var prop = obj.GetType().GetField(fieldName, BindingFlags.NonPublic | BindingFlags.Instance); var value = prop?.GetValue(obj); @@ -36,42 +49,82 @@ namespace IPA.Utilities } /// - /// Sets a (potentially) private property on the target object. + /// Sets a property on the target object. /// /// the target object instance /// the name of the property /// the value to set it to - public static void SetPrivateProperty(this object obj, string propertyName, object value) + public static void SetProperty(this object obj, string propertyName, object value) { - var prop = obj.GetType() - .GetProperty(propertyName, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance); + var prop = obj.GetType().GetProperty(propertyName, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance); prop?.SetValue(obj, value, null); } /// - /// Invokes a (potentially) private method. + /// Sets a property on the target object, as gotten from + /// + /// the type to get the property from + /// the object instance + /// the property to set + /// the value to set it to + public static void SetProperty(this T obj, string propertyName, object value) where T : class + { + var prop = typeof(T).GetProperty(propertyName, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance); + prop?.SetValue(obj, value); + } + + /// + /// Invokes a method on an object. /// /// the object to call from /// the method name - /// the method parameters + /// the method arguments /// the return value - public static object InvokePrivateMethod(this object obj, string methodName, params object[] methodParams) + public static object InvokeMethod(this object obj, string methodName, params object[] methodArgs) { MethodInfo dynMethod = obj.GetType().GetMethod(methodName, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance); - return dynMethod?.Invoke(obj, methodParams); + return dynMethod?.Invoke(obj, methodArgs); } /// - /// Invokes a (potentially) private method. + /// Invokes a method from on an object. + /// + /// the type to search for the method on + /// the object instance + /// the method's name + /// the method arguments + /// the return value + public static object InvokeMethod(this T obj, string methodName, params object[] args) where T : class + { + var dynMethod = typeof(T).GetMethod(methodName, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance); + return dynMethod?.Invoke(obj, args); + } + + /// + /// Invokes a method. /// /// the return type - /// the object to call from + /// the object instance /// the method name to call - /// the method's parameters + /// the method's arguments /// the return value - public static T InvokePrivateMethod(this object obj, string methodName, params object[] methodParams) + public static T InvokeMethod(this object obj, string methodName, params object[] methodArgs) { - return (T)InvokePrivateMethod(obj, methodName, methodParams); + return (T)InvokeMethod(obj, methodName, methodArgs); + } + + /// + /// Invokes a method from on an object. + /// + /// the return type + /// the type to search for the method on + /// the object instance + /// the method name to call + /// the method's arguments + /// the return value + public static T InvokeMethod(this U obj, string methodName, params object[] methodArgs) where U : class + { + return (T)obj.InvokeMethod(methodName, methodArgs); } /// @@ -124,71 +177,12 @@ namespace IPA.Utilities private static void CopyForType(Type type, Component source, Component destination) { - FieldInfo[] myObjectFields = type.GetFields(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.GetField); + FieldInfo[] myObjectFields = type.GetFields(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance); foreach (FieldInfo fi in myObjectFields) { fi.SetValue(destination, fi.GetValue(source)); } } - - /// - /// Calls an instance method on a type specified by and . - /// - /// - /// the type name - /// the assembly the type is in - /// the name of the method to call - /// the type signature of the method - /// the method parameters - /// the result of the call - public static object CallNonStaticMethod(string functionClass, string dependency, string function, Type[] methodSig, params object[] parameters) - { - return CallNonStaticMethod(Type.GetType(string.Format("{0},{1}", functionClass, dependency)), function, methodSig, parameters); - } - - /// - /// Calls an instance method on a new object. - /// - /// the object type - /// the name of the method to call - /// the type signature - /// the parameters - /// the result of the call - public static object CallNonStaticMethod(this Type type, /*string functionClass, string dependency,*/ string function, Type[] methodSig, params object[] parameters) - { - //Type FunctionClass = Type.GetType(string.Format("{0},{1}", functionClass, dependency)); - if (type != null) - { - object instance = Activator.CreateInstance(type); - { - Type instType = instance.GetType(); - MethodInfo methodInfo = instType.GetMethod(function, methodSig); - if (methodInfo != null) - { - return methodInfo.Invoke(instance, parameters); - } - - throw new Exception("Method not found"); - } - } - - throw new ArgumentNullException(nameof(type)); - } - - /// - /// Calls an instance method on a new object. - /// - /// - /// the return type - /// the object type - /// the name of the method to call - /// the type signature - /// the parameters - /// the result of the call - public static T CallNonStaticMethod(this Type type, string function, Type[] methodSig, params object[] parameters) - { - return (T)CallNonStaticMethod(type, function, methodSig, parameters); - } } }