Skip to content

Commit

Permalink
Merge pull request #84 from amazingalek/raicuparta/patch-via-methodinfo
Browse files Browse the repository at this point in the history
Allow patching by providing MethodInfo
  • Loading branch information
Raicuparta authored Mar 14, 2020
2 parents 641303b + 1651797 commit e4ebb85
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 26 deletions.
5 changes: 5 additions & 0 deletions OWML.Common/IHarmonyHelper.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
using System;
using System.Reflection;

namespace OWML.Common
{
public interface IHarmonyHelper
{
void AddPrefix<T>(string methodName, Type patchType, string patchMethodName);
void AddPrefix(MethodInfo methodInfo, Type patchType, string patchMethodName);
void AddPostfix<T>(string methodName, Type patchType, string patchMethodName);
void AddPostfix(MethodInfo methodInfo, Type patchType, string patchMethodName);
void EmptyMethod<T>(string methodName);
void EmptyMethod(MethodInfo methodInfo);
void Transpile<T>(string methodName, Type patchType, string patchMethodName);
void Transpile(MethodInfo methodInfo, Type patchType, string patchMethodName);
}
}
2 changes: 1 addition & 1 deletion OWML.Launcher/App.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ namespace OWML.Launcher
{
public class App
{
private const string Version = "0.3.39";
private const string Version = "0.3.40";

private readonly IOwmlConfig _owmlConfig;
private readonly IModConsole _writer;
Expand Down
72 changes: 47 additions & 25 deletions OWML.ModHelper.Events/HarmonyHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,76 +39,98 @@ private HarmonyInstance CreateInstance()
return harmony;
}

private MethodInfo GetMethod<T>(string methodName)
{
var targetType = typeof(T);
try
{
_logger.Log($"Getting method {methodName} of {targetType.Name}");
return targetType.GetAnyMethod(methodName);
}
catch (Exception ex)
{
_console.WriteLine($"Exception while getting method {methodName} of {targetType.Name}: {ex}");
return null;
}
}

public void AddPrefix<T>(string methodName, Type patchType, string patchMethodName)
{
AddPrefix(GetMethod<T>(methodName), patchType, patchMethodName);
}

public void AddPrefix(MethodInfo original, Type patchType, string patchMethodName)
{
var prefix = patchType.GetAnyMethod(patchMethodName);
if (prefix == null)
{
_console.WriteLine($"Error in {nameof(AddPrefix)}: {typeof(T).Name}.{methodName} is null");
_console.WriteLine($"Error in {nameof(AddPrefix)}: {patchType.Name}.{patchMethodName} is null");
return;
}
Patch<T>(methodName, prefix, null, null);
Patch(original, prefix, null, null);
}

public void AddPostfix<T>(string methodName, Type patchType, string patchMethodName)
{
AddPostfix(GetMethod<T>(methodName), patchType, patchMethodName);
}

public void AddPostfix(MethodInfo original, Type patchType, string patchMethodName)
{
var postfix = patchType.GetAnyMethod(patchMethodName);
if (postfix == null)
{
_console.WriteLine($"Error in {nameof(AddPostfix)}: {typeof(T).Name}.{methodName} is null");
_console.WriteLine($"Error in {nameof(AddPostfix)}: {patchType.Name}.{patchMethodName} is null");
return;
}
Patch<T>(methodName, null, postfix, null);
Patch(original, null, postfix, null);
}

public void EmptyMethod<T>(string methodName)
{
Transpile<T>(methodName, typeof(Patches), nameof(Patches.EmptyMethod));
EmptyMethod(GetMethod<T>(methodName));
}

public void EmptyMethod(MethodInfo methodInfo)
{
Transpile(methodInfo, typeof(Patches), nameof(Patches.EmptyMethod));
}

public void Transpile<T>(string methodName, Type patchType, string patchMethodName)
{
Transpile(GetMethod<T>(methodName), patchType, patchMethodName);
}

public void Transpile(MethodInfo original, Type patchType, string patchMethodName)
{
var patchMethod = patchType.GetAnyMethod(patchMethodName);
if (patchMethod == null)
{
_console.WriteLine($"Error in {nameof(Transpile)}: {typeof(T).Name}.{methodName} is null");
_console.WriteLine($"Error in {nameof(Transpile)}: {patchType.Name}.{patchMethodName} is null");
return;
}
Patch<T>(methodName, null, null, patchMethod);
Patch(original, null, null, patchMethod);
}

private void Patch<T>(string methodName, MethodInfo prefix, MethodInfo postfix, MethodInfo transpiler)
private void Patch(MethodInfo original, MethodInfo prefix, MethodInfo postfix, MethodInfo transpiler)
{
var targetType = typeof(T);
_logger.Log("Trying to patch " + targetType.Name);
MethodInfo original;
try
{
_logger.Log($"Getting method {methodName} of {targetType.Name}");
original = targetType.GetAnyMethod(methodName);
_logger.Log($"Got method {methodName} of {targetType.Name}");
}
catch (Exception ex)
{
_console.WriteLine($"Exception while getting method {methodName} of {targetType.Name}: {ex}");
return;
}
if (original == null)
{
_console.WriteLine($"Error in {nameof(Patch)}: {targetType.Name}.{methodName} is null");
_console.WriteLine($"Error in {nameof(Patch)}: original MethodInfo is null");
return;
}
var prefixMethod = prefix == null ? null : new HarmonyMethod(prefix);
var postfixMethod = postfix == null ? null : new HarmonyMethod(postfix);
var transpilerMethod = transpiler == null ? null : new HarmonyMethod(transpiler);
var fullName = $"{original.DeclaringType}.{original.Name}";
try
{
_harmony.Patch(original, prefixMethod, postfixMethod, transpilerMethod);
_logger.Log($"Patched {targetType.Name}!");
_logger.Log($"Patched {fullName}!");
}
catch (Exception ex)
{
_console.WriteLine($"Exception while patching {targetType.Name}.{methodName}: {ex}");
_console.WriteLine($"Exception while patching {fullName}: {ex}");
}
}

Expand Down

0 comments on commit e4ebb85

Please sign in to comment.