mirror of
https://github.com/sinai-dev/UnityExplorer.git
synced 2025-09-20 21:46:02 +08:00
1.6.4
* Fix for games which do not load InputModule on startup. CppExplorer will now try to load the module itself. * Cleanups
This commit is contained in:
@ -1,51 +1,107 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Reflection;
|
||||
using UnityEngine;
|
||||
using MelonLoader;
|
||||
|
||||
namespace Explorer
|
||||
{
|
||||
/// <summary>
|
||||
/// Version-agnostic UnityEngine.Input module using Reflection
|
||||
/// Version-agnostic UnityEngine Input module using Reflection.
|
||||
/// </summary>
|
||||
public class InputHelper
|
||||
public static class InputHelper
|
||||
{
|
||||
private static readonly Type input = ReflectionHelpers.GetTypeByName("UnityEngine.Input");
|
||||
public static void CheckInput()
|
||||
{
|
||||
if (Input == null)
|
||||
{
|
||||
MelonLogger.Log("UnityEngine.Input is null, trying to load manually....");
|
||||
|
||||
private static readonly PropertyInfo mousePositionInfo = input.GetProperty("mousePosition");
|
||||
if ((TryLoad("UnityEngine.InputLegacyModule.dll") || TryLoad("UnityEngine.CoreModule.dll")) && Input != null)
|
||||
{
|
||||
MelonLogger.Log("Ok!");
|
||||
}
|
||||
else
|
||||
{
|
||||
MelonLogger.Log("Could not load Input module!");
|
||||
}
|
||||
|
||||
private static readonly MethodInfo getKey = input.GetMethod("GetKey", new Type[] { typeof(KeyCode) });
|
||||
private static readonly MethodInfo getKeyDown = input.GetMethod("GetKeyDown", new Type[] { typeof(KeyCode) });
|
||||
private static readonly MethodInfo getMouseButtonDown = input.GetMethod("GetMouseButtonDown", new Type[] { typeof(int) });
|
||||
private static readonly MethodInfo getMouseButton = input.GetMethod("GetMouseButton", new Type[] { typeof(int) });
|
||||
bool TryLoad(string module)
|
||||
{
|
||||
var path = $@"MelonLoader\Managed\{module}";
|
||||
if (!File.Exists(path)) return false;
|
||||
|
||||
try
|
||||
{
|
||||
Assembly.Load(File.ReadAllBytes(path));
|
||||
return true;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
MelonLogger.Log(e.GetType() + ", " + e.Message);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static Type Input => _input ?? (_input = ReflectionHelpers.GetTypeByName("UnityEngine.Input"));
|
||||
private static Type _input;
|
||||
|
||||
private static PropertyInfo MousePosInfo => _mousePosition ?? (_mousePosition = Input?.GetProperty("mousePosition"));
|
||||
private static PropertyInfo _mousePosition;
|
||||
|
||||
private static MethodInfo GetKeyInfo => _getKey ?? (_getKey = Input?.GetMethod("GetKey", new Type[] { typeof(KeyCode) }));
|
||||
private static MethodInfo _getKey;
|
||||
|
||||
private static MethodInfo GetKeyDownInfo => _getKeyDown ?? (_getKeyDown = Input?.GetMethod("GetKeyDown", new Type[] { typeof(KeyCode) }));
|
||||
private static MethodInfo _getKeyDown;
|
||||
|
||||
private static MethodInfo GetMouseButtonInfo => _getMouseButton ?? (_getMouseButton = Input?.GetMethod("GetMouseButton", new Type[] { typeof(int) }));
|
||||
private static MethodInfo _getMouseButton;
|
||||
|
||||
private static MethodInfo GetMouseButtonDownInfo => _getMouseButtonDown ?? (_getMouseButtonDown = Input?.GetMethod("GetMouseButtonDown", new Type[] { typeof(int) }));
|
||||
private static MethodInfo _getMouseButtonDown;
|
||||
|
||||
#pragma warning disable IDE1006 // Camel-case property (Unity style)
|
||||
public static Vector3 mousePosition => (Vector3)mousePositionInfo.GetValue(null);
|
||||
public static Vector3 mousePosition
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Input == null) return Vector3.zero;
|
||||
return (Vector3)MousePosInfo.GetValue(null);
|
||||
}
|
||||
}
|
||||
#pragma warning restore IDE1006
|
||||
|
||||
public static bool GetKeyDown(KeyCode key)
|
||||
{
|
||||
return (bool)getKeyDown.Invoke(null, new object[] { key });
|
||||
if (Input == null) return false;
|
||||
return (bool)GetKeyDownInfo.Invoke(null, new object[] { key });
|
||||
}
|
||||
|
||||
public static bool GetKey(KeyCode key)
|
||||
{
|
||||
return (bool)getKey.Invoke(null, new object[] { key });
|
||||
if (Input == null) return false;
|
||||
return (bool)GetKeyInfo.Invoke(null, new object[] { key });
|
||||
}
|
||||
|
||||
/// <param name="btn">1 = left, 2 = middle, 3 = right, etc</param>
|
||||
public static bool GetMouseButtonDown(int btn)
|
||||
{
|
||||
return (bool)getMouseButtonDown.Invoke(null, new object[] { btn });
|
||||
if (Input == null) return false;
|
||||
return (bool)GetMouseButtonDownInfo.Invoke(null, new object[] { btn });
|
||||
}
|
||||
|
||||
/// <param name="btn">1 = left, 2 = middle, 3 = right, etc</param>
|
||||
public static bool GetMouseButton(int btn)
|
||||
{
|
||||
return (bool)getMouseButton.Invoke(null, new object[] { btn });
|
||||
if (Input == null) return false;
|
||||
return (bool)GetMouseButtonInfo.Invoke(null, new object[] { btn });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,16 +1,13 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Reflection;
|
||||
using UnhollowerBaseLib;
|
||||
using UnhollowerRuntimeLib;
|
||||
using UnityEngine;
|
||||
using BF = System.Reflection.BindingFlags;
|
||||
using MelonLoader;
|
||||
using System.Collections;
|
||||
using Mono.CSharp;
|
||||
using ILType = Il2CppSystem.Type;
|
||||
|
||||
namespace Explorer
|
||||
{
|
||||
@ -18,11 +15,11 @@ namespace Explorer
|
||||
{
|
||||
public static BF CommonFlags = BF.Public | BF.Instance | BF.NonPublic | BF.Static;
|
||||
|
||||
public static Il2CppSystem.Type GameObjectType => Il2CppType.Of<GameObject>();
|
||||
public static Il2CppSystem.Type TransformType => Il2CppType.Of<Transform>();
|
||||
public static Il2CppSystem.Type ObjectType => Il2CppType.Of<UnityEngine.Object>();
|
||||
public static Il2CppSystem.Type ComponentType => Il2CppType.Of<Component>();
|
||||
public static Il2CppSystem.Type BehaviourType => Il2CppType.Of<Behaviour>();
|
||||
public static ILType GameObjectType => Il2CppType.Of<GameObject>();
|
||||
public static ILType TransformType => Il2CppType.Of<Transform>();
|
||||
public static ILType ObjectType => Il2CppType.Of<UnityEngine.Object>();
|
||||
public static ILType ComponentType => Il2CppType.Of<Component>();
|
||||
public static ILType BehaviourType => Il2CppType.Of<Behaviour>();
|
||||
|
||||
private static readonly MethodInfo m_tryCastMethodInfo = typeof(Il2CppObjectBase).GetMethod("TryCast");
|
||||
|
||||
@ -35,47 +32,6 @@ namespace Explorer
|
||||
.Invoke(obj, null);
|
||||
}
|
||||
|
||||
public static string ExceptionToString(Exception e)
|
||||
{
|
||||
if (IsFailedGeneric(e))
|
||||
{
|
||||
return "Unable to initialize this type.";
|
||||
}
|
||||
else if (IsObjectCollected(e))
|
||||
{
|
||||
return "Garbage collected in Il2Cpp.";
|
||||
}
|
||||
|
||||
return e.GetType() + ", " + e.Message;
|
||||
}
|
||||
|
||||
public static bool IsFailedGeneric(Exception e)
|
||||
{
|
||||
return IsExceptionOfType(e, typeof(TargetInvocationException)) && IsExceptionOfType(e, typeof(TypeLoadException));
|
||||
}
|
||||
|
||||
public static bool IsObjectCollected(Exception e)
|
||||
{
|
||||
return IsExceptionOfType(e, typeof(ObjectCollectedException));
|
||||
}
|
||||
|
||||
public static bool IsExceptionOfType(Exception e, Type t, bool strict = true, bool checkInner = true)
|
||||
{
|
||||
bool isType;
|
||||
|
||||
if (strict)
|
||||
isType = e.GetType() == t;
|
||||
else
|
||||
isType = t.IsAssignableFrom(e.GetType());
|
||||
|
||||
if (isType) return true;
|
||||
|
||||
if (e.InnerException != null && checkInner)
|
||||
return IsExceptionOfType(e.InnerException, t, strict);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool IsEnumerable(Type t)
|
||||
{
|
||||
return typeof(IEnumerable).IsAssignableFrom(t);
|
||||
@ -117,7 +73,7 @@ namespace Explorer
|
||||
{
|
||||
foreach (var asm in AppDomain.CurrentDomain.GetAssemblies())
|
||||
{
|
||||
foreach (var type in GetTypesSafe(asm))
|
||||
foreach (var type in asm.TryGetTypes())
|
||||
{
|
||||
if (type.FullName == fullName)
|
||||
{
|
||||
@ -148,13 +104,6 @@ namespace Explorer
|
||||
return obj.GetType();
|
||||
}
|
||||
|
||||
public static IEnumerable<Type> GetTypesSafe(Assembly asm)
|
||||
{
|
||||
try { return asm.GetTypes(); }
|
||||
catch (ReflectionTypeLoadException e) { return e.Types.Where(x => x != null); }
|
||||
catch { return Enumerable.Empty<Type>(); }
|
||||
}
|
||||
|
||||
public static Type[] GetAllBaseTypes(object obj)
|
||||
{
|
||||
var list = new List<Type>();
|
||||
@ -170,5 +119,46 @@ namespace Explorer
|
||||
|
||||
return list.ToArray();
|
||||
}
|
||||
|
||||
public static string ExceptionToString(Exception e)
|
||||
{
|
||||
if (IsFailedGeneric(e))
|
||||
{
|
||||
return "Unable to initialize this type.";
|
||||
}
|
||||
else if (IsObjectCollected(e))
|
||||
{
|
||||
return "Garbage collected in Il2Cpp.";
|
||||
}
|
||||
|
||||
return e.GetType() + ", " + e.Message;
|
||||
}
|
||||
|
||||
public static bool IsFailedGeneric(Exception e)
|
||||
{
|
||||
return IsExceptionOfType(e, typeof(TargetInvocationException)) && IsExceptionOfType(e, typeof(TypeLoadException));
|
||||
}
|
||||
|
||||
public static bool IsObjectCollected(Exception e)
|
||||
{
|
||||
return IsExceptionOfType(e, typeof(ObjectCollectedException));
|
||||
}
|
||||
|
||||
public static bool IsExceptionOfType(Exception e, Type t, bool strict = true, bool checkInner = true)
|
||||
{
|
||||
bool isType;
|
||||
|
||||
if (strict)
|
||||
isType = e.GetType() == t;
|
||||
else
|
||||
isType = t.IsAssignableFrom(e.GetType());
|
||||
|
||||
if (isType) return true;
|
||||
|
||||
if (e.InnerException != null && checkInner)
|
||||
return IsExceptionOfType(e.InnerException, t, strict);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user