Patcher.cs 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using System.Linq;
  5. using System.Reflection;
  6. using System.Text;
  7. using Mono.Cecil;
  8. using Mono.Cecil.Inject;
  9. using ReiPatcher;
  10. using ReiPatcher.Patch;
  11. namespace XUnity.AutoTranslator.Patcher
  12. {
  13. public class Patcher : PatchBase
  14. {
  15. private static readonly HashSet<string> EntryClasses = new HashSet<string> { "Display", "Input" };
  16. private AssemblyDefinition _hookAssembly;
  17. private string _assemblyName;
  18. public override string Name
  19. {
  20. get
  21. {
  22. return "Auto Translator";
  23. }
  24. }
  25. public override string Version
  26. {
  27. get
  28. {
  29. return "3.0.1";
  30. }
  31. }
  32. public override void PrePatch()
  33. {
  34. if( ManagedDllExists( "UnityEngine.CoreModule.dll" ) )
  35. {
  36. RPConfig.RequestAssembly( "UnityEngine.CoreModule.dll" );
  37. _assemblyName = "UnityEngine.CoreModule";
  38. }
  39. else if( ManagedDllExists( "UnityEngine.dll" ) )
  40. {
  41. RPConfig.RequestAssembly( "UnityEngine.dll" );
  42. _assemblyName = "UnityEngine";
  43. }
  44. _hookAssembly = LoadAssembly( "XUnity.AutoTranslator.Plugin.Core.dll" );
  45. }
  46. public override bool CanPatch( PatcherArguments args )
  47. {
  48. return ( args.Assembly.Name.Name == _assemblyName ) && !HasAttribute( this, args.Assembly, "XUnity.AutoTranslator.Plugin.Core" );
  49. }
  50. public override void Patch( PatcherArguments args )
  51. {
  52. var PluginLoader = _hookAssembly.MainModule.GetType( "XUnity.AutoTranslator.Plugin.Core.PluginLoader" );
  53. var LoadThroughBootstrapper = PluginLoader.GetMethod( "LoadThroughBootstrapper" );
  54. var entryClasses = args.Assembly.MainModule.GetTypes().Where( x => EntryClasses.Contains( x.Name ) ).ToList();
  55. foreach( var entryClass in entryClasses )
  56. {
  57. var staticCtor = entryClass.Methods.FirstOrDefault( x => x.IsStatic && x.IsConstructor );
  58. if( staticCtor != null )
  59. {
  60. var injecctor = new InjectionDefinition( staticCtor, LoadThroughBootstrapper, InjectFlags.None );
  61. injecctor.Inject(
  62. startCode: 0,
  63. direction: InjectDirection.Before );
  64. }
  65. }
  66. SetPatchedAttribute( args.Assembly, "XUnity.AutoTranslator.Plugin.Core" );
  67. }
  68. public bool ManagedDllExists( string name )
  69. {
  70. string path = Path.Combine( RPConfig.ConfigFile.GetSection( "ReiPatcher" ).GetKey( "AssembliesDir" ).Value, name );
  71. return File.Exists( path );
  72. }
  73. public static AssemblyDefinition LoadAssembly( string name )
  74. {
  75. string path = Path.Combine( RPConfig.ConfigFile.GetSection( "ReiPatcher" ).GetKey( "AssembliesDir" ).Value, name );
  76. if( !File.Exists( path ) ) throw new FileNotFoundException( "Missing DLL: " + path );
  77. using( Stream s = File.OpenRead( path ) )
  78. {
  79. return AssemblyDefinition.ReadAssembly( s );
  80. }
  81. }
  82. public static bool HasAttribute( PatchBase patch, AssemblyDefinition assembly, string attribute )
  83. {
  84. return patch.GetPatchedAttributes( assembly ).Any( a => a.Info == attribute );
  85. }
  86. }
  87. }