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.

147 lines
5.5 KiB

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