You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

105 lines
3.6 KiB

  1. using System;
  2. using System.IO;
  3. using System.Reflection;
  4. #if NET3
  5. using Array = Net3_Proxy.Array;
  6. #endif
  7. namespace IPA.Loader.Features
  8. {
  9. internal class InitInjectorFeature : Feature
  10. {
  11. protected internal override bool StoreOnPlugin => false;
  12. public override bool Initialize(PluginMetadata meta, string[] parameters)
  13. { // parameters should be (assembly qualified lookup type, [fully qualified type]:[method name])
  14. // method should be static
  15. if (parameters.Length != 2)
  16. {
  17. InvalidMessage = "Incorrect number of parameters";
  18. return false;
  19. }
  20. RequireLoaded(meta);
  21. var methodParts = parameters[1].Split(':');
  22. var type = Type.GetType(parameters[0], false);
  23. if (type == null)
  24. {
  25. InvalidMessage = $"Could not find type {parameters[0]}";
  26. return false;
  27. }
  28. Type getType;
  29. try
  30. {
  31. getType = meta.Assembly.GetType(methodParts[0]);
  32. }
  33. catch (ArgumentException)
  34. {
  35. InvalidMessage = $"Invalid type name {methodParts[0]}";
  36. return false;
  37. }
  38. catch (Exception e) when (e is FileNotFoundException || e is FileLoadException || e is BadImageFormatException)
  39. {
  40. string filename;
  41. switch (e)
  42. {
  43. case FileNotFoundException fn:
  44. filename = fn.FileName;
  45. goto hasFilename;
  46. case FileLoadException fl:
  47. filename = fl.FileName;
  48. goto hasFilename;
  49. case BadImageFormatException bi:
  50. filename = bi.FileName;
  51. hasFilename:
  52. InvalidMessage = $"Could not find {filename} while loading type";
  53. break;
  54. default:
  55. InvalidMessage = $"Error while loading type: {e}";
  56. break;
  57. }
  58. return false;
  59. }
  60. MethodInfo method;
  61. try
  62. {
  63. method = getType.GetMethod(methodParts[1], BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic,
  64. null, new[]
  65. {
  66. typeof(object),
  67. typeof(ParameterInfo),
  68. typeof(PluginMetadata)
  69. }, Array.Empty<ParameterModifier>());
  70. }
  71. catch (Exception e)
  72. {
  73. InvalidMessage = $"Error while loading type: {e}";
  74. return false;
  75. }
  76. if (method == null)
  77. {
  78. InvalidMessage = $"Could not find method {methodParts[1]} in type {methodParts[0]}";
  79. return false;
  80. }
  81. try
  82. {
  83. var del = (PluginInitInjector.InjectParameter)Delegate.CreateDelegate(typeof(PluginInitInjector.InjectParameter), null, method);
  84. PluginInitInjector.AddInjector(type, del);
  85. return true;
  86. }
  87. catch (Exception e)
  88. {
  89. InvalidMessage = $"Error generated while creating delegate: {e}";
  90. return false;
  91. }
  92. }
  93. }
  94. }