99 lines
3.0 KiB
C#
99 lines
3.0 KiB
C#
using HarmonyLib;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Reflection;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace astealz.SmartSpawnController.Utils
|
|
{
|
|
public abstract class GenericPatch<T> where T : GenericPatch<T>
|
|
{
|
|
private Harmony _harmony;
|
|
private HarmonyMethod _prefix;
|
|
private HarmonyMethod _postfix;
|
|
private HarmonyMethod _transpiler;
|
|
private HarmonyMethod _finalizer;
|
|
|
|
public GenericPatch(string name = null, string prefix = null, string postfix = null, string transpiler = null, string finalizer = null)
|
|
{
|
|
_harmony = new Harmony(name ?? typeof(T).Name);
|
|
_prefix = GetPatchMethod(prefix);
|
|
_postfix = GetPatchMethod(postfix);
|
|
_transpiler = GetPatchMethod(transpiler);
|
|
_finalizer = GetPatchMethod(finalizer);
|
|
|
|
if (_prefix == null && _postfix == null && _transpiler == null && _finalizer == null)
|
|
{
|
|
throw new Exception($"{_harmony.Id}: At least one of the patch methods must be specified");
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get original method
|
|
/// </summary>
|
|
/// <returns>Method</returns>
|
|
protected abstract MethodBase GetTargetMethod();
|
|
|
|
/// <summary>
|
|
/// Get MethodInfo from string
|
|
/// </summary>
|
|
/// <param name="methodName">Method name</param>
|
|
/// <returns>Method</returns>
|
|
private HarmonyMethod GetPatchMethod(string methodName)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(methodName))
|
|
{
|
|
return null;
|
|
}
|
|
|
|
return new HarmonyMethod(typeof(T).GetMethod(methodName, BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.DeclaredOnly));
|
|
}
|
|
|
|
/// <summary>
|
|
/// Apply patch to target
|
|
/// </summary>
|
|
public void Apply()
|
|
{
|
|
var targetMethod = GetTargetMethod();
|
|
|
|
if (targetMethod == null)
|
|
{
|
|
throw new InvalidOperationException($"{_harmony.Id}: TargetMethod is null");
|
|
}
|
|
|
|
try
|
|
{
|
|
_harmony.Patch(targetMethod, _prefix, _postfix, _transpiler, _finalizer);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
throw new Exception($"{_harmony.Id}:", ex);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Remove applied patch from target
|
|
/// </summary>
|
|
public void Remove()
|
|
{
|
|
var targetMethod = GetTargetMethod();
|
|
|
|
if (targetMethod == null)
|
|
{
|
|
throw new InvalidOperationException($"{_harmony.Id}: TargetMethod is null");
|
|
}
|
|
|
|
try
|
|
{
|
|
_harmony.Unpatch(targetMethod, HarmonyPatchType.All, _harmony.Id);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
throw new Exception($"{_harmony.Id}:", ex);
|
|
}
|
|
}
|
|
}
|
|
}
|