private void PrepareType() { if (!RunMethod <HarmonyPrepare, bool>(true)) { return; } var enumerable = RunMethod <HarmonyTargetMethods, IEnumerable <MethodBase> >(null); if (enumerable != null) { originals = enumerable.ToList(); } else if (Attribute.GetCustomAttribute(container, typeof(HarmonyPatchAll)) != null) { var originalType = containerAttributes.originalType; originals.AddRange(AccessTools.GetDeclaredConstructors(originalType).Cast <MethodBase>()); originals.AddRange(AccessTools.GetDeclaredMethods(originalType).Cast <MethodBase>()); } else { var methodBase = GetOriginalMethod() ?? RunMethod <HarmonyTargetMethod, MethodBase>(null); if (methodBase == null) { throw new ArgumentException("No target method specified for class " + container.FullName); } originals.Add(methodBase); } PatchTools.GetPatches(container, out prefix.method, out postfix.method, out transpiler.method); if (prefix.method != null) { if (!prefix.method.IsStatic) { throw new ArgumentException("Patch method " + prefix.method.FullDescription() + " must be static"); } var harmonyMethods = prefix.method.GetHarmonyMethods(); containerAttributes.Merge(HarmonyMethod.Merge(harmonyMethods)).CopyTo(prefix); } if (postfix.method != null) { if (!postfix.method.IsStatic) { throw new ArgumentException("Patch method " + postfix.method.FullDescription() + " must be static"); } var harmonyMethods2 = postfix.method.GetHarmonyMethods(); containerAttributes.Merge(HarmonyMethod.Merge(harmonyMethods2)).CopyTo(postfix); } if (transpiler.method != null) { if (!transpiler.method.IsStatic) { throw new ArgumentException("Patch method " + transpiler.method.FullDescription() + " must be static"); } var harmonyMethods3 = transpiler.method.GetHarmonyMethods(); containerAttributes.Merge(HarmonyMethod.Merge(harmonyMethods3)).CopyTo(transpiler); } }
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()); case MethodType.Setter: if (attr.methodName == null) { return(null); } return(AccessTools.DeclaredProperty(attr.declaringType, attr.methodName).GetSetMethod()); 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); }
void PrepareType() { var mainPrepareResult = RunMethod <HarmonyPrepare, bool>(true); if (mainPrepareResult == false) { return; } var customOriginals = RunMethod <HarmonyTargetMethods, IEnumerable <MethodBase> >(null); if (customOriginals != null) { originals = customOriginals.ToList(); } else { var isPatchAll = Attribute.GetCustomAttribute(container, typeof(HarmonyPatchAll)) != null; if (isPatchAll) { var type = containerAttributes.declaringType; originals.AddRange(AccessTools.GetDeclaredConstructors(type).Cast <MethodBase>()); originals.AddRange(AccessTools.GetDeclaredMethods(type).Cast <MethodBase>()); } else { var original = GetOriginalMethod(); if (original == null) { original = RunMethod <HarmonyTargetMethod, MethodBase>(null); } if (original != null) { originals.Add(original); } else { throw new ArgumentException("No target method specified for class " + container.FullName); } } } PatchTools.GetPatches(container, out prefix.method, out postfix.method, out transpiler.method); if (prefix.method != null) { if (prefix.method.IsStatic == false) { throw new ArgumentException("Patch method " + prefix.method.FullDescription() + " must be static"); } var prefixAttributes = prefix.method.GetHarmonyMethods(); containerAttributes.Merge(HarmonyMethod.Merge(prefixAttributes)).CopyTo(prefix); } if (postfix.method != null) { if (postfix.method.IsStatic == false) { throw new ArgumentException("Patch method " + postfix.method.FullDescription() + " must be static"); } var postfixAttributes = postfix.method.GetHarmonyMethods(); containerAttributes.Merge(HarmonyMethod.Merge(postfixAttributes)).CopyTo(postfix); } if (transpiler.method != null) { if (transpiler.method.IsStatic == false) { throw new ArgumentException("Patch method " + transpiler.method.FullDescription() + " must be static"); } var infixAttributes = transpiler.method.GetHarmonyMethods(); containerAttributes.Merge(HarmonyMethod.Merge(infixAttributes)).CopyTo(transpiler); } }
void PrepareType() { var mainPrepareResult = RunMethod <HarmonyPrepare, bool>(true); if (mainPrepareResult == false) { return; } var customOriginals = RunMethod <HarmonyTargetMethods, IEnumerable <MethodBase> >(null); if (customOriginals != null) { originals = customOriginals.ToList(); } else { var originalMethodType = containerAttributes.methodType; // MethodType default is Normal if (containerAttributes.methodType == null) { containerAttributes.methodType = MethodType.Normal; } var isPatchAll = Attribute.GetCustomAttribute(container, typeof(HarmonyPatchAll)) != null; if (isPatchAll) { var type = containerAttributes.declaringType; originals.AddRange(AccessTools.GetDeclaredConstructors(type).Cast <MethodBase>()); originals.AddRange(AccessTools.GetDeclaredMethods(type).Cast <MethodBase>()); var props = AccessTools.GetDeclaredProperties(type); originals.AddRange(props.Select(prop => prop.GetGetMethod(true)).Where(method => method != null).Cast <MethodBase>()); originals.AddRange(props.Select(prop => prop.GetSetMethod(true)).Where(method => method != null).Cast <MethodBase>()); } else { var original = RunMethod <HarmonyTargetMethod, MethodBase>(null); if (original == null) { original = GetOriginalMethod(); } if (original == null) { var info = "("; info += "declaringType=" + containerAttributes.declaringType + ", "; info += "methodName =" + containerAttributes.methodName + ", "; info += "methodType=" + originalMethodType + ", "; info += "argumentTypes=" + containerAttributes.argumentTypes.Description(); info += ")"; throw new ArgumentException("No target method specified for class " + container.FullName + " " + info); } originals.Add(original); } } PatchTools.GetPatches(container, out prefix.method, out postfix.method, out transpiler.method); if (prefix.method != null) { if (prefix.method.IsStatic == false) { throw new ArgumentException("Patch method " + prefix.method.FullDescription() + " must be static"); } var prefixAttributes = prefix.method.GetHarmonyMethods(); containerAttributes.Merge(HarmonyMethod.Merge(prefixAttributes)).CopyTo(prefix); } if (postfix.method != null) { if (postfix.method.IsStatic == false) { throw new ArgumentException("Patch method " + postfix.method.FullDescription() + " must be static"); } var postfixAttributes = postfix.method.GetHarmonyMethods(); containerAttributes.Merge(HarmonyMethod.Merge(postfixAttributes)).CopyTo(postfix); } if (transpiler.method != null) { if (transpiler.method.IsStatic == false) { throw new ArgumentException("Patch method " + transpiler.method.FullDescription() + " must be static"); } var infixAttributes = transpiler.method.GetHarmonyMethods(); containerAttributes.Merge(HarmonyMethod.Merge(infixAttributes)).CopyTo(transpiler); } }