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.

102 lines
3.5 KiB

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