123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210 |
- using System;
- using System.Collections.Generic;
- using System.Linq;
- namespace BepInEx
- {
- #region BaseUnityPlugin
- /// <summary>
- /// This attribute denotes that a class is a plugin, and specifies the required metadata.
- /// </summary>
- [AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
- public class BepInPlugin : Attribute
- {
- /// <summary>
- /// The unique identifier of the plugin. Should not change between plugin versions.
- /// </summary>
- public string GUID { get; protected set; }
- /// <summary>
- /// The user friendly name of the plugin. Is able to be changed between versions.
- /// </summary>
- public string Name { get; protected set; }
- /// <summary>
- /// The specfic version of the plugin.
- /// </summary>
- public Version Version { get; protected set; }
- /// <param name="GUID">The unique identifier of the plugin. Should not change between plugin versions.</param>
- /// <param name="Name">The user friendly name of the plugin. Is able to be changed between versions.</param>
- /// <param name="Version">The specfic version of the plugin.</param>
- public BepInPlugin(string GUID, string Name, string Version)
- {
- this.GUID = GUID;
- this.Name = Name;
- this.Version = new Version(Version);
- }
- }
- /// <summary>
- /// This attribute specifies any dependencies that this plugin has on other plugins.
- /// </summary>
- [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
- public class BepInDependency : Attribute
- {
- public enum DependencyFlags
- {
- /// <summary>
- /// The plugin has a hard dependency on the referenced plugin, and will not run without it.
- /// </summary>
- HardDependency = 1,
- /// <summary>
- /// This plugin has a soft dependency on the referenced plugin, and is able to run without it.
- /// </summary>
- SoftDependency = 2,
- }
- /// <summary>
- /// The GUID of the referenced plugin.
- /// </summary>
- public string DependencyGUID { get; protected set; }
- /// <summary>
- /// The flags associated with this dependency definition.
- /// </summary>
- public DependencyFlags Flags { get; protected set; }
- /// <param name="DependencyGUID">The GUID of the referenced plugin.</param>
- /// <param name="Flags">The flags associated with this dependency definition.</param>
- public BepInDependency(string DependencyGUID, DependencyFlags Flags = DependencyFlags.HardDependency)
- {
- this.DependencyGUID = DependencyGUID;
- this.Flags = Flags;
- }
- }
- /// <summary>
- /// This attribute specifies which processes this plugin should be run for. Not specifying this attribute will load the plugin under every process.
- /// </summary>
- [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
- public class BepInProcess : Attribute
- {
- /// <summary>
- /// The name of the process that this plugin will run under.
- /// </summary>
- public string ProcessName { get; protected set; }
- /// <param name="ProcessName">The name of the process that this plugin will run under.</param>
- public BepInProcess(string ProcessName)
- {
- this.ProcessName = ProcessName;
- }
- }
- #endregion
- #region MetadataHelper
- /// <summary>
- /// Helper class to use for retrieving metadata about a plugin, defined as attributes.
- /// </summary>
- public static class MetadataHelper
- {
- /// <summary>
- /// Retrieves the BepInPlugin metadata from a plugin type.
- /// </summary>
- /// <param name="plugin">The plugin type.</param>
- /// <returns>The BepInPlugin metadata of the plugin type.</returns>
- public static BepInPlugin GetMetadata(Type pluginType)
- {
- object[] attributes = pluginType.GetCustomAttributes(typeof(BepInPlugin), false);
- if (attributes.Length == 0)
- return null;
- return (BepInPlugin)attributes[0];
- }
- /// <summary>
- /// Retrieves the BepInPlugin metadata from a plugin instance.
- /// </summary>
- /// <param name="plugin">The plugin instance.</param>
- /// <returns>The BepInPlugin metadata of the plugin instance.</returns>
- public static BepInPlugin GetMetadata(object plugin)
- => GetMetadata(plugin.GetType());
- /// <summary>
- /// Gets the specified attributes of a type, if they exist.
- /// </summary>
- /// <typeparam name="T">The attribute type to retrieve.</typeparam>
- /// <param name="plugin">The plugin type.</param>
- /// <returns>The attributes of the type, if existing.</returns>
- public static T[] GetAttributes<T>(Type pluginType) where T : Attribute
- {
- return (T[])pluginType.GetCustomAttributes(typeof(T), true);
- }
- /// <summary>
- /// Gets the specified attributes of an instance, if they exist.
- /// </summary>
- /// <typeparam name="T">The attribute type to retrieve.</typeparam>
- /// <param name="plugin">The plugin instance.</param>
- /// <returns>The attributes of the instance, if existing.</returns>
- public static IEnumerable<T> GetAttributes<T>(object plugin) where T : Attribute
- => GetAttributes<T>(plugin.GetType());
- /// <summary>
- /// Retrieves the dependencies of the specified plugin type.
- /// </summary>
- /// <param name="Plugin">The plugin type.</param>
- /// <param name="AllPlugins">All currently loaded plugin types.</param>
- /// <returns>A list of all plugin types that the specified plugin type depends upon.</returns>
- public static IEnumerable<Type> GetDependencies(Type Plugin, IEnumerable<Type> AllPlugins)
- {
- object[] attributes = Plugin.GetCustomAttributes(typeof(BepInDependency), true);
- List<Type> dependencyTypes = new List<Type>();
- foreach (BepInDependency dependency in attributes)
- {
- Type dependencyType = AllPlugins.FirstOrDefault(x => GetMetadata(x)?.GUID == dependency.DependencyGUID);
- if (dependencyType == null)
- {
- if ((dependency.Flags & BepInDependency.DependencyFlags.SoftDependency) != 0)
- continue; //skip on soft dependencies
- throw new MissingDependencyException("Cannot find dependency type.");
- }
- dependencyTypes.Add(dependencyType);
- }
- return dependencyTypes;
- }
- }
- /// <summary>
- /// An exception which is thrown when a plugin's dependencies cannot be found.
- /// </summary>
- public class MissingDependencyException : Exception
- {
- public MissingDependencyException(string message) : base(message) { }
- }
- #endregion
- #region Build configuration
- /// <summary>
- /// This class is appended to AssemblyInfo.cs when BepInEx is built via a CI pipeline.
- /// It is mainly intended to signify that the current build is not a release build and is special, like for instance a bleeding edge build.
- /// </summary>
- internal class BuildInfoAttribute : Attribute
- {
- public string Info { get; }
- public BuildInfoAttribute(string info)
- {
- Info = info;
- }
- }
- #endregion
- }
|