Files
QuartZ-dump/GlobalTorch/Patches/Patcher.cs
2024-12-29 21:15:58 +01:00

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;
}
}
}