internal static MethodBase GetOriginalMethod(this HarmonyMethod attr) { try { switch (attr.methodType) { case MethodType.Normal: if (attr.methodName is null) { return(null); } return(AccessTools.DeclaredMethod(attr.declaringType, attr.methodName, attr.argumentTypes)); case MethodType.Getter: if (attr.methodName is null) { return(null); } return(AccessTools.DeclaredProperty(attr.declaringType, attr.methodName).GetGetMethod(true)); case MethodType.Setter: if (attr.methodName is null) { return(null); } return(AccessTools.DeclaredProperty(attr.declaringType, attr.methodName).GetSetMethod(true)); case MethodType.Constructor: return(AccessTools.DeclaredConstructor(attr.declaringType, attr.argumentTypes)); case MethodType.StaticConstructor: return(AccessTools.GetDeclaredConstructors(attr.declaringType) .Where(c => c.IsStatic) .FirstOrDefault()); case MethodType.Enumerator: if (attr.methodName is null) { return(null); } var method = AccessTools.DeclaredMethod(attr.declaringType, attr.methodName, attr.argumentTypes); return(AccessTools.EnumeratorMoveNext(method)); } } catch (AmbiguousMatchException ex) { throw new HarmonyException($"Ambiguous match for HarmonyMethod[{attr.Description()}]", ex.InnerException ?? ex); } return(null); }
internal PropertyInfo GetPropertyInfo(Type type, string name) { if (properties.TryGetValue(type, out var propertiesByType) == false) { propertiesByType = new Dictionary <string, PropertyInfo>(); properties.Add(type, propertiesByType); } if (propertiesByType.TryGetValue(name, out var property) == false) { property = AccessTools.DeclaredProperty(type, name); propertiesByType.Add(name, property); } return(property); }
MethodBase GetOriginalMethod() { var attr = containerAttributes; if (attr.declaringType == null) { return(null); } switch (attr.methodType) { case MethodType.Normal: if (attr.methodName == null) { return(null); } return(AccessTools.DeclaredMethod(attr.declaringType, attr.methodName, attr.argumentTypes)); case MethodType.Getter: if (attr.methodName == null) { return(null); } return(AccessTools.DeclaredProperty(attr.declaringType, attr.methodName).GetGetMethod(true)); case MethodType.Setter: if (attr.methodName == null) { return(null); } return(AccessTools.DeclaredProperty(attr.declaringType, attr.methodName).GetSetMethod(true)); case MethodType.Constructor: return(AccessTools.DeclaredConstructor(attr.declaringType, attr.argumentTypes)); case MethodType.StaticConstructor: return(AccessTools.GetDeclaredConstructors(attr.declaringType) .Where(c => c.IsStatic) .FirstOrDefault()); } return(null); }
internal static MethodBase GetOriginalMethod(this HarmonyMethod attr) { switch (attr.methodType) { case MethodType.Normal: if (attr.methodName == null) { return(null); } return(AccessTools.DeclaredMethod(attr.declaringType, attr.methodName, attr.argumentTypes)); case MethodType.Getter: if (attr.methodName == null) { return(null); } return(AccessTools.DeclaredProperty(attr.declaringType, attr.methodName).GetGetMethod(true)); case MethodType.Setter: if (attr.methodName == null) { return(null); } return(AccessTools.DeclaredProperty(attr.declaringType, attr.methodName).GetSetMethod(true)); case MethodType.Constructor: return(AccessTools.DeclaredConstructor(attr.declaringType, attr.argumentTypes)); case MethodType.StaticConstructor: return(AccessTools.GetDeclaredConstructors(attr.declaringType) .Where(c => c.IsStatic) .FirstOrDefault()); } return(null); }
/// <summary> /// Get the member specified by the <paramref name="attribute"/>. Throws if the member was not found. /// </summary> /// <exception cref="ArgumentException">Thrown if the member described in the <paramref name="attribute"/> couldn't be found.</exception> /// <exception cref="ArgumentNullException"><paramref name="attribute"/> is <see langword="null"/></exception> internal static MethodBase GetOriginalMethod(HarmonyMethod attribute) { if (attribute == null) { throw new ArgumentNullException(nameof(attribute)); } string GetPatchName() { return(attribute.method?.FullDescription() ?? "Unknown patch"); } MethodBase MakeFailure(string reason) { Logger.Log(Logger.LogChannel.Error, () => $"Failed to process patch {GetPatchName()} - {reason}"); return(null); } if (attribute.declaringType == null) { return(MakeFailure("declaringType cannot be null")); } switch (attribute.methodType) { case MethodType.Normal: { if (string.IsNullOrEmpty(attribute.methodName)) { return(MakeFailure("methodName can't be empty")); } if (attribute.methodName == ".ctor") { Logger.LogText(Logger.LogChannel.Warn, GetPatchName() + " - MethodType.Constructor should be used instead of setting methodName to .ctor"); goto case MethodType.Constructor; } if (attribute.methodName == ".cctor") { Logger.LogText(Logger.LogChannel.Warn, GetPatchName() + " - MethodType.StaticConstructor should be used instead of setting methodName to .cctor"); goto case MethodType.StaticConstructor; } if (attribute.methodName.StartsWith("get_") || attribute.methodName.StartsWith("set_")) { Logger.LogText(Logger.LogChannel.Warn, GetPatchName() + " - MethodType.Getter and MethodType.Setter should be used instead adding get_ and set_ to property names"); } var result = AccessTools.DeclaredMethod(attribute.declaringType, attribute.methodName, attribute.argumentTypes); if (result != null) { return(result); } result = AccessTools.Method(attribute.declaringType, attribute.methodName, attribute.argumentTypes); if (result != null) { Logger.LogText(Logger.LogChannel.Warn, GetPatchName() + $" - Could not find method {attribute.methodName} with {attribute.argumentTypes?.Length ?? 0} parameters in type {attribute.declaringType.FullDescription()}, but it was found in base class of this type {result.DeclaringType.FullDescription()}"); return(result); } return(MakeFailure($"Could not find method {attribute.methodName} with {attribute.argumentTypes.Description()} parameters in type {attribute.declaringType.FullDescription()}")); } case MethodType.Getter: { if (string.IsNullOrEmpty(attribute.methodName)) { return(MakeFailure("methodName can't be empty")); } var result = AccessTools.DeclaredProperty(attribute.declaringType, attribute.methodName); if (result != null) { var getter = result.GetGetMethod(true); if (getter == null) { return(MakeFailure($"Property {attribute.methodName} does not have a Getter")); } return(getter); } result = AccessTools.Property(attribute.declaringType, attribute.methodName); if (result != null) { Logger.LogText(Logger.LogChannel.Warn, GetPatchName() + $" - Could not find property {attribute.methodName} in type {attribute.declaringType.FullDescription()}, but it was found in base class of this type: {result.DeclaringType.FullDescription()}"); var getter = result.GetGetMethod(true); if (getter == null) { return(MakeFailure($"Property {attribute.methodName} does not have a Getter")); } return(getter); } return(MakeFailure($"Could not find property {attribute.methodName} in type {attribute.declaringType.FullDescription()}")); } case MethodType.Setter: { if (string.IsNullOrEmpty(attribute.methodName)) { return(MakeFailure("methodName can't be empty")); } var result = AccessTools.DeclaredProperty(attribute.declaringType, attribute.methodName); if (result != null) { var getter = result.GetSetMethod(true); if (getter == null) { return(MakeFailure($"Property {attribute.methodName} does not have a Setter")); } return(getter); } result = AccessTools.Property(attribute.declaringType, attribute.methodName); if (result != null) { Logger.LogText(Logger.LogChannel.Warn, GetPatchName() + $" - Could not find property {attribute.methodName} in type {attribute.declaringType.FullDescription()}, but it was found in base class of this type: {result.DeclaringType.FullDescription()}"); var getter = result.GetSetMethod(true); if (getter == null) { return(MakeFailure($"Property {attribute.methodName} does not have a Setter")); } return(getter); } return(MakeFailure($"Could not find property {attribute.methodName} in type {attribute.declaringType.FullDescription()}")); } case MethodType.Constructor: { var constructor = AccessTools.DeclaredConstructor(attribute.declaringType, attribute.argumentTypes); if (constructor != null) { return(constructor); } return(MakeFailure($"Could not find constructor with {attribute.argumentTypes.Description()} parameters in type {attribute.declaringType.FullDescription()}")); } case MethodType.StaticConstructor: { var constructor = AccessTools.GetDeclaredConstructors(attribute.declaringType).FirstOrDefault(c => c.IsStatic); if (constructor != null) { return(constructor); } return(MakeFailure($"Could not find static constructor in type {attribute.declaringType.FullDescription()}")); } default: throw new ArgumentOutOfRangeException(nameof(attribute.methodType), attribute.methodType, "Unknown method type"); } }