/// <summary>Create a patch processor from an annotated class</summary> /// <param name="type">The class</param> /// public PatchProcessor ProcessorForAnnotatedClass(Type type) { var parentMethodInfos = HarmonyMethodExtensions.GetFromType(type); if (parentMethodInfos != null && parentMethodInfos.Count() > 0) { var info = HarmonyMethod.Merge(parentMethodInfos); return(new PatchProcessor(this, type, info)); } return(null); }
void ImportMethod(MethodInfo theMethod) { method = theMethod; if (method != null) { var infos = HarmonyMethodExtensions.GetFromMethod(method); if (infos != null) { Merge(infos).CopyTo(this); } } }
public static HarmonyMethod Merge(List <HarmonyMethod> attributes) { var result = new HarmonyMethod(); if (attributes == null) { return(result); } var resultTrv = Traverse.Create(result); attributes.ForEach(attribute => { var trv = Traverse.Create(attribute); HarmonyFields().ForEach(f => { var val = trv.Field(f).GetValue(); if (val != null) { HarmonyMethodExtensions.SetValue(resultTrv, f, val); } }); }); return(result); }
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 = container.GetCustomAttributes(true).Any(a => a.GetType().FullName == typeof(HarmonyPatchAll).FullName); 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 var prefixMethod, out var postfixMethod, out var transpilerMethod); if (prefix != null) { prefix.method = prefixMethod; } if (postfix != null) { postfix.method = postfixMethod; } if (transpiler != null) { transpiler.method = transpilerMethod; } if (prefixMethod != null) { if (prefixMethod.IsStatic == false) { throw new ArgumentException("Patch method " + prefixMethod.FullDescription() + " must be static"); } var prefixAttributes = HarmonyMethodExtensions.GetFromMethod(prefix.method); containerAttributes.Merge(HarmonyMethod.Merge(prefixAttributes)).CopyTo(prefix); } if (postfixMethod != null) { if (postfixMethod.IsStatic == false) { throw new ArgumentException("Patch method " + postfixMethod.FullDescription() + " must be static"); } var postfixAttributes = HarmonyMethodExtensions.GetFromMethod(postfixMethod); containerAttributes.Merge(HarmonyMethod.Merge(postfixAttributes)).CopyTo(postfix); } if (transpilerMethod != null) { if (transpilerMethod.IsStatic == false) { throw new ArgumentException("Patch method " + transpilerMethod.FullDescription() + " must be static"); } var infixAttributes = HarmonyMethodExtensions.GetFromMethod(transpilerMethod); containerAttributes.Merge(HarmonyMethod.Merge(infixAttributes)).CopyTo(transpiler); } }