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.

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