Add configurable reflection signature blacklist, extends to MCS as well

This commit is contained in:
Sinai
2021-05-13 23:02:46 +10:00
parent 843d7ed451
commit ccd08c3a63
6 changed files with 241 additions and 75 deletions

View File

@ -18,20 +18,23 @@ namespace UnityExplorer.Core.Config
public static ConfigElement<KeyCode> Main_Menu_Toggle; public static ConfigElement<KeyCode> Main_Menu_Toggle;
public static ConfigElement<bool> Force_Unlock_Mouse; public static ConfigElement<bool> Force_Unlock_Mouse;
public static ConfigElement<KeyCode> Force_Unlock_Keybind; public static ConfigElement<KeyCode> Force_Unlock_Toggle;
public static ConfigElement<bool> Aggressive_Force_Unlock; public static ConfigElement<bool> Aggressive_Mouse_Unlock;
public static ConfigElement<int> Default_Page_Limit;
public static ConfigElement<string> Default_Output_Path; public static ConfigElement<string> Default_Output_Path;
public static ConfigElement<bool> Log_Unity_Debug; public static ConfigElement<bool> Log_Unity_Debug;
public static ConfigElement<bool> Hide_On_Startup; public static ConfigElement<bool> Hide_On_Startup;
public static ConfigElement<float> Startup_Delay_Time; public static ConfigElement<float> Startup_Delay_Time;
public static ConfigElement<string> Reflection_Signature_Blacklist;
// internal configs // internal configs
internal static InternalConfigHandler InternalHandler { get; private set; } internal static InternalConfigHandler InternalHandler { get; private set; }
public static ConfigElement<string> ObjectExplorerData; public static ConfigElement<string> ObjectExplorerData;
public static ConfigElement<string> InspectorData; public static ConfigElement<string> InspectorData;
public static ConfigElement<string> CSConsoleData; public static ConfigElement<string> CSConsoleData;
public static ConfigElement<string> OptionsPanelData;
public static ConfigElement<string> ConsoleLogData;
internal static readonly Dictionary<string, IConfigElement> ConfigElements = new Dictionary<string, IConfigElement>(); internal static readonly Dictionary<string, IConfigElement> ConfigElements = new Dictionary<string, IConfigElement>();
internal static readonly Dictionary<string, IConfigElement> InternalConfigs = new Dictionary<string, IConfigElement>(); internal static readonly Dictionary<string, IConfigElement> InternalConfigs = new Dictionary<string, IConfigElement>();
@ -80,11 +83,11 @@ namespace UnityExplorer.Core.Config
"Force the Cursor to be unlocked (visible) when the UnityExplorer menu is open.", "Force the Cursor to be unlocked (visible) when the UnityExplorer menu is open.",
true); true);
Force_Unlock_Keybind = new ConfigElement<KeyCode>("Force Unlock Keybind", Force_Unlock_Toggle = new ConfigElement<KeyCode>("Force Unlock Toggle Key",
"The keybind to toggle the 'Force Unlock Mouse' setting. Only usable when UnityExplorer is open.", "The keybind to toggle the 'Force Unlock Mouse' setting. Only usable when UnityExplorer is open.",
KeyCode.None); KeyCode.None);
Aggressive_Force_Unlock = new ConfigElement<bool>("Aggressive Mouse Unlock", Aggressive_Mouse_Unlock = new ConfigElement<bool>("Aggressive Mouse Unlock",
"Use WaitForEndOfFrame to aggressively force the Mouse to be unlocked (requires game restart).", "Use WaitForEndOfFrame to aggressively force the Mouse to be unlocked (requires game restart).",
false); false);
@ -92,10 +95,6 @@ namespace UnityExplorer.Core.Config
"Should UnityEngine.Debug.Log messages be printed to UnityExplorer's log?", "Should UnityEngine.Debug.Log messages be printed to UnityExplorer's log?",
false); false);
Default_Page_Limit = new ConfigElement<int>("Default Page Limit",
"The default maximum number of elements per 'page' in UnityExplorer.",
25);
Default_Output_Path = new ConfigElement<string>("Default Output Path", Default_Output_Path = new ConfigElement<string>("Default Output Path",
"The default output path when exporting things from UnityExplorer.", "The default output path when exporting things from UnityExplorer.",
Path.Combine(ExplorerCore.Loader.ExplorerFolder, "Output")); Path.Combine(ExplorerCore.Loader.ExplorerFolder, "Output"));
@ -104,11 +103,21 @@ namespace UnityExplorer.Core.Config
"The delay on startup before the UI is created.", "The delay on startup before the UI is created.",
1f); 1f);
// Internal configs Reflection_Signature_Blacklist = new ConfigElement<string>("Reflection Signature Blacklist",
"Use this to blacklist certain member signatures if they are known to cause a crash or other issues." +
"\r\nSeperate signatures with a semicolon ';'.",
"DEFAULT");
Reflection_Signature_Blacklist.OnValueChanged += ReflectionUtility.LoadBlacklistString;
ReflectionUtility.LoadBlacklistString(Reflection_Signature_Blacklist.Value);
// Internal configs (panel save data)
ObjectExplorerData = new ConfigElement<string>("ObjectExplorer", "", "", true); ObjectExplorerData = new ConfigElement<string>("ObjectExplorer", "", "", true);
InspectorData = new ConfigElement<string>("Inspector", "", "", true); InspectorData = new ConfigElement<string>("Inspector", "", "", true);
CSConsoleData = new ConfigElement<string>("CSConsole", "", "", true); CSConsoleData = new ConfigElement<string>("CSConsole", "", "", true);
OptionsPanelData = new ConfigElement<string>("OptionsPanel", "", "", true);
ConsoleLogData = new ConfigElement<string>("ConsoleLog", "", "", true);
} }
} }
} }

