updated: hot reload to 1.13.7

This commit is contained in:
Chris
2025-07-09 23:24:14 -04:00
parent 236f9ea5df
commit 7641b83b6a
45 changed files with 2018 additions and 462 deletions

View File

@@ -6,7 +6,7 @@ using SingularityGroup.HotReload.MonoMod.Utils;
namespace SingularityGroup.HotReload {
static class MethodCompatiblity {
internal static bool AreMethodsCompatible(MethodBase previousMethod, MethodBase patchMethod) {
internal static string CheckCompatibility(MethodBase previousMethod, MethodBase patchMethod) {
var previousConstructor = previousMethod as ConstructorInfo;
var patchConstructor = patchMethod as ConstructorInfo;
if(previousConstructor != null && !ReferenceEquals(patchConstructor, null)) {
@@ -17,20 +17,29 @@ namespace SingularityGroup.HotReload {
if(!ReferenceEquals(previousMethodInfo, null) && !ReferenceEquals(patchMethodInfo, null)) {
return AreMethodInfosCompatible(previousMethodInfo, patchMethodInfo);
}
return false;
return "unknown issue";
}
static bool AreMethodBasesCompatible(MethodBase previousMethod, MethodBase patchMethod) {
static string AreMethodBasesCompatible(MethodBase previousMethod, MethodBase patchMethod) {
if(previousMethod.Name != patchMethod.Name) {
return false;
return "Method name mismatch";
}
//Declaring type of patch method is different from the target method but their full name (namespace + name) is equal
if(previousMethod.DeclaringType.FullName != patchMethod.DeclaringType.FullName) {
return false;
bool isDeclaringTypeCompatible = false;
var declaringType = patchMethod.DeclaringType;
while (declaringType != null) {
if(previousMethod.DeclaringType?.FullName == declaringType.FullName) {
isDeclaringTypeCompatible = true;
break;
}
declaringType = declaringType.BaseType;
}
if (!isDeclaringTypeCompatible) {
return "Declaring type name mismatch";
}
//Check in case type parameter overloads to distinguish between: void M<T>() { } <-> void M() { }
if(previousMethod.IsGenericMethodDefinition != patchMethod.IsGenericMethodDefinition) {
return false;
return "IsGenericMethodDefinition mismatch";
}
var prevParams = previousMethod.GetParameters();
@@ -53,11 +62,11 @@ namespace SingularityGroup.HotReload {
//Special case: patch method for an instance method is static and has an explicit this parameter.
//If the patch method doesn't have any parameters it is not compatible.
if(patchParams.Length == 0) {
return false;
return "missing this parameter";
}
//this parameter has to be the declaring type
if(!ParamTypeMatches(patchParams[0].ParameterType, previousMethod.DeclaringType)) {
return false;
return "this parameter type mismatch";
}
//Ignore the this parameter and compare the remaining ones.
patchParamsSegment = new ArraySegment<ParameterInfo>(patchParams, 1, patchParams.Length - 1);
@@ -75,9 +84,6 @@ namespace SingularityGroup.HotReload {
if (!ParamTypeMatches(patchT, previousMethod.DeclaringType)) {
return false;
}
if (prevParams.Length >= 1 && prevParams[0].ParameterType == previousMethod.DeclaringType) {
return false;
}
return patchParams[0].Name == "this";
}
@@ -85,25 +91,25 @@ namespace SingularityGroup.HotReload {
return patchT == originalT || patchT.IsByRef && patchT.GetElementType() == originalT;
}
static bool CompareParameters(ArraySegment<ParameterInfo> x, ArraySegment<ParameterInfo> y) {
static string CompareParameters(ArraySegment<ParameterInfo> x, ArraySegment<ParameterInfo> y) {
if(x.Count != y.Count) {
return false;
return "parameter count mismatch";
}
for (var i = 0; i < x.Count; i++) {
if(x.Array[i + x.Offset].ParameterType != y.Array[i + y.Offset].ParameterType) {
return false;
return "parameter type mismatch";
}
}
return true;
return null;
}
static bool AreConstructorsCompatible(ConstructorInfo x, ConstructorInfo y) {
static string AreConstructorsCompatible(ConstructorInfo x, ConstructorInfo y) {
return AreMethodBasesCompatible(x, y);
}
static bool AreMethodInfosCompatible(MethodInfo x, MethodInfo y) {
return AreMethodBasesCompatible(x, y) && x.ReturnType == y.ReturnType;
static string AreMethodInfosCompatible(MethodInfo x, MethodInfo y) {
return AreMethodBasesCompatible(x, y) ?? (x.ReturnType == y.ReturnType ? null : "Return type mismatch");
}
}
}