mirror of
https://github.com/GrahamKracker/UnityExplorer.git
synced 2025-07-13 07:16:37 +08:00
Add configurable reflection signature blacklist, extends to MCS as well
This commit is contained in:
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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 += () =>
|
||||||
{
|
{
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user