131 lines
4.5 KiB
C#
131 lines
4.5 KiB
C#
using System;
|
|
using System.Diagnostics;
|
|
using System.Reflection;
|
|
using NLog;
|
|
using Torch.Managers.PatchManager;
|
|
|
|
namespace Global.Patches
|
|
{
|
|
public static class Patcher
|
|
{
|
|
private static readonly Logger Log = LogManager.GetCurrentClassLogger();
|
|
public static PatchContext ctx;
|
|
|
|
|
|
public static void InitilizePatcherContext(PatchContext Context)
|
|
{
|
|
ctx = Context;
|
|
}
|
|
|
|
public static MethodInfo GetMethod<T>(string TargetMethodName, BindingFlags Flags)
|
|
{
|
|
return MethodGet(typeof(T), TargetMethodName, Flags, null);
|
|
}
|
|
|
|
public static MethodInfo GetMethod<T>(
|
|
string TargetMethodName,
|
|
BindingFlags Flags,
|
|
Type[] Types)
|
|
{
|
|
return MethodGet(typeof(T), TargetMethodName, Flags, Types);
|
|
}
|
|
|
|
public static MethodInfo SuffixPatch<T>(
|
|
string TargetMethodName,
|
|
BindingFlags Flags,
|
|
string ReplaceMentMethodName)
|
|
{
|
|
return Patch(false, typeof(T), TargetMethodName, Flags, ReplaceMentMethodName, null);
|
|
}
|
|
|
|
public static MethodInfo SuffixPatch<T>(
|
|
string TargetMethodName,
|
|
BindingFlags Flags,
|
|
Type[] Types,
|
|
string ReplaceMentMethodName)
|
|
{
|
|
return Patch(false, typeof(T), TargetMethodName, Flags, ReplaceMentMethodName, Types);
|
|
}
|
|
|
|
public static MethodInfo PrePatch<T>(
|
|
string TargetMethodName,
|
|
BindingFlags Flags,
|
|
string ReplaceMentMethodName)
|
|
{
|
|
return Patch(true, typeof(T), TargetMethodName, Flags, ReplaceMentMethodName, null);
|
|
}
|
|
|
|
public static MethodInfo PrePatch<T>(
|
|
string TargetMethodName,
|
|
BindingFlags Flags,
|
|
Type[] Types,
|
|
string ReplaceMentMethodName)
|
|
{
|
|
return Patch(true, typeof(T), TargetMethodName, Flags, ReplaceMentMethodName, Types);
|
|
}
|
|
|
|
private static MethodInfo Patch(
|
|
bool PreFix,
|
|
Type TargetClass,
|
|
string TargetMethodName,
|
|
BindingFlags Flags,
|
|
string ReplaceMentMethodName,
|
|
Type[] Types)
|
|
{
|
|
try
|
|
{
|
|
var method1 = Types != null
|
|
? TargetClass.GetMethod(TargetMethodName, Flags, null, Types, null)
|
|
: TargetClass.GetMethod(TargetMethodName, Flags);
|
|
if (method1 == null)
|
|
{
|
|
Log.Error("Unable to find patch method " + TargetClass.Name + "." + TargetMethodName);
|
|
return null;
|
|
}
|
|
|
|
var declaringType = new StackFrame(2, false).GetMethod().DeclaringType;
|
|
if (declaringType == null)
|
|
Log.Error("Unable to find calling class!");
|
|
var method2 = declaringType.GetMethod(ReplaceMentMethodName,
|
|
BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
|
|
if (PreFix)
|
|
ctx.GetPattern(method1).Prefixes.Add(method2);
|
|
else
|
|
ctx.GetPattern(method1).Suffixes.Add(method2);
|
|
return method1;
|
|
}
|
|
catch (AmbiguousMatchException ex)
|
|
{
|
|
Log.Error(ex,
|
|
"You need to specify the method types! More than one method named: " + TargetClass.Name + "." +
|
|
TargetMethodName, Array.Empty<object>());
|
|
}
|
|
catch (ArgumentException ex)
|
|
{
|
|
Log.Error(ex, "Invalid Arguments for " + TargetMethodName + " exsisting in: " + TargetClass.Name,
|
|
Array.Empty<object>());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Log.Error(ex, "Unkown Patch Error!", Array.Empty<object>());
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
private static MethodInfo MethodGet(
|
|
Type TargetClass,
|
|
string TargetMethodName,
|
|
BindingFlags Flags,
|
|
Type[] Types)
|
|
{
|
|
var methodInfo = Types != null
|
|
? TargetClass.GetMethod(TargetMethodName, Flags, null, Types, null)
|
|
: TargetClass.GetMethod(TargetMethodName, Flags);
|
|
if (!(methodInfo == null))
|
|
return methodInfo;
|
|
Log.Error("Unable to find patch method " + TargetClass.Name + "." + TargetMethodName);
|
|
return null;
|
|
}
|
|
}
|
|
} |