View File

@ -45,7 +45,7 @@ namespace UnityExplorer.Core.Input
Unlock = ConfigManager.Force_Unlock_Mouse.Value; Unlock = ConfigManager.Force_Unlock_Mouse.Value;
ConfigManager.Force_Unlock_Mouse.OnValueChanged += (bool val) => { Unlock = val; }; ConfigManager.Force_Unlock_Mouse.OnValueChanged += (bool val) => { Unlock = val; };
if (ConfigManager.Aggressive_Force_Unlock.Value) if (ConfigManager.Aggressive_Mouse_Unlock.Value)
SetupAggressiveUnlock(); SetupAggressiveUnlock();
} }

View File

@ -55,6 +55,7 @@ namespace UnityExplorer
#endregion #endregion
#region Deobfuscation cache #region Deobfuscation cache
private static readonly Dictionary<string, Type> DeobfuscatedTypes = new Dictionary<string, Type>(); private static readonly Dictionary<string, Type> DeobfuscatedTypes = new Dictionary<string, Type>();
@ -101,6 +102,7 @@ namespace UnityExplorer
#endregion #endregion
// Get type by name // Get type by name
internal override Type Internal_GetTypeByName(string fullName) internal override Type Internal_GetTypeByName(string fullName)
@ -172,6 +174,7 @@ namespace UnityExplorer
#endregion #endregion
#region Casting #region Casting
private static readonly Dictionary<string, IntPtr> cppClassPointers = new Dictionary<string, IntPtr>(); private static readonly Dictionary<string, IntPtr> cppClassPointers = new Dictionary<string, IntPtr>();
@ -183,6 +186,9 @@ namespace UnityExplorer
var type = obj.GetType(); var type = obj.GetType();
if (type == castTo)
return obj;
// from structs // from structs
if (type.IsValueType) if (type.IsValueType)
{ {
@ -251,6 +257,7 @@ namespace UnityExplorer
#endregion #endregion
#region Boxing and unboxing ValueTypes #region Boxing and unboxing ValueTypes
// cached il2cpp unbox methods // cached il2cpp unbox methods
@ -356,7 +363,8 @@ namespace UnityExplorer
#endregion #endregion
#region Strings
#region String boxing/unboxing
private const string IL2CPP_STRING_FULLNAME = "Il2CppSystem.String"; private const string IL2CPP_STRING_FULLNAME = "Il2CppSystem.String";
private const string STRING_FULLNAME = "System.String"; private const string STRING_FULLNAME = "System.String";
@ -400,6 +408,7 @@ namespace UnityExplorer
#endregion #endregion
#region Singleton finder #region Singleton finder
internal override void Internal_FindSingleton(string[] possibleNames, Type type, BF flags, List<object> instances) internal override void Internal_FindSingleton(string[] possibleNames, Type type, BF flags, List<object> instances)
@ -425,8 +434,7 @@ namespace UnityExplorer
#endregion #endregion
#region Force-loading game modules
#region FORCE LOADING GAME MODULES
// Helper for IL2CPP to try to make sure the Unhollowed game assemblies are actually loaded. // Helper for IL2CPP to try to make sure the Unhollowed game assemblies are actually loaded.
@ -471,8 +479,153 @@ namespace UnityExplorer
#region Il2cpp reflection blacklist
public override string DefaultReflectionBlacklist => string.Join(";", defaultIl2CppBlacklist);
// These methods currently cause a crash in most il2cpp games,
// even from doing "GetParameters()" on the MemberInfo.
// Blacklisting until the issue is fixed in Unhollower.
public static HashSet<string> defaultIl2CppBlacklist = new HashSet<string>
{
// These were deprecated a long time ago, still show up in some IL2CPP games for some reason
"UnityEngine.MonoBehaviour.allowPrefabModeInPlayMode",
"UnityEngine.MonoBehaviour.runInEditMode",
"UnityEngine.Component.animation",
"UnityEngine.Component.audio",
"UnityEngine.Component.camera",
"UnityEngine.Component.collider",
"UnityEngine.Component.collider2D",
"UnityEngine.Component.constantForce",
"UnityEngine.Component.hingeJoint",
"UnityEngine.Component.light",
"UnityEngine.Component.networkView",
"UnityEngine.Component.particleSystem",
"UnityEngine.Component.renderer",
"UnityEngine.Component.rigidbody",
"UnityEngine.Component.rigidbody2D",
"UnityEngine.Light.flare",
// These can cause a crash in IL2CPP
"Il2CppSystem.Type.DeclaringMethod",
"Il2CppSystem.RuntimeType.DeclaringMethod",
"Unity.Jobs.LowLevel.Unsafe.JobsUtility.CreateJobReflectionData",
"Unity.Profiling.ProfilerRecorder.CopyTo",
"Unity.Profiling.ProfilerRecorder.StartNew",
"UnityEngine.Analytics.Analytics.RegisterEvent",
"UnityEngine.Analytics.Analytics.SendEvent",
"UnityEngine.Analytics.ContinuousEvent+ConfigureEventDelegate.Invoke",
"UnityEngine.Analytics.ContinuousEvent.ConfigureEvent",
"UnityEngine.Animations.AnimationLayerMixerPlayable.Create",
"UnityEngine.Animations.AnimationLayerMixerPlayable.CreateHandle",
"UnityEngine.Animations.AnimationMixerPlayable.Create",
"UnityEngine.Animations.AnimationMixerPlayable.CreateHandle",
"UnityEngine.AssetBundle.RecompressAssetBundleAsync",
"UnityEngine.Audio.AudioMixerPlayable.Create",
"UnityEngine.BoxcastCommand.ScheduleBatch",
"UnityEngine.Camera.CalculateProjectionMatrixFromPhysicalProperties",
"UnityEngine.CapsulecastCommand.ScheduleBatch",
"UnityEngine.Collider2D.Cast",
"UnityEngine.Collider2D.Raycast",
"UnityEngine.ComputeBuffer+BeginBufferWriteDelegate.Invoke",
"UnityEngine.ComputeBuffer+EndBufferWriteDelegate.Invoke",
"UnityEngine.ComputeBuffer.BeginBufferWrite",
"UnityEngine.ComputeBuffer.EndBufferWrite",
"UnityEngine.Cubemap+SetPixelDataImplArrayDelegate.Invoke",
"UnityEngine.Cubemap+SetPixelDataImplDelegate.Invoke",
"UnityEngine.Cubemap.SetPixelDataImpl",
"UnityEngine.Cubemap.SetPixelDataImplArray",
"UnityEngine.CubemapArray+SetPixelDataImplArrayDelegate.Invoke",
"UnityEngine.CubemapArray+SetPixelDataImplDelegate.Invoke",
"UnityEngine.CubemapArray.SetPixelDataImpl",
"UnityEngine.CubemapArray.SetPixelDataImplArray",
"UnityEngine.Experimental.Playables.MaterialEffectPlayable.Create",
"UnityEngine.Experimental.Rendering.RayTracingAccelerationStructure+AddInstanceDelegate.Invoke",
"UnityEngine.Experimental.Rendering.RayTracingAccelerationStructure+AddInstance_Procedural_InjectedDelegate.Invoke",
"UnityEngine.Experimental.Rendering.RayTracingAccelerationStructure.AddInstance",
"UnityEngine.Experimental.Rendering.RayTracingAccelerationStructure.AddInstance_Procedural",
"UnityEngine.Experimental.Rendering.RayTracingAccelerationStructure.AddInstance_Procedural_Injected",
"UnityEngine.Experimental.Rendering.RayTracingShader+DispatchDelegate.Invoke",
"UnityEngine.Experimental.Rendering.RayTracingShader.Dispatch",
"UnityEngine.Experimental.Rendering.RenderPassAttachment.Clear",
"UnityEngine.GUI.DoButtonGrid",
"UnityEngine.GUI.Slider",
"UnityEngine.GUI.Toolbar",
"UnityEngine.Graphics.DrawMeshInstancedIndirect",
"UnityEngine.Graphics.DrawMeshInstancedProcedural",
"UnityEngine.Graphics.DrawProcedural",
"UnityEngine.Graphics.DrawProceduralIndirect",
"UnityEngine.Graphics.DrawProceduralIndirectNow",
"UnityEngine.Graphics.DrawProceduralNow",
"UnityEngine.LineRenderer+BakeMeshDelegate.Invoke",
"UnityEngine.LineRenderer.BakeMesh",
"UnityEngine.Mesh.GetIndices",
"UnityEngine.Mesh.GetTriangles",
"UnityEngine.Mesh.SetIndices",
"UnityEngine.Mesh.SetTriangles",
"UnityEngine.Physics2D.BoxCast",
"UnityEngine.Physics2D.CapsuleCast",
"UnityEngine.Physics2D.CircleCast",
"UnityEngine.PhysicsScene.BoxCast",
"UnityEngine.PhysicsScene.CapsuleCast",
"UnityEngine.PhysicsScene.OverlapBox",
"UnityEngine.PhysicsScene.OverlapCapsule",
"UnityEngine.PhysicsScene.SphereCast",
"UnityEngine.PhysicsScene2D.BoxCast",
"UnityEngine.PhysicsScene2D.CapsuleCast",
"UnityEngine.PhysicsScene2D.CircleCast",
"UnityEngine.PhysicsScene2D.GetRayIntersection",
"UnityEngine.PhysicsScene2D.Linecast",
"UnityEngine.PhysicsScene2D.OverlapArea",
"UnityEngine.PhysicsScene2D.OverlapBox",
"UnityEngine.PhysicsScene2D.OverlapCapsule",
"UnityEngine.PhysicsScene2D.OverlapCircle",
"UnityEngine.PhysicsScene2D.OverlapCollider",
"UnityEngine.PhysicsScene2D.OverlapPoint",
"UnityEngine.PhysicsScene2D.Raycast",
"UnityEngine.Playables.Playable.Create",
"UnityEngine.Profiling.CustomSampler.Create",
"UnityEngine.RaycastCommand.ScheduleBatch",
"UnityEngine.RemoteConfigSettings+QueueConfigDelegate.Invoke",
"UnityEngine.RemoteConfigSettings.QueueConfig",
"UnityEngine.RenderTexture.GetTemporaryImpl",
"UnityEngine.Rendering.AsyncGPUReadback.Request",
"UnityEngine.Rendering.AttachmentDescriptor.ConfigureClear",
"UnityEngine.Rendering.BatchRendererGroup+AddBatch_InjectedDelegate.Invoke",
"UnityEngine.Rendering.BatchRendererGroup.AddBatch",
"UnityEngine.Rendering.BatchRendererGroup.AddBatch_Injected",
"UnityEngine.Rendering.CommandBuffer+Internal_DispatchRaysDelegate.Invoke",
"UnityEngine.Rendering.CommandBuffer.DispatchRays",
"UnityEngine.Rendering.CommandBuffer.DrawMeshInstancedProcedural",
"UnityEngine.Rendering.CommandBuffer.Internal_DispatchRays",
"UnityEngine.Rendering.CommandBuffer.ResolveAntiAliasedSurface",
"UnityEngine.Rendering.ScriptableRenderContext.BeginRenderPass",
"UnityEngine.Rendering.ScriptableRenderContext.BeginScopedRenderPass",
"UnityEngine.Rendering.ScriptableRenderContext.BeginScopedSubPass",
"UnityEngine.Rendering.ScriptableRenderContext.BeginSubPass",
"UnityEngine.Rendering.ScriptableRenderContext.SetupCameraProperties",
"UnityEngine.Rigidbody2D.Cast",
"UnityEngine.Scripting.GarbageCollector+CollectIncrementalDelegate.Invoke",
"UnityEngine.Scripting.GarbageCollector.CollectIncremental",
"UnityEngine.SpherecastCommand.ScheduleBatch",
"UnityEngine.Texture2D+SetPixelDataImplArrayDelegate.Invoke",
"UnityEngine.Texture2D+SetPixelDataImplDelegate.Invoke",
"UnityEngine.Texture2D.SetPixelDataImpl",
"UnityEngine.Texture2D.SetPixelDataImplArray",
"UnityEngine.Texture2DArray+SetPixelDataImplArrayDelegate.Invoke",
"UnityEngine.Texture2DArray+SetPixelDataImplDelegate.Invoke",
"UnityEngine.Texture2DArray.SetPixelDataImpl",
"UnityEngine.Texture2DArray.SetPixelDataImplArray",
"UnityEngine.Texture3D+SetPixelDataImplArrayDelegate.Invoke",
"UnityEngine.Texture3D+SetPixelDataImplDelegate.Invoke",
"UnityEngine.Texture3D.SetPixelDataImpl",
"UnityEngine.Texture3D.SetPixelDataImplArray",
"UnityEngine.TrailRenderer+BakeMeshDelegate.Invoke",
"UnityEngine.TrailRenderer.BakeMesh",
"UnityEngine.WWW.LoadFromCacheOrDownload",
"UnityEngine.XR.InputDevice.SendHapticImpulse",
};
#endregion
} }
} }

