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.

103 lines
3.1 KiB

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