HarmonyInstanceExtensions.cs 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Reflection;
  5. using System.Text;
  6. using Harmony;
  7. using XUnity.AutoTranslator.Plugin.Core.Constants;
  8. namespace XUnity.AutoTranslator.Plugin.Core.Extensions
  9. {
  10. internal static class HarmonyInstanceExtensions
  11. {
  12. public static readonly MethodInfo PatchMethod = ClrTypes.HarmonyInstance.GetMethod( "Patch", new Type[] { ClrTypes.MethodBase, ClrTypes.HarmonyMethod, ClrTypes.HarmonyMethod, ClrTypes.HarmonyMethod } );
  13. public static void PatchAll( this HarmonyInstance instance, IEnumerable<Type> types )
  14. {
  15. foreach( var type in types )
  16. {
  17. instance.PatchType( type );
  18. }
  19. }
  20. public static void PatchType( this HarmonyInstance instance, Type type )
  21. {
  22. try
  23. {
  24. var prepare = type.GetMethod( "Prepare", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public );
  25. if( prepare == null || (bool)prepare.Invoke( null, new object[] { instance } ) )
  26. {
  27. var original = (MethodBase)type.GetMethod( "TargetMethod", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public ).Invoke( null, new object[] { instance } );
  28. if( original != null )
  29. {
  30. var prefix = type.GetMethod( "Prefix", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public );
  31. var postfix = type.GetMethod( "Postfix", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public );
  32. var transpiler = type.GetMethod( "Transpiler", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public );
  33. var harmonyPrefix = prefix != null ? new HarmonyMethod( prefix ) : null;
  34. var harmonyPostfix = postfix != null ? new HarmonyMethod( postfix ) : null;
  35. var harmonyTranspiler = transpiler != null ? new HarmonyMethod( transpiler ) : null;
  36. PatchMethod.Invoke( instance, new object[] { original, harmonyPrefix, harmonyPostfix, harmonyTranspiler } );
  37. }
  38. else
  39. {
  40. XuaLogger.Current.Warn( $"Could not enable hook '{type.Name}'. Likely due differences between different versions of the engine or text framework." );
  41. }
  42. }
  43. }
  44. catch( Exception e )
  45. {
  46. XuaLogger.Current.Warn( e, "An error occurred while patching a property/method on a class. Failing class: " + type.Name );
  47. }
  48. }
  49. }
  50. }