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.

148 lines
5.5 KiB

4 years ago
  1. #nullable enable
  2. using IPA.Loader.Features;
  3. using IPA.Utilities;
  4. using Mono.Cecil;
  5. using System;
  6. using System.Collections.Generic;
  7. using System.IO;
  8. using System.Linq;
  9. using System.Reflection;
  10. using Version = SemVer.Version;
  11. #if NET3
  12. using Net3_Proxy;
  13. using Path = Net3_Proxy.Path;
  14. #endif
  15. namespace IPA.Loader
  16. {
  17. /// <summary>
  18. /// A class which describes a loaded plugin.
  19. /// </summary>
  20. public class PluginMetadata
  21. {
  22. /// <summary>
  23. /// The assembly the plugin was loaded from.
  24. /// </summary>
  25. /// <value>the loaded Assembly that contains the plugin main type</value>
  26. public Assembly Assembly { get; internal set; } = null!;
  27. /// <summary>
  28. /// The TypeDefinition for the main type of the plugin.
  29. /// </summary>
  30. /// <value>the Cecil definition for the plugin main type</value>
  31. public TypeDefinition? PluginType { get; internal set; }
  32. /// <summary>
  33. /// The human readable name of the plugin.
  34. /// </summary>
  35. /// <value>the name of the plugin</value>
  36. public string Name => manifest.Name;
  37. /// <summary>
  38. /// The ID of the plugin.
  39. /// </summary>
  40. /// <value>the ID of the plugin</value>
  41. public string Id => manifest.Id!; // by the time that this is publicly visible, it's always non-null
  42. /// <summary>
  43. /// The name of the author that wrote this plugin.
  44. /// </summary>
  45. /// <value>the name of the plugin's author</value>
  46. public string Author => manifest.Author;
  47. /// <summary>
  48. /// The description of this plugin.
  49. /// </summary>
  50. /// <value>the description of the plugin</value>
  51. public string Description => manifest.Description;
  52. /// <summary>
  53. /// The version of the plugin.
  54. /// </summary>
  55. /// <value>the version of the plugin</value>
  56. public Version Version => manifest.Version;
  57. /// <summary>
  58. /// The file the plugin was loaded from.
  59. /// </summary>
  60. /// <value>the file the plugin was loaded from</value>
  61. public FileInfo File { get; internal set; } = null!;
  62. // ReSharper disable once UnusedAutoPropertyAccessor.Global
  63. /// <summary>
  64. /// The features this plugin requests.
  65. /// </summary>
  66. /// <value>the list of features requested by the plugin</value>
  67. public IReadOnlyList<Feature> Features => InternalFeatures;
  68. internal readonly List<Feature> InternalFeatures = new();
  69. internal readonly HashSet<Feature.Instance> UnloadedFeatures = new();
  70. internal readonly List<Feature.Instance> CreateFeaturesWhenLoaded = new();
  71. /// <summary>
  72. /// A list of files (that aren't <see cref="File"/>) that are associated with this plugin.
  73. /// </summary>
  74. /// <value>a list of associated files</value>
  75. public IReadOnlyList<FileInfo> AssociatedFiles { get; private set; } = new List<FileInfo>();
  76. /// <summary>
  77. /// The name of the resource in the plugin assembly containing the plugin's icon.
  78. /// </summary>
  79. /// <value>the name of the plugin's icon</value>
  80. public string? IconName => manifest.IconPath;
  81. /// <summary>
  82. /// A link to this plugin's home page, if any.
  83. /// </summary>
  84. /// <value>the <see cref="Uri"/> of the plugin's home page</value>
  85. public Uri? PluginHomeLink => manifest.Links?.ProjectHome;
  86. /// <summary>
  87. /// A link to this plugin's source code, if avaliable.
  88. /// </summary>
  89. /// <value>the <see cref="Uri"/> of the plugin's source code</value>
  90. public Uri? PluginSourceLink => manifest.Links?.ProjectSource;
  91. /// <summary>
  92. /// A link to a donate page for the author of this plugin, if avaliable.
  93. /// </summary>
  94. /// <value>the <see cref="Uri"/> of the author's donate page</value>
  95. public Uri? DonateLink => manifest.Links?.Donate;
  96. internal bool IsSelf;
  97. /// <summary>
  98. /// Whether or not this metadata object represents a bare manifest.
  99. /// </summary>
  100. /// <value><see langword="true"/> if it is bare, <see langword="false"/> otherwise</value>
  101. public bool IsBare { get; internal set; }
  102. private PluginManifest manifest = null!;
  103. internal HashSet<PluginMetadata> Dependencies { get; } = new();
  104. internal HashSet<PluginMetadata> LoadsAfter { get; } = new();
  105. internal PluginManifest Manifest
  106. {
  107. get => manifest;
  108. set
  109. {
  110. manifest = value;
  111. AssociatedFiles = value.Files
  112. .Select(f => Path.Combine(UnityGame.InstallPath, f))
  113. .Select(p => new FileInfo(p)).ToList();
  114. }
  115. }
  116. /// <summary>
  117. /// The <see cref="IPA.RuntimeOptions"/> that the plugin specified in its <see cref="PluginAttribute"/>.
  118. /// </summary>
  119. public RuntimeOptions RuntimeOptions { get; internal set; }
  120. /// <summary>
  121. /// Gets all of the metadata as a readable string.
  122. /// </summary>
  123. /// <returns>the readable printable metadata string</returns>
  124. public override string ToString() => $"{Name}({Id}@{Version})({PluginType?.FullName}) from '{Utils.GetRelativePath(File?.FullName ?? "", UnityGame.InstallPath)}'";
  125. }
  126. }