View File

@ -8,15 +8,13 @@ using BF = System.Reflection.BindingFlags;
using UnityExplorer.Core.Runtime; using UnityExplorer.Core.Runtime;
using System.Text; using System.Text;
using UnityEngine; using UnityEngine;
using UnityExplorer.Core.Config;
namespace UnityExplorer namespace UnityExplorer
{ {
public class ReflectionUtility public class ReflectionUtility
{ {
// The Instance and instance methods are not for public use, they're only so IL2CPP can override.
// This class and the Extensions class expose static methods to use instead.
public const BF FLAGS = BF.Public | BF.Instance | BF.NonPublic | BF.Static; public const BF FLAGS = BF.Public | BF.Instance | BF.NonPublic | BF.Static;
internal static readonly ReflectionUtility Instance = internal static readonly ReflectionUtility Instance =
@ -37,10 +35,9 @@ namespace UnityExplorer
/// <summary>Key: Type.FullName</summary> /// <summary>Key: Type.FullName</summary>
public static readonly SortedDictionary<string, Type> AllTypes = new SortedDictionary<string, Type>(StringComparer.OrdinalIgnoreCase); public static readonly SortedDictionary<string, Type> AllTypes = new SortedDictionary<string, Type>(StringComparer.OrdinalIgnoreCase);
//private static readonly SortedSet<string> allTypeNames = new SortedSet<string>(StringComparer.OrdinalIgnoreCase);
private static string[] allTypesArray; private static string[] allTypesArray;
private static string[] GetTypeNameArray() public static string[] GetTypeNameArray()
{ {
if (allTypesArray == null || allTypesArray.Length != AllTypes.Count) if (allTypesArray == null || allTypesArray.Length != AllTypes.Count)
{ {
@ -405,5 +402,43 @@ namespace UnityExplorer
#endregion #endregion
#region Reflection Blacklist
public virtual string DefaultReflectionBlacklist => string.Empty;
public static void LoadBlacklistString(string blacklist)
{
if (string.Equals(blacklist, "DEFAULT", StringComparison.InvariantCultureIgnoreCase))
blacklist = Instance.DefaultReflectionBlacklist;
if (string.IsNullOrEmpty(blacklist))
return;
var sigs = blacklist.Split(';');
foreach (var sig in sigs)
{
var s = sig.Trim();
if (string.IsNullOrEmpty(s))
continue;
if (!currentBlacklist.Contains(s))
currentBlacklist.Add(s);
}
Mono.CSharp.IL2CPP.Blacklist.SignatureBlacklist = currentBlacklist;
}
public static bool IsBlacklisted(MemberInfo member)
{
if (string.IsNullOrEmpty(member.DeclaringType?.Namespace))
return false;
var sig = $"{member.DeclaringType.FullName}.{member.Name}";
return currentBlacklist.Contains(sig);
}
private static readonly HashSet<string> currentBlacklist = new HashSet<string>();
#endregion
} }
} }

View File

@ -18,7 +18,7 @@ namespace UnityExplorer.Loader.ML
public override void Init() public override void Init()
{ {
prefCategory = MelonPreferences.CreateCategory(CTG_NAME, $"{CTG_NAME} Settings"); prefCategory = MelonPreferences.CreateCategory(CTG_NAME, $"{CTG_NAME} Settings", false, true);
} }
public override void LoadConfig() public override void LoadConfig()
@ -36,7 +36,7 @@ namespace UnityExplorer.Loader.ML
public override void RegisterConfigElement<T>(ConfigElement<T> config) public override void RegisterConfigElement<T>(ConfigElement<T> config)
{ {
var entry = prefCategory.CreateEntry(config.Name, config.Value, null, config.IsInternal) as MelonPreferences_Entry<T>; var entry = prefCategory.CreateEntry(config.Name, config.Value, null, config.Description, config.IsInternal, false);
entry.OnValueChangedUntyped += () => entry.OnValueChangedUntyped += () =>
{ {

View File

@ -237,15 +237,15 @@ namespace UnityExplorer.UI.CacheObject
} }
private static void TryCacheMember(MemberInfo member, List<CacheMember> list, HashSet<string> cachedSigs, private static void TryCacheMember(MemberInfo member, List<CacheMember> list, HashSet<string> cachedSigs,
Type declaringType, ReflectionInspector _inspector, bool ignoreMethodBlacklist = false) Type declaringType, ReflectionInspector _inspector, bool ignorePropertyMethodInfos = true)
{ {
try try
{ {
var sig = GetSig(member); if (ReflectionUtility.IsBlacklisted(member))
if (IsBlacklisted(sig))
return; return;
var sig = GetSig(member);
//ExplorerCore.Log($"Trying to cache member {sig}..."); //ExplorerCore.Log($"Trying to cache member {sig}...");
//ExplorerCore.Log(member.DeclaringType.FullName + "." + member.Name); //ExplorerCore.Log(member.DeclaringType.FullName + "." + member.Name);
@ -256,14 +256,15 @@ namespace UnityExplorer.UI.CacheObject
case MemberTypes.Method: case MemberTypes.Method:
{ {
var mi = member as MethodInfo; var mi = member as MethodInfo;
if (!ignoreMethodBlacklist && IsBlacklisted(mi)) if (!ignorePropertyMethodInfos
&& (mi.Name.StartsWith("get_") || mi.Name.StartsWith("set_")))
return; return;
var args = mi.GetParameters(); var args = mi.GetParameters();
if (!CanParseArgs(args)) if (!CanParseArgs(args))
return; return;
sig += AppendArgsToSig(args); sig += GetArgumentString(args);
if (cachedSigs.Contains(sig)) if (cachedSigs.Contains(sig))
return; return;
@ -285,11 +286,11 @@ namespace UnityExplorer.UI.CacheObject
// write-only property, cache the set method instead. // write-only property, cache the set method instead.
var setMethod = pi.GetSetMethod(true); var setMethod = pi.GetSetMethod(true);
if (setMethod != null) if (setMethod != null)
TryCacheMember(setMethod, list, cachedSigs, declaringType, _inspector, true); TryCacheMember(setMethod, list, cachedSigs, declaringType, _inspector, false);
return; return;
} }
sig += AppendArgsToSig(args); sig += GetArgumentString(args);
if (cachedSigs.Contains(sig)) if (cachedSigs.Contains(sig))
return; return;
@ -326,54 +327,22 @@ namespace UnityExplorer.UI.CacheObject
internal static string GetSig(MemberInfo member) => $"{member.DeclaringType.Name}.{member.Name}"; internal static string GetSig(MemberInfo member) => $"{member.DeclaringType.Name}.{member.Name}";
internal static string AppendArgsToSig(ParameterInfo[] args) internal static string GetArgumentString(ParameterInfo[] args)
{ {
string ret = " ("; var sb = new StringBuilder();
sb.Append(' ');
sb.Append('(');
foreach (var param in args) foreach (var param in args)
ret += $"{param.ParameterType.Name} {param.Name}, "; {
ret += ")"; sb.Append(param.ParameterType.Name);
return ret; sb.Append(' ');
sb.Append(param.Name);
sb.Append(',');
sb.Append(' ');
}
sb.Append(')');
return sb.ToString();
} }
// Blacklists
private static readonly HashSet<string> bl_typeAndMember = new HashSet<string>
{
// these can cause a crash in IL2CPP
#if CPP
"Type.DeclaringMethod",
"Rigidbody2D.Cast",
"Collider2D.Cast",
"Collider2D.Raycast",
"Texture2D.SetPixelDataImpl",
"Camera.CalculateProjectionMatrixFromPhysicalProperties",
#endif
// These were deprecated a long time ago, still show up in some games for some reason
"MonoBehaviour.allowPrefabModeInPlayMode",
"MonoBehaviour.runInEditMode",
"Component.animation",
"Component.audio",
"Component.camera",
"Component.collider",
"Component.collider2D",
"Component.constantForce",
"Component.hingeJoint",
"Component.light",
"Component.networkView",
"Component.particleSystem",
"Component.renderer",
"Component.rigidbody",
"Component.rigidbody2D",
"Light.flare",
};
private static readonly HashSet<string> bl_methodNameStartsWith = new HashSet<string>
{
// these are redundant
"get_",
"set_",
};
internal static bool IsBlacklisted(string sig) => bl_typeAndMember.Any(it => sig.Contains(it));
internal static bool IsBlacklisted(MethodInfo method) => bl_methodNameStartsWith.Any(it => method.Name.StartsWith(it));
#endregion #endregion