99 lines
3.2 KiB
C#
99 lines
3.2 KiB
C#
using Harmony.ILCopying;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Reflection;
|
|
using System.Reflection.Emit;
|
|
|
|
namespace Harmony
|
|
{
|
|
public static class PatchFunctions
|
|
{
|
|
public static void AddPrefix(PatchInfo patchInfo, string owner, HarmonyMethod info)
|
|
{
|
|
if (info == null || info.method == null) return;
|
|
|
|
var priority = info.prioritiy == -1 ? Priority.Normal : info.prioritiy;
|
|
var before = info.before ?? new string[0];
|
|
var after = info.after ?? new string[0];
|
|
|
|
patchInfo.AddPrefix(info.method, owner, priority, before, after);
|
|
}
|
|
|
|
public static void RemovePrefix(PatchInfo patchInfo, string owner)
|
|
{
|
|
patchInfo.RemovePrefix(owner);
|
|
}
|
|
|
|
public static void AddPostfix(PatchInfo patchInfo, string owner, HarmonyMethod info)
|
|
{
|
|
if (info == null || info.method == null) return;
|
|
|
|
var priority = info.prioritiy == -1 ? Priority.Normal : info.prioritiy;
|
|
var before = info.before ?? new string[0];
|
|
var after = info.after ?? new string[0];
|
|
|
|
patchInfo.AddPostfix(info.method, owner, priority, before, after);
|
|
}
|
|
|
|
public static void RemovePostfix(PatchInfo patchInfo, string owner)
|
|
{
|
|
patchInfo.RemovePostfix(owner);
|
|
}
|
|
|
|
public static void AddTranspiler(PatchInfo patchInfo, string owner, HarmonyMethod info)
|
|
{
|
|
if (info == null || info.method == null) return;
|
|
|
|
var priority = info.prioritiy == -1 ? Priority.Normal : info.prioritiy;
|
|
var before = info.before ?? new string[0];
|
|
var after = info.after ?? new string[0];
|
|
|
|
patchInfo.AddTranspiler(info.method, owner, priority, before, after);
|
|
}
|
|
|
|
public static void RemoveTranspiler(PatchInfo patchInfo, string owner)
|
|
{
|
|
patchInfo.RemoveTranspiler(owner);
|
|
}
|
|
|
|
public static void RemovePatch(PatchInfo patchInfo, MethodInfo patch)
|
|
{
|
|
patchInfo.RemovePatch(patch);
|
|
}
|
|
|
|
// pass in a generator that will create local variables for the returned instructions
|
|
//
|
|
public static List<ILInstruction> GetInstructions(ILGenerator generator, MethodBase method)
|
|
{
|
|
return MethodBodyReader.GetInstructions(generator, method);
|
|
}
|
|
|
|
public static List<MethodInfo> GetSortedPatchMethods(MethodBase original, Patch[] patches)
|
|
{
|
|
return patches
|
|
.Where(p => p.patch != null)
|
|
.OrderBy(p => p)
|
|
.Select(p => p.GetMethod(original))
|
|
.ToList();
|
|
}
|
|
|
|
public static DynamicMethod UpdateWrapper(MethodBase original, PatchInfo patchInfo, string instanceID)
|
|
{
|
|
var sortedPrefixes = GetSortedPatchMethods(original, patchInfo.prefixes);
|
|
var sortedPostfixes = GetSortedPatchMethods(original, patchInfo.postfixes);
|
|
var sortedTranspilers = GetSortedPatchMethods(original, patchInfo.transpilers);
|
|
|
|
var replacement = MethodPatcher.CreatePatchedMethod(original, instanceID, sortedPrefixes, sortedPostfixes, sortedTranspilers);
|
|
if (replacement == null) throw new MissingMethodException("Cannot create dynamic replacement for " + original.FullDescription());
|
|
|
|
var errorString = Memory.DetourMethod(original, replacement);
|
|
if (errorString != null)
|
|
throw new FormatException("Method " + original.FullDescription() + " cannot be patched. Reason: " + errorString);
|
|
|
|
PatchTools.RememberObject(original, replacement); // no gc for new value + release old value to gc
|
|
|
|
return replacement;
|
|
}
|
|
}
|
|
} |