internal static List <AttributePatch> GetPatchMethods(Type type, bool collectIncomplete = false) { return(AccessTools.GetDeclaredMethods(type) .SelectMany(m => AttributePatch.Create(m, collectIncomplete)) .Where(attributePatch => attributePatch is object) .ToList()); }
internal static List <AttributePatch> GetPatchMethods(Type type) { return(AccessTools.GetDeclaredMethods(type) .Select(method => AttributePatch.Create(method)) .Where(attributePatch => attributePatch != null) .ToList()); }
internal static List <AttributePatch> GetPatchMethods(Type type) { return(AccessTools.GetDeclaredMethods(type) .SelectMany(AttributePatch.Create) .Where(attributePatch => attributePatch is object) .ToList()); }
private MethodInfo GetTranspiler(MethodInfo method) { var methodName = method.Name; var type = method.DeclaringType; var methods = AccessTools.GetDeclaredMethods(type); var ici = typeof(IEnumerable <CodeInstruction>); return(methods.FirstOrDefault(m => m.ReturnType == ici && m.Name.StartsWith($"<{methodName}>"))); }
internal static List <AttributePatch> GetPatchMethods(Type type) { var harmonyPatchName = typeof(HarmonyPatch).FullName; return(AccessTools.GetDeclaredMethods(type) .Select(method => AttributePatch.Create(method)) .Where(attributePatch => attributePatch != null) .ToList()); }
List <MethodBase> GetBulkMethods() { var isPatchAll = containerType.GetCustomAttributes(true).Any(a => a.GetType().FullName == typeof(HarmonyPatchAll).FullName); if (isPatchAll) { var type = containerAttributes.declaringType; if (type == null) { throw new ArgumentException($"Using {typeof(HarmonyPatchAll).FullName} requires an additional attribute for specifying the Class/Type"); } var list = new List <MethodBase>(); list.AddRange(AccessTools.GetDeclaredConstructors(type).Cast <MethodBase>()); list.AddRange(AccessTools.GetDeclaredMethods(type).Cast <MethodBase>()); var props = AccessTools.GetDeclaredProperties(type); list.AddRange(props.Select(prop => prop.GetGetMethod(true)).Where(method => method != null).Cast <MethodBase>()); list.AddRange(props.Select(prop => prop.GetSetMethod(true)).Where(method => method != null).Cast <MethodBase>()); return(list); } string FailOnResult(IEnumerable <MethodBase> res) { if (res == null) { return("null"); } if (res.Any(m => m == null)) { return("some element was null"); } return(null); } var targetMethods = RunMethod <HarmonyTargetMethods, IEnumerable <MethodBase> >(null, null, FailOnResult); if (targetMethods != null) { return(targetMethods.ToList()); } var result = new List <MethodBase>(); var targetMethod = RunMethod <HarmonyTargetMethod, MethodBase>(null, null, method => method == null ? "null" : null); if (targetMethod != null) { result.Add(targetMethod); } return(result); }
internal static MethodInfo GetManipulator(MethodInfo method) { var methodName = method.Name; var type = method.DeclaringType; var methods = AccessTools.GetDeclaredMethods(type); var ctxType = typeof(ILContext); return(methods.FirstOrDefault(m => { if (!m.GetParameters().Select(p => p.ParameterType).Contains(ctxType)) { return false; } return m.Name.StartsWith($"<{methodName }>"); })); }
internal static MethodInfo GetTranspiler(MethodInfo method) { var methodName = method.Name; var type = method.DeclaringType; var methods = AccessTools.GetDeclaredMethods(type); var ici = typeof(IEnumerable <CodeInstruction>); return(methods.FirstOrDefault(m => { if (m.ReturnType != ici) { return false; } return m.Name.StartsWith($"<{methodName }>"); })); }
List <MethodBase> GetBulkMethods() { var isPatchAll = containerType.GetCustomAttributes(true).Any(a => a.GetType().FullName == typeof(HarmonyPatchAll).FullName); if (isPatchAll) { var type = containerAttributes.declaringType; if (type is null) { throw new ArgumentException($"Using {typeof(HarmonyPatchAll).FullName} requires an additional attribute for specifying the Class/Type"); } var list = new List <MethodBase>(); list.AddRange(AccessTools.GetDeclaredConstructors(type).Cast <MethodBase>()); list.AddRange(AccessTools.GetDeclaredMethods(type).Cast <MethodBase>()); var props = AccessTools.GetDeclaredProperties(type); list.AddRange(props.Select(prop => prop.GetGetMethod(true)).Where(method => method is object).Cast <MethodBase>()); list.AddRange(props.Select(prop => prop.GetSetMethod(true)).Where(method => method is object).Cast <MethodBase>()); return(list); }
void PrepareType() { var mainPrepareResult = RunMethod <HarmonyPrepare, bool>(true); if (mainPrepareResult == false) { return; } var customOriginals = RunMethod <HarmonyTargetMethods, IEnumerable <MethodBase> >(null); if (customOriginals != null) { originals.Clear(); originals.AddRange(customOriginals); } 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, out var finalizerMethod); if (prefix != null) { prefix.method = prefixMethod; } if (postfix != null) { postfix.method = postfixMethod; } if (transpiler != null) { transpiler.method = transpilerMethod; } if (finalizer != null) { finalizer.method = finalizerMethod; } if (prefixMethod != null) { if (prefixMethod.IsStatic == false) { throw new ArgumentException("Patch method " + prefixMethod.FullDescription() + " must be static"); } var prefixAttributes = HarmonyMethodExtensions.GetFromMethod(prefixMethod); 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 transpilerAttributes = HarmonyMethodExtensions.GetFromMethod(transpilerMethod); containerAttributes.Merge(HarmonyMethod.Merge(transpilerAttributes)).CopyTo(transpiler); } if (finalizerMethod != null) { if (finalizerMethod.IsStatic == false) { throw new ArgumentException("Patch method " + finalizerMethod.FullDescription() + " must be static"); } var finalizerAttributes = HarmonyMethodExtensions.GetFromMethod(finalizerMethod); containerAttributes.Merge(HarmonyMethod.Merge(finalizerAttributes)).CopyTo(finalizer); } }
private void PrepareType() { var mainPrepareResult = RunMethod <HarmonyPrepare, bool>(true); if (mainPrepareResult == false) { return; } var originalMethodType = containerAttributes.methodType; // MethodType default is Normal if (containerAttributes.methodType == null) { containerAttributes.methodType = MethodType.Normal; } var reversePatchAttr = typeof(HarmonyReversePatch).FullName; var reversePatchMethods = container.GetMethods(AccessTools.all).Where(m => m.GetCustomAttributes(true).Any(a => a.GetType().FullName == reversePatchAttr)).ToList(); foreach (var reversePatchMethod in reversePatchMethods) { var attr = containerAttributes.Merge(new HarmonyMethod(reversePatchMethod)); var originalMethod = GetOriginalMethod(attr); var reversePatcher = instance.CreateReversePatcher(originalMethod, reversePatchMethod); reversePatcher.Patch(); } var customOriginals = RunMethod <HarmonyTargetMethods, IEnumerable <MethodBase> >(null); if (customOriginals != null) { originals.Clear(); originals.AddRange(customOriginals); } else { 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) ?? GetOriginalMethod(containerAttributes); 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); } } GetPatches(container, out var prefixMethod, out var postfixMethod, out var transpilerMethod, out var finalizerMethod); if (prefix != null) { prefix.method = prefixMethod; } if (postfix != null) { postfix.method = postfixMethod; } if (transpiler != null) { transpiler.method = transpilerMethod; } if (finalizer != null) { finalizer.method = finalizerMethod; } if (prefixMethod != null) { if (prefixMethod.IsStatic == false) { throw new ArgumentException($"Patch method {prefixMethod.GetID()} must be static"); } var prefixAttributes = HarmonyMethodExtensions.GetFromMethod(prefixMethod); containerAttributes.Merge(HarmonyMethod.Merge(prefixAttributes)).CopyTo(prefix); } if (postfixMethod != null) { if (postfixMethod.IsStatic == false) { throw new ArgumentException($"Patch method {postfixMethod.GetID()} 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.GetID()} must be static"); } var transpilerAttributes = HarmonyMethodExtensions.GetFromMethod(transpilerMethod); containerAttributes.Merge(HarmonyMethod.Merge(transpilerAttributes)).CopyTo(transpiler); } if (finalizerMethod != null) { if (finalizerMethod.IsStatic == false) { throw new ArgumentException($"Patch method {finalizerMethod.GetID()} must be static"); } var finalizerAttributes = HarmonyMethodExtensions.GetFromMethod(finalizerMethod); containerAttributes.Merge(HarmonyMethod.Merge(finalizerAttributes)).CopyTo(finalizer); } }