#nullable enable
using IPA.Loader.Features;
using IPA.Utilities;
using Mono.Cecil;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using Version = SemVer.Version;
#if NET3
using Net3_Proxy;
using Path = Net3_Proxy.Path;
#endif
namespace IPA.Loader
{
///
/// A class which describes a loaded plugin.
///
public class PluginMetadata
{
///
/// The assembly the plugin was loaded from.
///
/// the loaded Assembly that contains the plugin main type
public Assembly Assembly { get; internal set; } = null!;
///
/// The TypeDefinition for the main type of the plugin.
///
/// the Cecil definition for the plugin main type
public TypeDefinition? PluginType { get; internal set; }
///
/// The human readable name of the plugin.
///
/// the name of the plugin
public string Name => manifest.Name;
///
/// The ID of the plugin.
///
/// the ID of the plugin
public string Id => manifest.Id!; // by the time that this is publicly visible, it's always non-null
///
/// The name of the author that wrote this plugin.
///
/// the name of the plugin's author
public string Author => manifest.Author;
///
/// The description of this plugin.
///
/// the description of the plugin
public string Description => manifest.Description;
///
/// The version of the plugin.
///
/// the version of the plugin
public Version Version => manifest.Version;
///
/// The file the plugin was loaded from.
///
/// the file the plugin was loaded from
public FileInfo File { get; internal set; } = null!;
// ReSharper disable once UnusedAutoPropertyAccessor.Global
///
/// The features this plugin requests.
///
/// the list of features requested by the plugin
public IReadOnlyList Features => InternalFeatures;
internal readonly List InternalFeatures = new();
internal readonly HashSet UnloadedFeatures = new();
internal readonly List CreateFeaturesWhenLoaded = new();
///
/// A list of files (that aren't ) that are associated with this plugin.
///
/// a list of associated files
public IReadOnlyList AssociatedFiles { get; private set; } = new List();
///
/// The name of the resource in the plugin assembly containing the plugin's icon.
///
/// the name of the plugin's icon
public string? IconName => manifest.IconPath;
///
/// A link to this plugin's home page, if any.
///
/// the of the plugin's home page
public Uri? PluginHomeLink => manifest.Links?.ProjectHome;
///
/// A link to this plugin's source code, if avaliable.
///
/// the of the plugin's source code
public Uri? PluginSourceLink => manifest.Links?.ProjectSource;
///
/// A link to a donate page for the author of this plugin, if avaliable.
///
/// the of the author's donate page
public Uri? DonateLink => manifest.Links?.Donate;
internal bool IsSelf;
///
/// Whether or not this metadata object represents a bare manifest.
///
/// if it is bare, otherwise
public bool IsBare { get; internal set; }
private PluginManifest manifest = null!;
internal HashSet Dependencies { get; } = new();
internal HashSet LoadsAfter { get; } = new();
internal PluginManifest Manifest
{
get => manifest;
set
{
manifest = value;
AssociatedFiles = value.Files
.Select(f => Path.Combine(UnityGame.InstallPath, f))
.Select(p => new FileInfo(p)).ToList();
}
}
///
/// The that the plugin specified in its .
///
public RuntimeOptions RuntimeOptions { get; internal set; }
///
/// Gets all of the metadata as a readable string.
///
/// the readable printable metadata string
public override string ToString() => $"{Name}({Id}@{Version})({PluginType?.FullName}) from '{Utils.GetRelativePath(File?.FullName ?? "", UnityGame.InstallPath)}'";
}
}