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.1 KiB

  1. using IPA.Logging;
  2. using Newtonsoft.Json;
  3. using Newtonsoft.Json.Linq;
  4. using System;
  5. using System.IO;
  6. namespace IPA.Loader.Features
  7. {
  8. internal class DefineFeature : Feature
  9. {
  10. public static bool NewFeature = true;
  11. private class DataModel
  12. {
  13. [JsonProperty("type", Required = Required.Always)]
  14. public string TypeName;
  15. [JsonProperty("name", Required = Required.DisallowNull)]
  16. public string ActualName = null;
  17. public string Name => ActualName ?? TypeName;
  18. }
  19. private DataModel data;
  20. protected override bool Initialize(PluginMetadata meta, JObject featureData)
  21. {
  22. Logger.features.Debug("Executing DefineFeature Init");
  23. try
  24. {
  25. data = featureData.ToObject<DataModel>();
  26. }
  27. catch (Exception e)
  28. {
  29. InvalidMessage = $"Invalid data: {e}";
  30. return false;
  31. }
  32. InvalidMessage = $"Feature {data.Name} already exists";
  33. return PreregisterFeature(meta, data.Name);
  34. }
  35. public override void AfterInit(PluginMetadata meta, object pluginInstance)
  36. {
  37. Logger.features.Debug("Executing DefineFeature AfterInit");
  38. Type type;
  39. try
  40. {
  41. type = meta.Assembly.GetType(data.TypeName);
  42. }
  43. catch (ArgumentException)
  44. {
  45. Logger.features.Error($"Invalid type name {data.TypeName}");
  46. return;
  47. }
  48. catch (Exception e) when (e is FileNotFoundException || e is FileLoadException || e is BadImageFormatException)
  49. {
  50. var filename = "";
  51. switch (e)
  52. {
  53. case FileNotFoundException fn:
  54. filename = fn.FileName;
  55. break;
  56. case FileLoadException fl:
  57. filename = fl.FileName;
  58. break;
  59. case BadImageFormatException bi:
  60. filename = bi.FileName;
  61. break;
  62. }
  63. Logger.features.Error($"Could not find {filename} while loading type");
  64. return;
  65. }
  66. if (type == null)
  67. {
  68. Logger.features.Error($"Invalid type name {data.TypeName}");
  69. return;
  70. }
  71. try
  72. {
  73. if (RegisterFeature(meta, data.Name, type))
  74. {
  75. NewFeature = true;
  76. return;
  77. }
  78. Logger.features.Error($"Feature with name {data.Name} already exists");
  79. return;
  80. }
  81. catch (ArgumentException)
  82. {
  83. Logger.features.Error($"{type.FullName} not a subclass of {nameof(Feature)}");
  84. return;
  85. }
  86. }
  87. }
  88. }