mirror of
https://github.com/goatcorp/Dalamud.git
synced 2026-01-03 06:13:40 +01:00
Revert "refactor(Dalamud): switch to file-scoped namespaces"
This reverts commit b5f34c3199.
This commit is contained in:
parent
d473826247
commit
1561fbac00
325 changed files with 45549 additions and 45209 deletions
|
|
@ -20,385 +20,386 @@ using Dalamud.Plugin.Ipc;
|
|||
using Dalamud.Plugin.Ipc.Exceptions;
|
||||
using Dalamud.Plugin.Ipc.Internal;
|
||||
|
||||
namespace Dalamud.Plugin;
|
||||
|
||||
/// <summary>
|
||||
/// This class acts as an interface to various objects needed to interact with Dalamud and the game.
|
||||
/// </summary>
|
||||
public sealed class DalamudPluginInterface : IDisposable
|
||||
namespace Dalamud.Plugin
|
||||
{
|
||||
private readonly string pluginName;
|
||||
private readonly PluginConfigurations configs;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="DalamudPluginInterface"/> class.
|
||||
/// Set up the interface and populate all fields needed.
|
||||
/// This class acts as an interface to various objects needed to interact with Dalamud and the game.
|
||||
/// </summary>
|
||||
/// <param name="pluginName">The internal name of the plugin.</param>
|
||||
/// <param name="assemblyLocation">Location of the assembly.</param>
|
||||
/// <param name="reason">The reason the plugin was loaded.</param>
|
||||
/// <param name="isDev">A value indicating whether this is a dev plugin.</param>
|
||||
internal DalamudPluginInterface(string pluginName, FileInfo assemblyLocation, PluginLoadReason reason, bool isDev)
|
||||
public sealed class DalamudPluginInterface : IDisposable
|
||||
{
|
||||
var configuration = Service<DalamudConfiguration>.Get();
|
||||
var dataManager = Service<DataManager>.Get();
|
||||
var localization = Service<Localization>.Get();
|
||||
private readonly string pluginName;
|
||||
private readonly PluginConfigurations configs;
|
||||
|
||||
this.UiBuilder = new UiBuilder(pluginName);
|
||||
|
||||
this.pluginName = pluginName;
|
||||
this.AssemblyLocation = assemblyLocation;
|
||||
this.configs = Service<PluginManager>.Get().PluginConfigs;
|
||||
this.Reason = reason;
|
||||
this.IsDev = isDev;
|
||||
|
||||
this.LoadTime = DateTime.Now;
|
||||
this.LoadTimeUTC = DateTime.UtcNow;
|
||||
|
||||
this.GeneralChatType = configuration.GeneralChatType;
|
||||
this.Sanitizer = new Sanitizer(dataManager.Language);
|
||||
if (configuration.LanguageOverride != null)
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="DalamudPluginInterface"/> class.
|
||||
/// Set up the interface and populate all fields needed.
|
||||
/// </summary>
|
||||
/// <param name="pluginName">The internal name of the plugin.</param>
|
||||
/// <param name="assemblyLocation">Location of the assembly.</param>
|
||||
/// <param name="reason">The reason the plugin was loaded.</param>
|
||||
/// <param name="isDev">A value indicating whether this is a dev plugin.</param>
|
||||
internal DalamudPluginInterface(string pluginName, FileInfo assemblyLocation, PluginLoadReason reason, bool isDev)
|
||||
{
|
||||
this.UiLanguage = configuration.LanguageOverride;
|
||||
}
|
||||
else
|
||||
{
|
||||
var currentUiLang = CultureInfo.CurrentUICulture;
|
||||
if (Localization.ApplicableLangCodes.Any(langCode => currentUiLang.TwoLetterISOLanguageName == langCode))
|
||||
this.UiLanguage = currentUiLang.TwoLetterISOLanguageName;
|
||||
var configuration = Service<DalamudConfiguration>.Get();
|
||||
var dataManager = Service<DataManager>.Get();
|
||||
var localization = Service<Localization>.Get();
|
||||
|
||||
this.UiBuilder = new UiBuilder(pluginName);
|
||||
|
||||
this.pluginName = pluginName;
|
||||
this.AssemblyLocation = assemblyLocation;
|
||||
this.configs = Service<PluginManager>.Get().PluginConfigs;
|
||||
this.Reason = reason;
|
||||
this.IsDev = isDev;
|
||||
|
||||
this.LoadTime = DateTime.Now;
|
||||
this.LoadTimeUTC = DateTime.UtcNow;
|
||||
|
||||
this.GeneralChatType = configuration.GeneralChatType;
|
||||
this.Sanitizer = new Sanitizer(dataManager.Language);
|
||||
if (configuration.LanguageOverride != null)
|
||||
{
|
||||
this.UiLanguage = configuration.LanguageOverride;
|
||||
}
|
||||
else
|
||||
this.UiLanguage = "en";
|
||||
{
|
||||
var currentUiLang = CultureInfo.CurrentUICulture;
|
||||
if (Localization.ApplicableLangCodes.Any(langCode => currentUiLang.TwoLetterISOLanguageName == langCode))
|
||||
this.UiLanguage = currentUiLang.TwoLetterISOLanguageName;
|
||||
else
|
||||
this.UiLanguage = "en";
|
||||
}
|
||||
|
||||
localization.LocalizationChanged += this.OnLocalizationChanged;
|
||||
configuration.DalamudConfigurationSaved += this.OnDalamudConfigurationSaved;
|
||||
}
|
||||
|
||||
localization.LocalizationChanged += this.OnLocalizationChanged;
|
||||
configuration.DalamudConfigurationSaved += this.OnDalamudConfigurationSaved;
|
||||
}
|
||||
/// <summary>
|
||||
/// Delegate for localization change with two-letter iso lang code.
|
||||
/// </summary>
|
||||
/// <param name="langCode">The new language code.</param>
|
||||
public delegate void LanguageChangedDelegate(string langCode);
|
||||
|
||||
/// <summary>
|
||||
/// Delegate for localization change with two-letter iso lang code.
|
||||
/// </summary>
|
||||
/// <param name="langCode">The new language code.</param>
|
||||
public delegate void LanguageChangedDelegate(string langCode);
|
||||
/// <summary>
|
||||
/// Event that gets fired when loc is changed
|
||||
/// </summary>
|
||||
public event LanguageChangedDelegate LanguageChanged;
|
||||
|
||||
/// <summary>
|
||||
/// Event that gets fired when loc is changed
|
||||
/// </summary>
|
||||
public event LanguageChangedDelegate LanguageChanged;
|
||||
/// <summary>
|
||||
/// Gets the reason this plugin was loaded.
|
||||
/// </summary>
|
||||
public PluginLoadReason Reason { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the reason this plugin was loaded.
|
||||
/// </summary>
|
||||
public PluginLoadReason Reason { get; }
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this is a dev plugin.
|
||||
/// </summary>
|
||||
public bool IsDev { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this is a dev plugin.
|
||||
/// </summary>
|
||||
public bool IsDev { get; }
|
||||
/// <summary>
|
||||
/// Gets the time that this plugin was loaded.
|
||||
/// </summary>
|
||||
public DateTime LoadTime { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the time that this plugin was loaded.
|
||||
/// </summary>
|
||||
public DateTime LoadTime { get; }
|
||||
/// <summary>
|
||||
/// Gets the UTC time that this plugin was loaded.
|
||||
/// </summary>
|
||||
public DateTime LoadTimeUTC { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the UTC time that this plugin was loaded.
|
||||
/// </summary>
|
||||
public DateTime LoadTimeUTC { get; }
|
||||
/// <summary>
|
||||
/// Gets the timespan delta from when this plugin was loaded.
|
||||
/// </summary>
|
||||
public TimeSpan LoadTimeDelta => DateTime.Now - this.LoadTime;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the timespan delta from when this plugin was loaded.
|
||||
/// </summary>
|
||||
public TimeSpan LoadTimeDelta => DateTime.Now - this.LoadTime;
|
||||
/// <summary>
|
||||
/// Gets the directory Dalamud assets are stored in.
|
||||
/// </summary>
|
||||
public DirectoryInfo DalamudAssetDirectory => Service<Dalamud>.Get().AssetDirectory;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the directory Dalamud assets are stored in.
|
||||
/// </summary>
|
||||
public DirectoryInfo DalamudAssetDirectory => Service<Dalamud>.Get().AssetDirectory;
|
||||
/// <summary>
|
||||
/// Gets the location of your plugin assembly.
|
||||
/// </summary>
|
||||
public FileInfo AssemblyLocation { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the location of your plugin assembly.
|
||||
/// </summary>
|
||||
public FileInfo AssemblyLocation { get; }
|
||||
/// <summary>
|
||||
/// Gets the directory your plugin configurations are stored in.
|
||||
/// </summary>
|
||||
public DirectoryInfo ConfigDirectory => new(this.GetPluginConfigDirectory());
|
||||
|
||||
/// <summary>
|
||||
/// Gets the directory your plugin configurations are stored in.
|
||||
/// </summary>
|
||||
public DirectoryInfo ConfigDirectory => new(this.GetPluginConfigDirectory());
|
||||
/// <summary>
|
||||
/// Gets the config file of your plugin.
|
||||
/// </summary>
|
||||
public FileInfo ConfigFile => this.configs.GetConfigFile(this.pluginName);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the config file of your plugin.
|
||||
/// </summary>
|
||||
public FileInfo ConfigFile => this.configs.GetConfigFile(this.pluginName);
|
||||
/// <summary>
|
||||
/// Gets the <see cref="UiBuilder"/> instance which allows you to draw UI into the game via ImGui draw calls.
|
||||
/// </summary>
|
||||
public UiBuilder UiBuilder { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="UiBuilder"/> instance which allows you to draw UI into the game via ImGui draw calls.
|
||||
/// </summary>
|
||||
public UiBuilder UiBuilder { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether Dalamud is running in Debug mode or the /xldev menu is open. This can occur on release builds.
|
||||
/// </summary>
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether Dalamud is running in Debug mode or the /xldev menu is open. This can occur on release builds.
|
||||
/// </summary>
|
||||
#if DEBUG
|
||||
public bool IsDebugging => true;
|
||||
public bool IsDebugging => true;
|
||||
#else
|
||||
public bool IsDebugging => Service<DalamudInterface>.Get().IsDevMenuOpen;
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current UI language in two-letter iso format.
|
||||
/// </summary>
|
||||
public string UiLanguage { get; private set; }
|
||||
/// <summary>
|
||||
/// Gets the current UI language in two-letter iso format.
|
||||
/// </summary>
|
||||
public string UiLanguage { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets serializer class with functions to remove special characters from strings.
|
||||
/// </summary>
|
||||
public ISanitizer Sanitizer { get; }
|
||||
/// <summary>
|
||||
/// Gets serializer class with functions to remove special characters from strings.
|
||||
/// </summary>
|
||||
public ISanitizer Sanitizer { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the chat type used by default for plugin messages.
|
||||
/// </summary>
|
||||
public XivChatType GeneralChatType { get; private set; }
|
||||
/// <summary>
|
||||
/// Gets the chat type used by default for plugin messages.
|
||||
/// </summary>
|
||||
public XivChatType GeneralChatType { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a list of installed plugin names.
|
||||
/// </summary>
|
||||
public List<string> PluginNames => Service<PluginManager>.Get().InstalledPlugins.Select(p => p.Manifest.Name).ToList();
|
||||
/// <summary>
|
||||
/// Gets a list of installed plugin names.
|
||||
/// </summary>
|
||||
public List<string> PluginNames => Service<PluginManager>.Get().InstalledPlugins.Select(p => p.Manifest.Name).ToList();
|
||||
|
||||
/// <summary>
|
||||
/// Gets a list of installed plugin internal names.
|
||||
/// </summary>
|
||||
public List<string> PluginInternalNames => Service<PluginManager>.Get().InstalledPlugins.Select(p => p.Manifest.InternalName).ToList();
|
||||
/// <summary>
|
||||
/// Gets a list of installed plugin internal names.
|
||||
/// </summary>
|
||||
public List<string> PluginInternalNames => Service<PluginManager>.Get().InstalledPlugins.Select(p => p.Manifest.InternalName).ToList();
|
||||
|
||||
#region IPC
|
||||
#region IPC
|
||||
|
||||
/// <summary>
|
||||
/// Gets an IPC provider.
|
||||
/// </summary>
|
||||
/// <typeparam name="TRet">The return type for funcs. Use object if this is unused.</typeparam>
|
||||
/// <param name="name">The name of the IPC registration.</param>
|
||||
/// <returns>An IPC provider.</returns>
|
||||
/// <exception cref="IpcTypeMismatchError">This is thrown when the requested types do not match the previously registered types are different.</exception>
|
||||
public ICallGateProvider<TRet> GetIpcProvider<TRet>(string name)
|
||||
=> new CallGatePubSub<TRet>(name);
|
||||
/// <summary>
|
||||
/// Gets an IPC provider.
|
||||
/// </summary>
|
||||
/// <typeparam name="TRet">The return type for funcs. Use object if this is unused.</typeparam>
|
||||
/// <param name="name">The name of the IPC registration.</param>
|
||||
/// <returns>An IPC provider.</returns>
|
||||
/// <exception cref="IpcTypeMismatchError">This is thrown when the requested types do not match the previously registered types are different.</exception>
|
||||
public ICallGateProvider<TRet> GetIpcProvider<TRet>(string name)
|
||||
=> new CallGatePubSub<TRet>(name);
|
||||
|
||||
/// <inheritdoc cref="ICallGateProvider{TRet}"/>
|
||||
public ICallGateProvider<T1, TRet> GetIpcProvider<T1, TRet>(string name)
|
||||
=> new CallGatePubSub<T1, TRet>(name);
|
||||
/// <inheritdoc cref="ICallGateProvider{TRet}"/>
|
||||
public ICallGateProvider<T1, TRet> GetIpcProvider<T1, TRet>(string name)
|
||||
=> new CallGatePubSub<T1, TRet>(name);
|
||||
|
||||
/// <inheritdoc cref="ICallGateProvider{TRet}"/>
|
||||
public ICallGateProvider<T1, T2, TRet> GetIpcProvider<T1, T2, TRet>(string name)
|
||||
=> new CallGatePubSub<T1, T2, TRet>(name);
|
||||
/// <inheritdoc cref="ICallGateProvider{TRet}"/>
|
||||
public ICallGateProvider<T1, T2, TRet> GetIpcProvider<T1, T2, TRet>(string name)
|
||||
=> new CallGatePubSub<T1, T2, TRet>(name);
|
||||
|
||||
/// <inheritdoc cref="ICallGateProvider{TRet}"/>
|
||||
public ICallGateProvider<T1, T2, T3, TRet> GetIpcProvider<T1, T2, T3, TRet>(string name)
|
||||
=> new CallGatePubSub<T1, T2, T3, TRet>(name);
|
||||
/// <inheritdoc cref="ICallGateProvider{TRet}"/>
|
||||
public ICallGateProvider<T1, T2, T3, TRet> GetIpcProvider<T1, T2, T3, TRet>(string name)
|
||||
=> new CallGatePubSub<T1, T2, T3, TRet>(name);
|
||||
|
||||
/// <inheritdoc cref="ICallGateProvider{TRet}"/>
|
||||
public ICallGateProvider<T1, T2, T3, T4, TRet> GetIpcProvider<T1, T2, T3, T4, TRet>(string name)
|
||||
=> new CallGatePubSub<T1, T2, T3, T4, TRet>(name);
|
||||
/// <inheritdoc cref="ICallGateProvider{TRet}"/>
|
||||
public ICallGateProvider<T1, T2, T3, T4, TRet> GetIpcProvider<T1, T2, T3, T4, TRet>(string name)
|
||||
=> new CallGatePubSub<T1, T2, T3, T4, TRet>(name);
|
||||
|
||||
/// <inheritdoc cref="ICallGateProvider{TRet}"/>
|
||||
public ICallGateProvider<T1, T2, T3, T4, T5, TRet> GetIpcProvider<T1, T2, T3, T4, T5, TRet>(string name)
|
||||
=> new CallGatePubSub<T1, T2, T3, T4, T5, TRet>(name);
|
||||
/// <inheritdoc cref="ICallGateProvider{TRet}"/>
|
||||
public ICallGateProvider<T1, T2, T3, T4, T5, TRet> GetIpcProvider<T1, T2, T3, T4, T5, TRet>(string name)
|
||||
=> new CallGatePubSub<T1, T2, T3, T4, T5, TRet>(name);
|
||||
|
||||
/// <inheritdoc cref="ICallGateProvider{TRet}"/>
|
||||
public ICallGateProvider<T1, T2, T3, T4, T5, T6, TRet> GetIpcProvider<T1, T2, T3, T4, T5, T6, TRet>(string name)
|
||||
=> new CallGatePubSub<T1, T2, T3, T4, T5, T6, TRet>(name);
|
||||
/// <inheritdoc cref="ICallGateProvider{TRet}"/>
|
||||
public ICallGateProvider<T1, T2, T3, T4, T5, T6, TRet> GetIpcProvider<T1, T2, T3, T4, T5, T6, TRet>(string name)
|
||||
=> new CallGatePubSub<T1, T2, T3, T4, T5, T6, TRet>(name);
|
||||
|
||||
/// <inheritdoc cref="ICallGateProvider{TRet}"/>
|
||||
public ICallGateProvider<T1, T2, T3, T4, T5, T6, T7, TRet> GetIpcProvider<T1, T2, T3, T4, T5, T6, T7, TRet>(string name)
|
||||
=> new CallGatePubSub<T1, T2, T3, T4, T5, T6, T7, TRet>(name);
|
||||
/// <inheritdoc cref="ICallGateProvider{TRet}"/>
|
||||
public ICallGateProvider<T1, T2, T3, T4, T5, T6, T7, TRet> GetIpcProvider<T1, T2, T3, T4, T5, T6, T7, TRet>(string name)
|
||||
=> new CallGatePubSub<T1, T2, T3, T4, T5, T6, T7, TRet>(name);
|
||||
|
||||
/// <inheritdoc cref="ICallGateProvider{TRet}"/>
|
||||
public ICallGateProvider<T1, T2, T3, T4, T5, T6, T7, T8, TRet> GetIpcProvider<T1, T2, T3, T4, T5, T6, T7, T8, TRet>(string name)
|
||||
=> new CallGatePubSub<T1, T2, T3, T4, T5, T6, T7, T8, TRet>(name);
|
||||
/// <inheritdoc cref="ICallGateProvider{TRet}"/>
|
||||
public ICallGateProvider<T1, T2, T3, T4, T5, T6, T7, T8, TRet> GetIpcProvider<T1, T2, T3, T4, T5, T6, T7, T8, TRet>(string name)
|
||||
=> new CallGatePubSub<T1, T2, T3, T4, T5, T6, T7, T8, TRet>(name);
|
||||
|
||||
/// <summary>
|
||||
/// Gets an IPC subscriber.
|
||||
/// </summary>
|
||||
/// <typeparam name="TRet">The return type for funcs. Use object if this is unused.</typeparam>
|
||||
/// <param name="name">The name of the IPC registration.</param>
|
||||
/// <returns>An IPC subscriber.</returns>
|
||||
public ICallGateSubscriber<TRet> GetIpcSubscriber<TRet>(string name)
|
||||
=> new CallGatePubSub<TRet>(name);
|
||||
/// <summary>
|
||||
/// Gets an IPC subscriber.
|
||||
/// </summary>
|
||||
/// <typeparam name="TRet">The return type for funcs. Use object if this is unused.</typeparam>
|
||||
/// <param name="name">The name of the IPC registration.</param>
|
||||
/// <returns>An IPC subscriber.</returns>
|
||||
public ICallGateSubscriber<TRet> GetIpcSubscriber<TRet>(string name)
|
||||
=> new CallGatePubSub<TRet>(name);
|
||||
|
||||
/// <inheritdoc cref="ICallGateSubscriber{TRet}"/>
|
||||
public ICallGateSubscriber<T1, TRet> GetIpcSubscriber<T1, TRet>(string name)
|
||||
=> new CallGatePubSub<T1, TRet>(name);
|
||||
/// <inheritdoc cref="ICallGateSubscriber{TRet}"/>
|
||||
public ICallGateSubscriber<T1, TRet> GetIpcSubscriber<T1, TRet>(string name)
|
||||
=> new CallGatePubSub<T1, TRet>(name);
|
||||
|
||||
/// <inheritdoc cref="ICallGateSubscriber{TRet}"/>
|
||||
public ICallGateSubscriber<T1, T2, TRet> GetIpcSubscriber<T1, T2, TRet>(string name)
|
||||
=> new CallGatePubSub<T1, T2, TRet>(name);
|
||||
/// <inheritdoc cref="ICallGateSubscriber{TRet}"/>
|
||||
public ICallGateSubscriber<T1, T2, TRet> GetIpcSubscriber<T1, T2, TRet>(string name)
|
||||
=> new CallGatePubSub<T1, T2, TRet>(name);
|
||||
|
||||
/// <inheritdoc cref="ICallGateSubscriber{TRet}"/>
|
||||
public ICallGateSubscriber<T1, T2, T3, TRet> GetIpcSubscriber<T1, T2, T3, TRet>(string name)
|
||||
=> new CallGatePubSub<T1, T2, T3, TRet>(name);
|
||||
/// <inheritdoc cref="ICallGateSubscriber{TRet}"/>
|
||||
public ICallGateSubscriber<T1, T2, T3, TRet> GetIpcSubscriber<T1, T2, T3, TRet>(string name)
|
||||
=> new CallGatePubSub<T1, T2, T3, TRet>(name);
|
||||
|
||||
/// <inheritdoc cref="ICallGateSubscriber{TRet}"/>
|
||||
public ICallGateSubscriber<T1, T2, T3, T4, TRet> GetIpcSubscriber<T1, T2, T3, T4, TRet>(string name)
|
||||
=> new CallGatePubSub<T1, T2, T3, T4, TRet>(name);
|
||||
/// <inheritdoc cref="ICallGateSubscriber{TRet}"/>
|
||||
public ICallGateSubscriber<T1, T2, T3, T4, TRet> GetIpcSubscriber<T1, T2, T3, T4, TRet>(string name)
|
||||
=> new CallGatePubSub<T1, T2, T3, T4, TRet>(name);
|
||||
|
||||
/// <inheritdoc cref="ICallGateSubscriber{TRet}"/>
|
||||
public ICallGateSubscriber<T1, T2, T3, T4, T5, TRet> GetIpcSubscriber<T1, T2, T3, T4, T5, TRet>(string name)
|
||||
=> new CallGatePubSub<T1, T2, T3, T4, T5, TRet>(name);
|
||||
/// <inheritdoc cref="ICallGateSubscriber{TRet}"/>
|
||||
public ICallGateSubscriber<T1, T2, T3, T4, T5, TRet> GetIpcSubscriber<T1, T2, T3, T4, T5, TRet>(string name)
|
||||
=> new CallGatePubSub<T1, T2, T3, T4, T5, TRet>(name);
|
||||
|
||||
/// <inheritdoc cref="ICallGateSubscriber{TRet}"/>
|
||||
public ICallGateSubscriber<T1, T2, T3, T4, T5, T6, TRet> GetIpcSubscriber<T1, T2, T3, T4, T5, T6, TRet>(string name)
|
||||
=> new CallGatePubSub<T1, T2, T3, T4, T5, T6, TRet>(name);
|
||||
/// <inheritdoc cref="ICallGateSubscriber{TRet}"/>
|
||||
public ICallGateSubscriber<T1, T2, T3, T4, T5, T6, TRet> GetIpcSubscriber<T1, T2, T3, T4, T5, T6, TRet>(string name)
|
||||
=> new CallGatePubSub<T1, T2, T3, T4, T5, T6, TRet>(name);
|
||||
|
||||
/// <inheritdoc cref="ICallGateSubscriber{TRet}"/>
|
||||
public ICallGateSubscriber<T1, T2, T3, T4, T5, T6, T7, TRet> GetIpcSubscriber<T1, T2, T3, T4, T5, T6, T7, TRet>(string name)
|
||||
=> new CallGatePubSub<T1, T2, T3, T4, T5, T6, T7, TRet>(name);
|
||||
/// <inheritdoc cref="ICallGateSubscriber{TRet}"/>
|
||||
public ICallGateSubscriber<T1, T2, T3, T4, T5, T6, T7, TRet> GetIpcSubscriber<T1, T2, T3, T4, T5, T6, T7, TRet>(string name)
|
||||
=> new CallGatePubSub<T1, T2, T3, T4, T5, T6, T7, TRet>(name);
|
||||
|
||||
/// <inheritdoc cref="ICallGateSubscriber{TRet}"/>
|
||||
public ICallGateSubscriber<T1, T2, T3, T4, T5, T6, T7, T8, TRet> GetIpcSubscriber<T1, T2, T3, T4, T5, T6, T7, T8, TRet>(string name)
|
||||
=> new CallGatePubSub<T1, T2, T3, T4, T5, T6, T7, T8, TRet>(name);
|
||||
/// <inheritdoc cref="ICallGateSubscriber{TRet}"/>
|
||||
public ICallGateSubscriber<T1, T2, T3, T4, T5, T6, T7, T8, TRet> GetIpcSubscriber<T1, T2, T3, T4, T5, T6, T7, T8, TRet>(string name)
|
||||
=> new CallGatePubSub<T1, T2, T3, T4, T5, T6, T7, T8, TRet>(name);
|
||||
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
#region Configuration
|
||||
#region Configuration
|
||||
|
||||
/// <summary>
|
||||
/// Save a plugin configuration(inheriting IPluginConfiguration).
|
||||
/// </summary>
|
||||
/// <param name="currentConfig">The current configuration.</param>
|
||||
public void SavePluginConfig(IPluginConfiguration? currentConfig)
|
||||
{
|
||||
if (currentConfig == null)
|
||||
return;
|
||||
|
||||
this.configs.Save(currentConfig, this.pluginName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get a previously saved plugin configuration or null if none was saved before.
|
||||
/// </summary>
|
||||
/// <returns>A previously saved config or null if none was saved before.</returns>
|
||||
public IPluginConfiguration? GetPluginConfig()
|
||||
{
|
||||
// This is done to support json deserialization of plugin configurations
|
||||
// even after running an in-game update of plugins, where the assembly version
|
||||
// changes.
|
||||
// Eventually it might make sense to have a separate method on this class
|
||||
// T GetPluginConfig<T>() where T : IPluginConfiguration
|
||||
// that can invoke LoadForType() directly instead of via reflection
|
||||
// This is here for now to support the current plugin API
|
||||
foreach (var type in Assembly.GetCallingAssembly().GetTypes())
|
||||
/// <summary>
|
||||
/// Save a plugin configuration(inheriting IPluginConfiguration).
|
||||
/// </summary>
|
||||
/// <param name="currentConfig">The current configuration.</param>
|
||||
public void SavePluginConfig(IPluginConfiguration? currentConfig)
|
||||
{
|
||||
if (type.IsAssignableTo(typeof(IPluginConfiguration)))
|
||||
{
|
||||
var mi = this.configs.GetType().GetMethod("LoadForType");
|
||||
var fn = mi.MakeGenericMethod(type);
|
||||
return (IPluginConfiguration)fn.Invoke(this.configs, new object[] { this.pluginName });
|
||||
}
|
||||
if (currentConfig == null)
|
||||
return;
|
||||
|
||||
this.configs.Save(currentConfig, this.pluginName);
|
||||
}
|
||||
|
||||
// this shouldn't be a thing, I think, but just in case
|
||||
return this.configs.Load(this.pluginName);
|
||||
}
|
||||
/// <summary>
|
||||
/// Get a previously saved plugin configuration or null if none was saved before.
|
||||
/// </summary>
|
||||
/// <returns>A previously saved config or null if none was saved before.</returns>
|
||||
public IPluginConfiguration? GetPluginConfig()
|
||||
{
|
||||
// This is done to support json deserialization of plugin configurations
|
||||
// even after running an in-game update of plugins, where the assembly version
|
||||
// changes.
|
||||
// Eventually it might make sense to have a separate method on this class
|
||||
// T GetPluginConfig<T>() where T : IPluginConfiguration
|
||||
// that can invoke LoadForType() directly instead of via reflection
|
||||
// This is here for now to support the current plugin API
|
||||
foreach (var type in Assembly.GetCallingAssembly().GetTypes())
|
||||
{
|
||||
if (type.IsAssignableTo(typeof(IPluginConfiguration)))
|
||||
{
|
||||
var mi = this.configs.GetType().GetMethod("LoadForType");
|
||||
var fn = mi.MakeGenericMethod(type);
|
||||
return (IPluginConfiguration)fn.Invoke(this.configs, new object[] { this.pluginName });
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the config directory.
|
||||
/// </summary>
|
||||
/// <returns>directory with path of AppData/XIVLauncher/pluginConfig/PluginInternalName.</returns>
|
||||
public string GetPluginConfigDirectory() => this.configs.GetDirectory(this.pluginName);
|
||||
// this shouldn't be a thing, I think, but just in case
|
||||
return this.configs.Load(this.pluginName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the loc directory.
|
||||
/// </summary>
|
||||
/// <returns>directory with path of AppData/XIVLauncher/pluginConfig/PluginInternalName/loc.</returns>
|
||||
public string GetPluginLocDirectory() => this.configs.GetDirectory(Path.Combine(this.pluginName, "loc"));
|
||||
/// <summary>
|
||||
/// Get the config directory.
|
||||
/// </summary>
|
||||
/// <returns>directory with path of AppData/XIVLauncher/pluginConfig/PluginInternalName.</returns>
|
||||
public string GetPluginConfigDirectory() => this.configs.GetDirectory(this.pluginName);
|
||||
|
||||
#endregion
|
||||
/// <summary>
|
||||
/// Get the loc directory.
|
||||
/// </summary>
|
||||
/// <returns>directory with path of AppData/XIVLauncher/pluginConfig/PluginInternalName/loc.</returns>
|
||||
public string GetPluginLocDirectory() => this.configs.GetDirectory(Path.Combine(this.pluginName, "loc"));
|
||||
|
||||
#region Chat Links
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Register a chat link handler.
|
||||
/// </summary>
|
||||
/// <param name="commandId">The ID of the command.</param>
|
||||
/// <param name="commandAction">The action to be executed.</param>
|
||||
/// <returns>Returns an SeString payload for the link.</returns>
|
||||
public DalamudLinkPayload AddChatLinkHandler(uint commandId, Action<uint, SeString> commandAction)
|
||||
{
|
||||
return Service<ChatGui>.Get().AddChatLinkHandler(this.pluginName, commandId, commandAction);
|
||||
}
|
||||
#region Chat Links
|
||||
|
||||
/// <summary>
|
||||
/// Remove a chat link handler.
|
||||
/// </summary>
|
||||
/// <param name="commandId">The ID of the command.</param>
|
||||
public void RemoveChatLinkHandler(uint commandId)
|
||||
{
|
||||
Service<ChatGui>.Get().RemoveChatLinkHandler(this.pluginName, commandId);
|
||||
}
|
||||
/// <summary>
|
||||
/// Register a chat link handler.
|
||||
/// </summary>
|
||||
/// <param name="commandId">The ID of the command.</param>
|
||||
/// <param name="commandAction">The action to be executed.</param>
|
||||
/// <returns>Returns an SeString payload for the link.</returns>
|
||||
public DalamudLinkPayload AddChatLinkHandler(uint commandId, Action<uint, SeString> commandAction)
|
||||
{
|
||||
return Service<ChatGui>.Get().AddChatLinkHandler(this.pluginName, commandId, commandAction);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes all chat link handlers registered by the plugin.
|
||||
/// </summary>
|
||||
public void RemoveChatLinkHandler()
|
||||
{
|
||||
Service<ChatGui>.Get().RemoveChatLinkHandler(this.pluginName);
|
||||
}
|
||||
#endregion
|
||||
/// <summary>
|
||||
/// Remove a chat link handler.
|
||||
/// </summary>
|
||||
/// <param name="commandId">The ID of the command.</param>
|
||||
public void RemoveChatLinkHandler(uint commandId)
|
||||
{
|
||||
Service<ChatGui>.Get().RemoveChatLinkHandler(this.pluginName, commandId);
|
||||
}
|
||||
|
||||
#region Dependency Injection
|
||||
/// <summary>
|
||||
/// Removes all chat link handlers registered by the plugin.
|
||||
/// </summary>
|
||||
public void RemoveChatLinkHandler()
|
||||
{
|
||||
Service<ChatGui>.Get().RemoveChatLinkHandler(this.pluginName);
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Create a new object of the provided type using its default constructor, then inject objects and properties.
|
||||
/// </summary>
|
||||
/// <param name="scopedObjects">Objects to inject additionally.</param>
|
||||
/// <typeparam name="T">The type to create.</typeparam>
|
||||
/// <returns>The created and initialized type.</returns>
|
||||
public T? Create<T>(params object[] scopedObjects) where T : class
|
||||
{
|
||||
var svcContainer = Service<IoC.Internal.ServiceContainer>.Get();
|
||||
#region Dependency Injection
|
||||
|
||||
var realScopedObjects = new object[scopedObjects.Length + 1];
|
||||
realScopedObjects[0] = this;
|
||||
Array.Copy(scopedObjects, 0, realScopedObjects, 1, scopedObjects.Length);
|
||||
/// <summary>
|
||||
/// Create a new object of the provided type using its default constructor, then inject objects and properties.
|
||||
/// </summary>
|
||||
/// <param name="scopedObjects">Objects to inject additionally.</param>
|
||||
/// <typeparam name="T">The type to create.</typeparam>
|
||||
/// <returns>The created and initialized type.</returns>
|
||||
public T? Create<T>(params object[] scopedObjects) where T : class
|
||||
{
|
||||
var svcContainer = Service<IoC.Internal.ServiceContainer>.Get();
|
||||
|
||||
return svcContainer.Create(typeof(T), realScopedObjects) as T;
|
||||
}
|
||||
var realScopedObjects = new object[scopedObjects.Length + 1];
|
||||
realScopedObjects[0] = this;
|
||||
Array.Copy(scopedObjects, 0, realScopedObjects, 1, scopedObjects.Length);
|
||||
|
||||
/// <summary>
|
||||
/// Inject services into properties on the provided object instance.
|
||||
/// </summary>
|
||||
/// <param name="instance">The instance to inject services into.</param>
|
||||
/// <param name="scopedObjects">Objects to inject additionally.</param>
|
||||
/// <returns>Whether or not the injection succeeded.</returns>
|
||||
public bool Inject(object instance, params object[] scopedObjects)
|
||||
{
|
||||
var svcContainer = Service<IoC.Internal.ServiceContainer>.Get();
|
||||
return svcContainer.Create(typeof(T), realScopedObjects) as T;
|
||||
}
|
||||
|
||||
var realScopedObjects = new object[scopedObjects.Length + 1];
|
||||
realScopedObjects[0] = this;
|
||||
Array.Copy(scopedObjects, 0, realScopedObjects, 1, scopedObjects.Length);
|
||||
/// <summary>
|
||||
/// Inject services into properties on the provided object instance.
|
||||
/// </summary>
|
||||
/// <param name="instance">The instance to inject services into.</param>
|
||||
/// <param name="scopedObjects">Objects to inject additionally.</param>
|
||||
/// <returns>Whether or not the injection succeeded.</returns>
|
||||
public bool Inject(object instance, params object[] scopedObjects)
|
||||
{
|
||||
var svcContainer = Service<IoC.Internal.ServiceContainer>.Get();
|
||||
|
||||
return svcContainer.InjectProperties(instance, realScopedObjects);
|
||||
}
|
||||
var realScopedObjects = new object[scopedObjects.Length + 1];
|
||||
realScopedObjects[0] = this;
|
||||
Array.Copy(scopedObjects, 0, realScopedObjects, 1, scopedObjects.Length);
|
||||
|
||||
#endregion
|
||||
return svcContainer.InjectProperties(instance, realScopedObjects);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unregister your plugin and dispose all references.
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
this.UiBuilder.Dispose();
|
||||
Service<ChatGui>.Get().RemoveChatLinkHandler(this.pluginName);
|
||||
Service<Localization>.Get().LocalizationChanged -= this.OnLocalizationChanged;
|
||||
Service<DalamudConfiguration>.Get().DalamudConfigurationSaved -= this.OnDalamudConfigurationSaved;
|
||||
}
|
||||
#endregion
|
||||
|
||||
private void OnLocalizationChanged(string langCode)
|
||||
{
|
||||
this.UiLanguage = langCode;
|
||||
this.LanguageChanged?.Invoke(langCode);
|
||||
}
|
||||
/// <summary>
|
||||
/// Unregister your plugin and dispose all references.
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
this.UiBuilder.Dispose();
|
||||
Service<ChatGui>.Get().RemoveChatLinkHandler(this.pluginName);
|
||||
Service<Localization>.Get().LocalizationChanged -= this.OnLocalizationChanged;
|
||||
Service<DalamudConfiguration>.Get().DalamudConfigurationSaved -= this.OnDalamudConfigurationSaved;
|
||||
}
|
||||
|
||||
private void OnDalamudConfigurationSaved(DalamudConfiguration dalamudConfiguration)
|
||||
{
|
||||
this.GeneralChatType = dalamudConfiguration.GeneralChatType;
|
||||
private void OnLocalizationChanged(string langCode)
|
||||
{
|
||||
this.UiLanguage = langCode;
|
||||
this.LanguageChanged?.Invoke(langCode);
|
||||
}
|
||||
|
||||
private void OnDalamudConfigurationSaved(DalamudConfiguration dalamudConfiguration)
|
||||
{
|
||||
this.GeneralChatType = dalamudConfiguration.GeneralChatType;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,14 +1,15 @@
|
|||
using System;
|
||||
|
||||
namespace Dalamud.Plugin;
|
||||
|
||||
/// <summary>
|
||||
/// This interface represents a basic Dalamud plugin. All plugins have to implement this interface.
|
||||
/// </summary>
|
||||
public interface IDalamudPlugin : IDisposable
|
||||
namespace Dalamud.Plugin
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the name of the plugin.
|
||||
/// This interface represents a basic Dalamud plugin. All plugins have to implement this interface.
|
||||
/// </summary>
|
||||
string Name { get; }
|
||||
public interface IDalamudPlugin : IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the name of the plugin.
|
||||
/// </summary>
|
||||
string Name { get; }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,21 +1,22 @@
|
|||
namespace Dalamud.Plugin.Internal.Exceptions;
|
||||
|
||||
/// <summary>
|
||||
/// This represents a banned plugin that attempted an operation.
|
||||
/// </summary>
|
||||
internal class BannedPluginException : PluginException
|
||||
namespace Dalamud.Plugin.Internal.Exceptions
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="BannedPluginException"/> class.
|
||||
/// This represents a banned plugin that attempted an operation.
|
||||
/// </summary>
|
||||
/// <param name="message">The message describing the invalid operation.</param>
|
||||
public BannedPluginException(string message)
|
||||
internal class BannedPluginException : PluginException
|
||||
{
|
||||
this.Message = message;
|
||||
}
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="BannedPluginException"/> class.
|
||||
/// </summary>
|
||||
/// <param name="message">The message describing the invalid operation.</param>
|
||||
public BannedPluginException(string message)
|
||||
{
|
||||
this.Message = message;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the message describing the invalid operation.
|
||||
/// </summary>
|
||||
public override string Message { get; }
|
||||
/// <summary>
|
||||
/// Gets the message describing the invalid operation.
|
||||
/// </summary>
|
||||
public override string Message { get; }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,25 +1,26 @@
|
|||
namespace Dalamud.Plugin.Internal.Exceptions;
|
||||
|
||||
/// <summary>
|
||||
/// This exception that is thrown when a plugin is instructed to load while another plugin with the same
|
||||
/// assembly name is already present and loaded.
|
||||
/// </summary>
|
||||
internal class DuplicatePluginException : PluginException
|
||||
namespace Dalamud.Plugin.Internal.Exceptions
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="DuplicatePluginException"/> class.
|
||||
/// This exception that is thrown when a plugin is instructed to load while another plugin with the same
|
||||
/// assembly name is already present and loaded.
|
||||
/// </summary>
|
||||
/// <param name="assemblyName">Name of the conflicting assembly.</param>
|
||||
public DuplicatePluginException(string assemblyName)
|
||||
internal class DuplicatePluginException : PluginException
|
||||
{
|
||||
this.AssemblyName = assemblyName;
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="DuplicatePluginException"/> class.
|
||||
/// </summary>
|
||||
/// <param name="assemblyName">Name of the conflicting assembly.</param>
|
||||
public DuplicatePluginException(string assemblyName)
|
||||
{
|
||||
this.AssemblyName = assemblyName;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name of the conflicting assembly.
|
||||
/// </summary>
|
||||
public string AssemblyName { get; init; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override string Message => $"A plugin with the same assembly name of {this.AssemblyName} is already loaded";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name of the conflicting assembly.
|
||||
/// </summary>
|
||||
public string AssemblyName { get; init; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override string Message => $"A plugin with the same assembly name of {this.AssemblyName} is already loaded";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,24 +1,25 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace Dalamud.Plugin.Internal.Exceptions;
|
||||
|
||||
/// <summary>
|
||||
/// This exception represents a file that does not implement IDalamudPlugin.
|
||||
/// </summary>
|
||||
internal class InvalidPluginException : PluginException
|
||||
namespace Dalamud.Plugin.Internal.Exceptions
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="InvalidPluginException"/> class.
|
||||
/// This exception represents a file that does not implement IDalamudPlugin.
|
||||
/// </summary>
|
||||
/// <param name="dllFile">The invalid file.</param>
|
||||
public InvalidPluginException(FileInfo dllFile)
|
||||
internal class InvalidPluginException : PluginException
|
||||
{
|
||||
this.DllFile = dllFile;
|
||||
}
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="InvalidPluginException"/> class.
|
||||
/// </summary>
|
||||
/// <param name="dllFile">The invalid file.</param>
|
||||
public InvalidPluginException(FileInfo dllFile)
|
||||
{
|
||||
this.DllFile = dllFile;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the invalid file.
|
||||
/// </summary>
|
||||
public FileInfo DllFile { get; init; }
|
||||
/// <summary>
|
||||
/// Gets the invalid file.
|
||||
/// </summary>
|
||||
public FileInfo DllFile { get; init; }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,23 +1,24 @@
|
|||
using System;
|
||||
|
||||
namespace Dalamud.Plugin.Internal.Exceptions;
|
||||
|
||||
/// <summary>
|
||||
/// This represents an invalid plugin operation.
|
||||
/// </summary>
|
||||
internal class InvalidPluginOperationException : PluginException
|
||||
namespace Dalamud.Plugin.Internal.Exceptions
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="InvalidPluginOperationException"/> class.
|
||||
/// This represents an invalid plugin operation.
|
||||
/// </summary>
|
||||
/// <param name="message">The message describing the invalid operation.</param>
|
||||
public InvalidPluginOperationException(string message)
|
||||
internal class InvalidPluginOperationException : PluginException
|
||||
{
|
||||
this.Message = message;
|
||||
}
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="InvalidPluginOperationException"/> class.
|
||||
/// </summary>
|
||||
/// <param name="message">The message describing the invalid operation.</param>
|
||||
public InvalidPluginOperationException(string message)
|
||||
{
|
||||
this.Message = message;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the message describing the invalid operation.
|
||||
/// </summary>
|
||||
public override string Message { get; }
|
||||
/// <summary>
|
||||
/// Gets the message describing the invalid operation.
|
||||
/// </summary>
|
||||
public override string Message { get; }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
using System;
|
||||
|
||||
namespace Dalamud.Plugin.Internal.Exceptions;
|
||||
|
||||
/// <summary>
|
||||
/// This represents the base Dalamud plugin exception.
|
||||
/// </summary>
|
||||
internal abstract class PluginException : Exception
|
||||
namespace Dalamud.Plugin.Internal.Exceptions
|
||||
{
|
||||
/// <summary>
|
||||
/// This represents the base Dalamud plugin exception.
|
||||
/// </summary>
|
||||
internal abstract class PluginException : Exception
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,156 +8,157 @@ using Dalamud.Interface.Internal.Notifications;
|
|||
using Dalamud.Logging.Internal;
|
||||
using Dalamud.Plugin.Internal.Types;
|
||||
|
||||
namespace Dalamud.Plugin.Internal;
|
||||
|
||||
/// <summary>
|
||||
/// This class represents a dev plugin and all facets of its lifecycle.
|
||||
/// The DLL on disk, dependencies, loaded assembly, etc.
|
||||
/// </summary>
|
||||
internal class LocalDevPlugin : LocalPlugin, IDisposable
|
||||
namespace Dalamud.Plugin.Internal
|
||||
{
|
||||
private static readonly ModuleLog Log = new("PLUGIN");
|
||||
|
||||
// Ref to Dalamud.Configuration.DevPluginSettings
|
||||
private readonly DevPluginSettings devSettings;
|
||||
|
||||
private FileSystemWatcher fileWatcher;
|
||||
private CancellationTokenSource fileWatcherTokenSource;
|
||||
private int reloadCounter;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="LocalDevPlugin"/> class.
|
||||
/// This class represents a dev plugin and all facets of its lifecycle.
|
||||
/// The DLL on disk, dependencies, loaded assembly, etc.
|
||||
/// </summary>
|
||||
/// <param name="dllFile">Path to the DLL file.</param>
|
||||
/// <param name="manifest">The plugin manifest.</param>
|
||||
public LocalDevPlugin(FileInfo dllFile, LocalPluginManifest? manifest)
|
||||
: base(dllFile, manifest)
|
||||
internal class LocalDevPlugin : LocalPlugin, IDisposable
|
||||
{
|
||||
var configuration = Service<DalamudConfiguration>.Get();
|
||||
private static readonly ModuleLog Log = new("PLUGIN");
|
||||
|
||||
if (!configuration.DevPluginSettings.TryGetValue(dllFile.FullName, out this.devSettings))
|
||||
// Ref to Dalamud.Configuration.DevPluginSettings
|
||||
private readonly DevPluginSettings devSettings;
|
||||
|
||||
private FileSystemWatcher fileWatcher;
|
||||
private CancellationTokenSource fileWatcherTokenSource;
|
||||
private int reloadCounter;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="LocalDevPlugin"/> class.
|
||||
/// </summary>
|
||||
/// <param name="dllFile">Path to the DLL file.</param>
|
||||
/// <param name="manifest">The plugin manifest.</param>
|
||||
public LocalDevPlugin(FileInfo dllFile, LocalPluginManifest? manifest)
|
||||
: base(dllFile, manifest)
|
||||
{
|
||||
configuration.DevPluginSettings[dllFile.FullName] = this.devSettings = new DevPluginSettings();
|
||||
configuration.Save();
|
||||
}
|
||||
var configuration = Service<DalamudConfiguration>.Get();
|
||||
|
||||
if (this.AutomaticReload)
|
||||
{
|
||||
this.EnableReloading();
|
||||
}
|
||||
}
|
||||
if (!configuration.DevPluginSettings.TryGetValue(dllFile.FullName, out this.devSettings))
|
||||
{
|
||||
configuration.DevPluginSettings[dllFile.FullName] = this.devSettings = new DevPluginSettings();
|
||||
configuration.Save();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether this dev plugin should start on boot.
|
||||
/// </summary>
|
||||
public bool StartOnBoot
|
||||
{
|
||||
get => this.devSettings.StartOnBoot;
|
||||
set => this.devSettings.StartOnBoot = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether this dev plugin should reload on change.
|
||||
/// </summary>
|
||||
public bool AutomaticReload
|
||||
{
|
||||
get => this.devSettings.AutomaticReloading;
|
||||
set
|
||||
{
|
||||
this.devSettings.AutomaticReloading = value;
|
||||
|
||||
if (this.devSettings.AutomaticReloading)
|
||||
if (this.AutomaticReload)
|
||||
{
|
||||
this.EnableReloading();
|
||||
}
|
||||
else
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether this dev plugin should start on boot.
|
||||
/// </summary>
|
||||
public bool StartOnBoot
|
||||
{
|
||||
get => this.devSettings.StartOnBoot;
|
||||
set => this.devSettings.StartOnBoot = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether this dev plugin should reload on change.
|
||||
/// </summary>
|
||||
public bool AutomaticReload
|
||||
{
|
||||
get => this.devSettings.AutomaticReloading;
|
||||
set
|
||||
{
|
||||
this.DisableReloading();
|
||||
this.devSettings.AutomaticReloading = value;
|
||||
|
||||
if (this.devSettings.AutomaticReloading)
|
||||
{
|
||||
this.EnableReloading();
|
||||
}
|
||||
else
|
||||
{
|
||||
this.DisableReloading();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public new void Dispose()
|
||||
{
|
||||
if (this.fileWatcher != null)
|
||||
/// <inheritdoc/>
|
||||
public new void Dispose()
|
||||
{
|
||||
this.fileWatcher.Changed -= this.OnFileChanged;
|
||||
this.fileWatcherTokenSource.Cancel();
|
||||
this.fileWatcher.Dispose();
|
||||
}
|
||||
|
||||
base.Dispose();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Configure this plugin for automatic reloading and enable it.
|
||||
/// </summary>
|
||||
public void EnableReloading()
|
||||
{
|
||||
if (this.fileWatcher == null)
|
||||
{
|
||||
this.fileWatcherTokenSource = new();
|
||||
this.fileWatcher = new FileSystemWatcher(this.DllFile.DirectoryName);
|
||||
this.fileWatcher.Changed += this.OnFileChanged;
|
||||
this.fileWatcher.Filter = this.DllFile.Name;
|
||||
this.fileWatcher.NotifyFilter = NotifyFilters.LastWrite;
|
||||
this.fileWatcher.EnableRaisingEvents = true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Disable automatic reloading for this plugin.
|
||||
/// </summary>
|
||||
public void DisableReloading()
|
||||
{
|
||||
if (this.fileWatcher != null)
|
||||
{
|
||||
this.fileWatcherTokenSource.Cancel();
|
||||
this.fileWatcher.Changed -= this.OnFileChanged;
|
||||
this.fileWatcher.Dispose();
|
||||
this.fileWatcher = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnFileChanged(object sender, FileSystemEventArgs args)
|
||||
{
|
||||
var current = Interlocked.Increment(ref this.reloadCounter);
|
||||
|
||||
Task.Delay(500).ContinueWith(
|
||||
task =>
|
||||
if (this.fileWatcher != null)
|
||||
{
|
||||
if (this.fileWatcherTokenSource.IsCancellationRequested)
|
||||
{
|
||||
Log.Debug($"Skipping reload of {this.Name}, file watcher was cancelled.");
|
||||
return;
|
||||
}
|
||||
this.fileWatcher.Changed -= this.OnFileChanged;
|
||||
this.fileWatcherTokenSource.Cancel();
|
||||
this.fileWatcher.Dispose();
|
||||
}
|
||||
|
||||
if (current != this.reloadCounter)
|
||||
{
|
||||
Log.Debug($"Skipping reload of {this.Name}, file has changed again.");
|
||||
return;
|
||||
}
|
||||
base.Dispose();
|
||||
}
|
||||
|
||||
if (this.State != PluginState.Loaded)
|
||||
{
|
||||
Log.Debug($"Skipping reload of {this.Name}, state ({this.State}) is not {PluginState.Loaded}.");
|
||||
return;
|
||||
}
|
||||
/// <summary>
|
||||
/// Configure this plugin for automatic reloading and enable it.
|
||||
/// </summary>
|
||||
public void EnableReloading()
|
||||
{
|
||||
if (this.fileWatcher == null)
|
||||
{
|
||||
this.fileWatcherTokenSource = new();
|
||||
this.fileWatcher = new FileSystemWatcher(this.DllFile.DirectoryName);
|
||||
this.fileWatcher.Changed += this.OnFileChanged;
|
||||
this.fileWatcher.Filter = this.DllFile.Name;
|
||||
this.fileWatcher.NotifyFilter = NotifyFilters.LastWrite;
|
||||
this.fileWatcher.EnableRaisingEvents = true;
|
||||
}
|
||||
}
|
||||
|
||||
var notificationManager = Service<NotificationManager>.Get();
|
||||
/// <summary>
|
||||
/// Disable automatic reloading for this plugin.
|
||||
/// </summary>
|
||||
public void DisableReloading()
|
||||
{
|
||||
if (this.fileWatcher != null)
|
||||
{
|
||||
this.fileWatcherTokenSource.Cancel();
|
||||
this.fileWatcher.Changed -= this.OnFileChanged;
|
||||
this.fileWatcher.Dispose();
|
||||
this.fileWatcher = null;
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
private void OnFileChanged(object sender, FileSystemEventArgs args)
|
||||
{
|
||||
var current = Interlocked.Increment(ref this.reloadCounter);
|
||||
|
||||
Task.Delay(500).ContinueWith(
|
||||
task =>
|
||||
{
|
||||
this.Reload();
|
||||
notificationManager.AddNotification($"The DevPlugin '{this.Name} was reloaded successfully.", "Plugin reloaded!", NotificationType.Success);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex, "DevPlugin reload failed.");
|
||||
notificationManager.AddNotification($"The DevPlugin '{this.Name} could not be reloaded.", "Plugin reload failed!", NotificationType.Error);
|
||||
}
|
||||
},
|
||||
this.fileWatcherTokenSource.Token);
|
||||
if (this.fileWatcherTokenSource.IsCancellationRequested)
|
||||
{
|
||||
Log.Debug($"Skipping reload of {this.Name}, file watcher was cancelled.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (current != this.reloadCounter)
|
||||
{
|
||||
Log.Debug($"Skipping reload of {this.Name}, file has changed again.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.State != PluginState.Loaded)
|
||||
{
|
||||
Log.Debug($"Skipping reload of {this.Name}, state ({this.State}) is not {PluginState.Loaded}.");
|
||||
return;
|
||||
}
|
||||
|
||||
var notificationManager = Service<NotificationManager>.Get();
|
||||
|
||||
try
|
||||
{
|
||||
this.Reload();
|
||||
notificationManager.AddNotification($"The DevPlugin '{this.Name} was reloaded successfully.", "Plugin reloaded!", NotificationType.Success);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex, "DevPlugin reload failed.");
|
||||
notificationManager.AddNotification($"The DevPlugin '{this.Name} could not be reloaded.", "Plugin reload failed!", NotificationType.Error);
|
||||
}
|
||||
},
|
||||
this.fileWatcherTokenSource.Token);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,364 +11,201 @@ using Dalamud.Plugin.Internal.Exceptions;
|
|||
using Dalamud.Plugin.Internal.Loader;
|
||||
using Dalamud.Plugin.Internal.Types;
|
||||
|
||||
namespace Dalamud.Plugin.Internal;
|
||||
|
||||
/// <summary>
|
||||
/// This class represents a plugin and all facets of its lifecycle.
|
||||
/// The DLL on disk, dependencies, loaded assembly, etc.
|
||||
/// </summary>
|
||||
internal class LocalPlugin : IDisposable
|
||||
namespace Dalamud.Plugin.Internal
|
||||
{
|
||||
private static readonly ModuleLog Log = new("LOCALPLUGIN");
|
||||
|
||||
private readonly FileInfo manifestFile;
|
||||
private readonly FileInfo disabledFile;
|
||||
private readonly FileInfo testingFile;
|
||||
|
||||
private PluginLoader loader;
|
||||
private Assembly pluginAssembly;
|
||||
private Type? pluginType;
|
||||
private IDalamudPlugin? instance;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="LocalPlugin"/> class.
|
||||
/// This class represents a plugin and all facets of its lifecycle.
|
||||
/// The DLL on disk, dependencies, loaded assembly, etc.
|
||||
/// </summary>
|
||||
/// <param name="dllFile">Path to the DLL file.</param>
|
||||
/// <param name="manifest">The plugin manifest.</param>
|
||||
public LocalPlugin(FileInfo dllFile, LocalPluginManifest? manifest)
|
||||
internal class LocalPlugin : IDisposable
|
||||
{
|
||||
if (dllFile.Name == "FFXIVClientStructs.Generators.dll")
|
||||
private static readonly ModuleLog Log = new("LOCALPLUGIN");
|
||||
|
||||
private readonly FileInfo manifestFile;
|
||||
private readonly FileInfo disabledFile;
|
||||
private readonly FileInfo testingFile;
|
||||
|
||||
private PluginLoader loader;
|
||||
private Assembly pluginAssembly;
|
||||
private Type? pluginType;
|
||||
private IDalamudPlugin? instance;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="LocalPlugin"/> class.
|
||||
/// </summary>
|
||||
/// <param name="dllFile">Path to the DLL file.</param>
|
||||
/// <param name="manifest">The plugin manifest.</param>
|
||||
public LocalPlugin(FileInfo dllFile, LocalPluginManifest? manifest)
|
||||
{
|
||||
// Could this be done another way? Sure. It is an extremely common source
|
||||
// of errors in the log through, and should never be loaded as a plugin.
|
||||
Log.Error($"Not a plugin: {dllFile.FullName}");
|
||||
throw new InvalidPluginException(dllFile);
|
||||
}
|
||||
|
||||
this.DllFile = dllFile;
|
||||
this.State = PluginState.Unloaded;
|
||||
|
||||
this.loader = PluginLoader.CreateFromAssemblyFile(this.DllFile.FullName, this.SetupLoaderConfig);
|
||||
|
||||
try
|
||||
{
|
||||
this.pluginAssembly = this.loader.LoadDefaultAssembly();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.pluginAssembly = null;
|
||||
this.pluginType = null;
|
||||
this.loader.Dispose();
|
||||
|
||||
Log.Error(ex, $"Not a plugin: {this.DllFile.FullName}");
|
||||
throw new InvalidPluginException(this.DllFile);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
this.pluginType = this.pluginAssembly.GetTypes().FirstOrDefault(type => type.IsAssignableTo(typeof(IDalamudPlugin)));
|
||||
}
|
||||
catch (ReflectionTypeLoadException ex)
|
||||
{
|
||||
Log.Error(ex, $"Could not load one or more types when searching for IDalamudPlugin: {this.DllFile.FullName}");
|
||||
// Something blew up when parsing types, but we still want to look for IDalamudPlugin. Let Load() handle the error.
|
||||
this.pluginType = ex.Types.FirstOrDefault(type => type.IsAssignableTo(typeof(IDalamudPlugin)));
|
||||
}
|
||||
|
||||
if (this.pluginType == default)
|
||||
{
|
||||
this.pluginAssembly = null;
|
||||
this.pluginType = null;
|
||||
this.loader.Dispose();
|
||||
|
||||
Log.Error($"Nothing inherits from IDalamudPlugin: {this.DllFile.FullName}");
|
||||
throw new InvalidPluginException(this.DllFile);
|
||||
}
|
||||
|
||||
var assemblyVersion = this.pluginAssembly.GetName().Version;
|
||||
|
||||
// Although it is conditionally used here, we need to set the initial value regardless.
|
||||
this.manifestFile = LocalPluginManifest.GetManifestFile(this.DllFile);
|
||||
|
||||
// If the parameter manifest was null
|
||||
if (manifest == null)
|
||||
{
|
||||
this.Manifest = new LocalPluginManifest()
|
||||
if (dllFile.Name == "FFXIVClientStructs.Generators.dll")
|
||||
{
|
||||
Author = "developer",
|
||||
Name = Path.GetFileNameWithoutExtension(this.DllFile.Name),
|
||||
InternalName = Path.GetFileNameWithoutExtension(this.DllFile.Name),
|
||||
AssemblyVersion = assemblyVersion,
|
||||
Description = string.Empty,
|
||||
ApplicableVersion = GameVersion.Any,
|
||||
DalamudApiLevel = PluginManager.DalamudApiLevel,
|
||||
IsHide = false,
|
||||
};
|
||||
// Could this be done another way? Sure. It is an extremely common source
|
||||
// of errors in the log through, and should never be loaded as a plugin.
|
||||
Log.Error($"Not a plugin: {dllFile.FullName}");
|
||||
throw new InvalidPluginException(dllFile);
|
||||
}
|
||||
|
||||
// Save the manifest to disk so there won't be any problems later.
|
||||
// We'll update the name property after it can be retrieved from the instance.
|
||||
this.Manifest.Save(this.manifestFile);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.Manifest = manifest;
|
||||
}
|
||||
this.DllFile = dllFile;
|
||||
this.State = PluginState.Unloaded;
|
||||
|
||||
// This converts from the ".disabled" file feature to the manifest instead.
|
||||
this.disabledFile = LocalPluginManifest.GetDisabledFile(this.DllFile);
|
||||
if (this.disabledFile.Exists)
|
||||
{
|
||||
this.Manifest.Disabled = true;
|
||||
this.disabledFile.Delete();
|
||||
}
|
||||
this.loader = PluginLoader.CreateFromAssemblyFile(this.DllFile.FullName, this.SetupLoaderConfig);
|
||||
|
||||
// This converts from the ".testing" file feature to the manifest instead.
|
||||
this.testingFile = LocalPluginManifest.GetTestingFile(this.DllFile);
|
||||
if (this.testingFile.Exists)
|
||||
{
|
||||
this.Manifest.Testing = true;
|
||||
this.testingFile.Delete();
|
||||
}
|
||||
|
||||
var pluginManager = Service<PluginManager>.Get();
|
||||
this.IsBanned = pluginManager.IsManifestBanned(this.Manifest);
|
||||
this.BanReason = pluginManager.GetBanReason(this.Manifest);
|
||||
|
||||
this.SaveManifest();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="DalamudPluginInterface"/> associated with this plugin.
|
||||
/// </summary>
|
||||
public DalamudPluginInterface DalamudInterface { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the path to the plugin DLL.
|
||||
/// </summary>
|
||||
public FileInfo DllFile { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the plugin manifest, if one exists.
|
||||
/// </summary>
|
||||
public LocalPluginManifest Manifest { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the current state of the plugin.
|
||||
/// </summary>
|
||||
public PluginState State { get; protected set; } = PluginState.Unloaded;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the AssemblyName plugin, populated during <see cref="Load(PluginLoadReason, bool)"/>.
|
||||
/// </summary>
|
||||
/// <returns>Plugin type.</returns>
|
||||
public AssemblyName? AssemblyName { get; private set; } = null;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the plugin name, directly from the plugin or if it is not loaded from the manifest.
|
||||
/// </summary>
|
||||
public string Name => this.instance?.Name ?? this.Manifest.Name ?? this.DllFile.Name;
|
||||
|
||||
/// <summary>
|
||||
/// Gets an optional reason, if the plugin is banned.
|
||||
/// </summary>
|
||||
public string BanReason { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the plugin is loaded and running.
|
||||
/// </summary>
|
||||
public bool IsLoaded => this.State == PluginState.Loaded;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the plugin is disabled.
|
||||
/// </summary>
|
||||
public bool IsDisabled => this.Manifest.Disabled;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this plugin's API level is out of date.
|
||||
/// </summary>
|
||||
public bool IsOutdated => this.Manifest.DalamudApiLevel < PluginManager.DalamudApiLevel;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the plugin is for testing use only.
|
||||
/// </summary>
|
||||
public bool IsTesting => this.Manifest.IsTestingExclusive || this.Manifest.Testing;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this plugin has been banned.
|
||||
/// </summary>
|
||||
public bool IsBanned { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this plugin is dev plugin.
|
||||
/// </summary>
|
||||
public bool IsDev => this is LocalDevPlugin;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Dispose()
|
||||
{
|
||||
this.instance?.Dispose();
|
||||
this.instance = null;
|
||||
|
||||
this.DalamudInterface?.Dispose();
|
||||
this.DalamudInterface = null;
|
||||
|
||||
this.pluginType = null;
|
||||
this.pluginAssembly = null;
|
||||
|
||||
this.loader?.Dispose();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Load this plugin.
|
||||
/// </summary>
|
||||
/// <param name="reason">The reason why this plugin is being loaded.</param>
|
||||
/// <param name="reloading">Load while reloading.</param>
|
||||
public void Load(PluginLoadReason reason, bool reloading = false)
|
||||
{
|
||||
var startInfo = Service<DalamudStartInfo>.Get();
|
||||
var configuration = Service<DalamudConfiguration>.Get();
|
||||
var pluginManager = Service<PluginManager>.Get();
|
||||
|
||||
// Allowed: Unloaded
|
||||
switch (this.State)
|
||||
{
|
||||
case PluginState.InProgress:
|
||||
throw new InvalidPluginOperationException($"Unable to load {this.Name}, already working");
|
||||
case PluginState.Loaded:
|
||||
throw new InvalidPluginOperationException($"Unable to load {this.Name}, already loaded");
|
||||
case PluginState.LoadError:
|
||||
throw new InvalidPluginOperationException($"Unable to load {this.Name}, load previously faulted, unload first");
|
||||
case PluginState.UnloadError:
|
||||
throw new InvalidPluginOperationException($"Unable to load {this.Name}, unload previously faulted, restart Dalamud");
|
||||
}
|
||||
|
||||
if (pluginManager.IsManifestBanned(this.Manifest))
|
||||
throw new BannedPluginException($"Unable to load {this.Name}, banned");
|
||||
|
||||
if (this.Manifest.ApplicableVersion < startInfo.GameVersion)
|
||||
throw new InvalidPluginOperationException($"Unable to load {this.Name}, no applicable version");
|
||||
|
||||
if (this.Manifest.DalamudApiLevel < PluginManager.DalamudApiLevel && !configuration.LoadAllApiLevels)
|
||||
throw new InvalidPluginOperationException($"Unable to load {this.Name}, incompatible API level");
|
||||
|
||||
if (this.Manifest.Disabled)
|
||||
throw new InvalidPluginOperationException($"Unable to load {this.Name}, disabled");
|
||||
|
||||
this.State = PluginState.InProgress;
|
||||
Log.Information($"Loading {this.DllFile.Name}");
|
||||
|
||||
if (this.DllFile.DirectoryName != null && File.Exists(Path.Combine(this.DllFile.DirectoryName, "Dalamud.dll")))
|
||||
{
|
||||
Log.Error("==== IMPORTANT MESSAGE TO {0}, THE DEVELOPER OF {1} ====", this.Manifest.Author, this.Manifest.InternalName);
|
||||
Log.Error("YOU ARE INCLUDING DALAMUD DEPENDENCIES IN YOUR BUILDS!!!");
|
||||
Log.Error("You may not be able to load your plugin. \"<Private>False</Private>\" needs to be set in your csproj.");
|
||||
Log.Error("If you are using ILMerge, do not merge anything other than your direct dependencies.");
|
||||
Log.Error("Do not merge FFXIVClientStructs.Generators.dll.");
|
||||
Log.Error("Please refer to https://github.com/goatcorp/Dalamud/discussions/603 for more information.");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
this.loader ??= PluginLoader.CreateFromAssemblyFile(this.DllFile.FullName, this.SetupLoaderConfig);
|
||||
|
||||
if (reloading)
|
||||
try
|
||||
{
|
||||
this.loader.Reload();
|
||||
this.pluginAssembly = this.loader.LoadDefaultAssembly();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.pluginAssembly = null;
|
||||
this.pluginType = null;
|
||||
this.loader.Dispose();
|
||||
|
||||
// Reload the manifest in-case there were changes here too.
|
||||
if (this.IsDev)
|
||||
Log.Error(ex, $"Not a plugin: {this.DllFile.FullName}");
|
||||
throw new InvalidPluginException(this.DllFile);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
this.pluginType = this.pluginAssembly.GetTypes().FirstOrDefault(type => type.IsAssignableTo(typeof(IDalamudPlugin)));
|
||||
}
|
||||
catch (ReflectionTypeLoadException ex)
|
||||
{
|
||||
Log.Error(ex, $"Could not load one or more types when searching for IDalamudPlugin: {this.DllFile.FullName}");
|
||||
// Something blew up when parsing types, but we still want to look for IDalamudPlugin. Let Load() handle the error.
|
||||
this.pluginType = ex.Types.FirstOrDefault(type => type.IsAssignableTo(typeof(IDalamudPlugin)));
|
||||
}
|
||||
|
||||
if (this.pluginType == default)
|
||||
{
|
||||
this.pluginAssembly = null;
|
||||
this.pluginType = null;
|
||||
this.loader.Dispose();
|
||||
|
||||
Log.Error($"Nothing inherits from IDalamudPlugin: {this.DllFile.FullName}");
|
||||
throw new InvalidPluginException(this.DllFile);
|
||||
}
|
||||
|
||||
var assemblyVersion = this.pluginAssembly.GetName().Version;
|
||||
|
||||
// Although it is conditionally used here, we need to set the initial value regardless.
|
||||
this.manifestFile = LocalPluginManifest.GetManifestFile(this.DllFile);
|
||||
|
||||
// If the parameter manifest was null
|
||||
if (manifest == null)
|
||||
{
|
||||
this.Manifest = new LocalPluginManifest()
|
||||
{
|
||||
var manifestFile = LocalPluginManifest.GetManifestFile(this.DllFile);
|
||||
if (manifestFile.Exists)
|
||||
{
|
||||
this.Manifest = LocalPluginManifest.Load(manifestFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
Author = "developer",
|
||||
Name = Path.GetFileNameWithoutExtension(this.DllFile.Name),
|
||||
InternalName = Path.GetFileNameWithoutExtension(this.DllFile.Name),
|
||||
AssemblyVersion = assemblyVersion,
|
||||
Description = string.Empty,
|
||||
ApplicableVersion = GameVersion.Any,
|
||||
DalamudApiLevel = PluginManager.DalamudApiLevel,
|
||||
IsHide = false,
|
||||
};
|
||||
|
||||
// Load the assembly
|
||||
this.pluginAssembly ??= this.loader.LoadDefaultAssembly();
|
||||
|
||||
this.AssemblyName = this.pluginAssembly.GetName();
|
||||
|
||||
// Find the plugin interface implementation. It is guaranteed to exist after checking in the ctor.
|
||||
this.pluginType ??= this.pluginAssembly.GetTypes().First(type => type.IsAssignableTo(typeof(IDalamudPlugin)));
|
||||
|
||||
// Check for any loaded plugins with the same assembly name
|
||||
var assemblyName = this.pluginAssembly.GetName().Name;
|
||||
foreach (var otherPlugin in pluginManager.InstalledPlugins)
|
||||
{
|
||||
// During hot-reloading, this plugin will be in the plugin list, and the instance will have been disposed
|
||||
if (otherPlugin == this || otherPlugin.instance == null)
|
||||
continue;
|
||||
|
||||
var otherPluginAssemblyName = otherPlugin.instance.GetType().Assembly.GetName().Name;
|
||||
if (otherPluginAssemblyName == assemblyName)
|
||||
{
|
||||
this.State = PluginState.Unloaded;
|
||||
Log.Debug($"Duplicate assembly: {this.Name}");
|
||||
|
||||
throw new DuplicatePluginException(assemblyName);
|
||||
}
|
||||
}
|
||||
|
||||
// Update the location for the Location and CodeBase patches
|
||||
PluginManager.PluginLocations[this.pluginType.Assembly.FullName] = new(this.DllFile);
|
||||
|
||||
this.DalamudInterface = new DalamudPluginInterface(this.pluginAssembly.GetName().Name!, this.DllFile, reason, this.IsDev);
|
||||
|
||||
var ioc = Service<ServiceContainer>.Get();
|
||||
this.instance = ioc.Create(this.pluginType, this.DalamudInterface) as IDalamudPlugin;
|
||||
if (this.instance == null)
|
||||
{
|
||||
this.State = PluginState.LoadError;
|
||||
this.DalamudInterface.Dispose();
|
||||
Log.Error($"Error while loading {this.Name}, failed to bind and call the plugin constructor");
|
||||
return;
|
||||
}
|
||||
|
||||
// In-case the manifest name was a placeholder. Can occur when no manifest was included.
|
||||
if (this.instance.Name != this.Manifest.Name)
|
||||
{
|
||||
this.Manifest.Name = this.instance.Name;
|
||||
// Save the manifest to disk so there won't be any problems later.
|
||||
// We'll update the name property after it can be retrieved from the instance.
|
||||
this.Manifest.Save(this.manifestFile);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.Manifest = manifest;
|
||||
}
|
||||
|
||||
this.State = PluginState.Loaded;
|
||||
Log.Information($"Finished loading {this.DllFile.Name}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.State = PluginState.LoadError;
|
||||
Log.Error(ex, $"Error while loading {this.Name}");
|
||||
// This converts from the ".disabled" file feature to the manifest instead.
|
||||
this.disabledFile = LocalPluginManifest.GetDisabledFile(this.DllFile);
|
||||
if (this.disabledFile.Exists)
|
||||
{
|
||||
this.Manifest.Disabled = true;
|
||||
this.disabledFile.Delete();
|
||||
}
|
||||
|
||||
throw;
|
||||
}
|
||||
}
|
||||
// This converts from the ".testing" file feature to the manifest instead.
|
||||
this.testingFile = LocalPluginManifest.GetTestingFile(this.DllFile);
|
||||
if (this.testingFile.Exists)
|
||||
{
|
||||
this.Manifest.Testing = true;
|
||||
this.testingFile.Delete();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unload this plugin. This is the same as dispose, but without the "disposed" connotations. This object should stay
|
||||
/// in the plugin list until it has been actually disposed.
|
||||
/// </summary>
|
||||
/// <param name="reloading">Unload while reloading.</param>
|
||||
public void Unload(bool reloading = false)
|
||||
{
|
||||
// Allowed: Loaded, LoadError(we are cleaning this up while we're at it)
|
||||
switch (this.State)
|
||||
{
|
||||
case PluginState.InProgress:
|
||||
throw new InvalidPluginOperationException($"Unable to unload {this.Name}, already working");
|
||||
case PluginState.Unloaded:
|
||||
throw new InvalidPluginOperationException($"Unable to unload {this.Name}, already unloaded");
|
||||
case PluginState.UnloadError:
|
||||
throw new InvalidPluginOperationException($"Unable to unload {this.Name}, unload previously faulted, restart Dalamud");
|
||||
var pluginManager = Service<PluginManager>.Get();
|
||||
this.IsBanned = pluginManager.IsManifestBanned(this.Manifest);
|
||||
this.BanReason = pluginManager.GetBanReason(this.Manifest);
|
||||
|
||||
this.SaveManifest();
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
this.State = PluginState.InProgress;
|
||||
Log.Information($"Unloading {this.DllFile.Name}");
|
||||
/// <summary>
|
||||
/// Gets the <see cref="DalamudPluginInterface"/> associated with this plugin.
|
||||
/// </summary>
|
||||
public DalamudPluginInterface DalamudInterface { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the path to the plugin DLL.
|
||||
/// </summary>
|
||||
public FileInfo DllFile { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the plugin manifest, if one exists.
|
||||
/// </summary>
|
||||
public LocalPluginManifest Manifest { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the current state of the plugin.
|
||||
/// </summary>
|
||||
public PluginState State { get; protected set; } = PluginState.Unloaded;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the AssemblyName plugin, populated during <see cref="Load(PluginLoadReason, bool)"/>.
|
||||
/// </summary>
|
||||
/// <returns>Plugin type.</returns>
|
||||
public AssemblyName? AssemblyName { get; private set; } = null;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the plugin name, directly from the plugin or if it is not loaded from the manifest.
|
||||
/// </summary>
|
||||
public string Name => this.instance?.Name ?? this.Manifest.Name ?? this.DllFile.Name;
|
||||
|
||||
/// <summary>
|
||||
/// Gets an optional reason, if the plugin is banned.
|
||||
/// </summary>
|
||||
public string BanReason { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the plugin is loaded and running.
|
||||
/// </summary>
|
||||
public bool IsLoaded => this.State == PluginState.Loaded;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the plugin is disabled.
|
||||
/// </summary>
|
||||
public bool IsDisabled => this.Manifest.Disabled;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this plugin's API level is out of date.
|
||||
/// </summary>
|
||||
public bool IsOutdated => this.Manifest.DalamudApiLevel < PluginManager.DalamudApiLevel;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the plugin is for testing use only.
|
||||
/// </summary>
|
||||
public bool IsTesting => this.Manifest.IsTestingExclusive || this.Manifest.Testing;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this plugin has been banned.
|
||||
/// </summary>
|
||||
public bool IsBanned { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this plugin is dev plugin.
|
||||
/// </summary>
|
||||
public bool IsDev => this is LocalDevPlugin;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Dispose()
|
||||
{
|
||||
this.instance?.Dispose();
|
||||
this.instance = null;
|
||||
|
||||
|
|
@ -378,83 +215,247 @@ internal class LocalPlugin : IDisposable
|
|||
this.pluginType = null;
|
||||
this.pluginAssembly = null;
|
||||
|
||||
if (!reloading)
|
||||
this.loader?.Dispose();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Load this plugin.
|
||||
/// </summary>
|
||||
/// <param name="reason">The reason why this plugin is being loaded.</param>
|
||||
/// <param name="reloading">Load while reloading.</param>
|
||||
public void Load(PluginLoadReason reason, bool reloading = false)
|
||||
{
|
||||
var startInfo = Service<DalamudStartInfo>.Get();
|
||||
var configuration = Service<DalamudConfiguration>.Get();
|
||||
var pluginManager = Service<PluginManager>.Get();
|
||||
|
||||
// Allowed: Unloaded
|
||||
switch (this.State)
|
||||
{
|
||||
this.loader?.Dispose();
|
||||
this.loader = null;
|
||||
case PluginState.InProgress:
|
||||
throw new InvalidPluginOperationException($"Unable to load {this.Name}, already working");
|
||||
case PluginState.Loaded:
|
||||
throw new InvalidPluginOperationException($"Unable to load {this.Name}, already loaded");
|
||||
case PluginState.LoadError:
|
||||
throw new InvalidPluginOperationException($"Unable to load {this.Name}, load previously faulted, unload first");
|
||||
case PluginState.UnloadError:
|
||||
throw new InvalidPluginOperationException($"Unable to load {this.Name}, unload previously faulted, restart Dalamud");
|
||||
}
|
||||
|
||||
this.State = PluginState.Unloaded;
|
||||
Log.Information($"Finished unloading {this.DllFile.Name}");
|
||||
if (pluginManager.IsManifestBanned(this.Manifest))
|
||||
throw new BannedPluginException($"Unable to load {this.Name}, banned");
|
||||
|
||||
if (this.Manifest.ApplicableVersion < startInfo.GameVersion)
|
||||
throw new InvalidPluginOperationException($"Unable to load {this.Name}, no applicable version");
|
||||
|
||||
if (this.Manifest.DalamudApiLevel < PluginManager.DalamudApiLevel && !configuration.LoadAllApiLevels)
|
||||
throw new InvalidPluginOperationException($"Unable to load {this.Name}, incompatible API level");
|
||||
|
||||
if (this.Manifest.Disabled)
|
||||
throw new InvalidPluginOperationException($"Unable to load {this.Name}, disabled");
|
||||
|
||||
this.State = PluginState.InProgress;
|
||||
Log.Information($"Loading {this.DllFile.Name}");
|
||||
|
||||
if (this.DllFile.DirectoryName != null && File.Exists(Path.Combine(this.DllFile.DirectoryName, "Dalamud.dll")))
|
||||
{
|
||||
Log.Error("==== IMPORTANT MESSAGE TO {0}, THE DEVELOPER OF {1} ====", this.Manifest.Author, this.Manifest.InternalName);
|
||||
Log.Error("YOU ARE INCLUDING DALAMUD DEPENDENCIES IN YOUR BUILDS!!!");
|
||||
Log.Error("You may not be able to load your plugin. \"<Private>False</Private>\" needs to be set in your csproj.");
|
||||
Log.Error("If you are using ILMerge, do not merge anything other than your direct dependencies.");
|
||||
Log.Error("Do not merge FFXIVClientStructs.Generators.dll.");
|
||||
Log.Error("Please refer to https://github.com/goatcorp/Dalamud/discussions/603 for more information.");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
this.loader ??= PluginLoader.CreateFromAssemblyFile(this.DllFile.FullName, this.SetupLoaderConfig);
|
||||
|
||||
if (reloading)
|
||||
{
|
||||
this.loader.Reload();
|
||||
|
||||
// Reload the manifest in-case there were changes here too.
|
||||
if (this.IsDev)
|
||||
{
|
||||
var manifestFile = LocalPluginManifest.GetManifestFile(this.DllFile);
|
||||
if (manifestFile.Exists)
|
||||
{
|
||||
this.Manifest = LocalPluginManifest.Load(manifestFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Load the assembly
|
||||
this.pluginAssembly ??= this.loader.LoadDefaultAssembly();
|
||||
|
||||
this.AssemblyName = this.pluginAssembly.GetName();
|
||||
|
||||
// Find the plugin interface implementation. It is guaranteed to exist after checking in the ctor.
|
||||
this.pluginType ??= this.pluginAssembly.GetTypes().First(type => type.IsAssignableTo(typeof(IDalamudPlugin)));
|
||||
|
||||
// Check for any loaded plugins with the same assembly name
|
||||
var assemblyName = this.pluginAssembly.GetName().Name;
|
||||
foreach (var otherPlugin in pluginManager.InstalledPlugins)
|
||||
{
|
||||
// During hot-reloading, this plugin will be in the plugin list, and the instance will have been disposed
|
||||
if (otherPlugin == this || otherPlugin.instance == null)
|
||||
continue;
|
||||
|
||||
var otherPluginAssemblyName = otherPlugin.instance.GetType().Assembly.GetName().Name;
|
||||
if (otherPluginAssemblyName == assemblyName)
|
||||
{
|
||||
this.State = PluginState.Unloaded;
|
||||
Log.Debug($"Duplicate assembly: {this.Name}");
|
||||
|
||||
throw new DuplicatePluginException(assemblyName);
|
||||
}
|
||||
}
|
||||
|
||||
// Update the location for the Location and CodeBase patches
|
||||
PluginManager.PluginLocations[this.pluginType.Assembly.FullName] = new(this.DllFile);
|
||||
|
||||
this.DalamudInterface = new DalamudPluginInterface(this.pluginAssembly.GetName().Name!, this.DllFile, reason, this.IsDev);
|
||||
|
||||
var ioc = Service<ServiceContainer>.Get();
|
||||
this.instance = ioc.Create(this.pluginType, this.DalamudInterface) as IDalamudPlugin;
|
||||
if (this.instance == null)
|
||||
{
|
||||
this.State = PluginState.LoadError;
|
||||
this.DalamudInterface.Dispose();
|
||||
Log.Error($"Error while loading {this.Name}, failed to bind and call the plugin constructor");
|
||||
return;
|
||||
}
|
||||
|
||||
// In-case the manifest name was a placeholder. Can occur when no manifest was included.
|
||||
if (this.instance.Name != this.Manifest.Name)
|
||||
{
|
||||
this.Manifest.Name = this.instance.Name;
|
||||
this.Manifest.Save(this.manifestFile);
|
||||
}
|
||||
|
||||
this.State = PluginState.Loaded;
|
||||
Log.Information($"Finished loading {this.DllFile.Name}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.State = PluginState.LoadError;
|
||||
Log.Error(ex, $"Error while loading {this.Name}");
|
||||
|
||||
throw;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
||||
/// <summary>
|
||||
/// Unload this plugin. This is the same as dispose, but without the "disposed" connotations. This object should stay
|
||||
/// in the plugin list until it has been actually disposed.
|
||||
/// </summary>
|
||||
/// <param name="reloading">Unload while reloading.</param>
|
||||
public void Unload(bool reloading = false)
|
||||
{
|
||||
this.State = PluginState.UnloadError;
|
||||
Log.Error(ex, $"Error while unloading {this.Name}");
|
||||
// Allowed: Loaded, LoadError(we are cleaning this up while we're at it)
|
||||
switch (this.State)
|
||||
{
|
||||
case PluginState.InProgress:
|
||||
throw new InvalidPluginOperationException($"Unable to unload {this.Name}, already working");
|
||||
case PluginState.Unloaded:
|
||||
throw new InvalidPluginOperationException($"Unable to unload {this.Name}, already unloaded");
|
||||
case PluginState.UnloadError:
|
||||
throw new InvalidPluginOperationException($"Unable to unload {this.Name}, unload previously faulted, restart Dalamud");
|
||||
}
|
||||
|
||||
throw;
|
||||
try
|
||||
{
|
||||
this.State = PluginState.InProgress;
|
||||
Log.Information($"Unloading {this.DllFile.Name}");
|
||||
|
||||
this.instance?.Dispose();
|
||||
this.instance = null;
|
||||
|
||||
this.DalamudInterface?.Dispose();
|
||||
this.DalamudInterface = null;
|
||||
|
||||
this.pluginType = null;
|
||||
this.pluginAssembly = null;
|
||||
|
||||
if (!reloading)
|
||||
{
|
||||
this.loader?.Dispose();
|
||||
this.loader = null;
|
||||
}
|
||||
|
||||
this.State = PluginState.Unloaded;
|
||||
Log.Information($"Finished unloading {this.DllFile.Name}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.State = PluginState.UnloadError;
|
||||
Log.Error(ex, $"Error while unloading {this.Name}");
|
||||
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reload this plugin.
|
||||
/// </summary>
|
||||
public void Reload()
|
||||
{
|
||||
this.Unload(true);
|
||||
this.Load(PluginLoadReason.Reload, true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Revert a disable. Must be unloaded first, does not load.
|
||||
/// </summary>
|
||||
public void Enable()
|
||||
{
|
||||
// Allowed: Unloaded, UnloadError
|
||||
switch (this.State)
|
||||
/// <summary>
|
||||
/// Reload this plugin.
|
||||
/// </summary>
|
||||
public void Reload()
|
||||
{
|
||||
case PluginState.InProgress:
|
||||
case PluginState.Loaded:
|
||||
case PluginState.LoadError:
|
||||
throw new InvalidPluginOperationException($"Unable to enable {this.Name}, still loaded");
|
||||
this.Unload(true);
|
||||
this.Load(PluginLoadReason.Reload, true);
|
||||
}
|
||||
|
||||
if (!this.Manifest.Disabled)
|
||||
throw new InvalidPluginOperationException($"Unable to enable {this.Name}, not disabled");
|
||||
|
||||
this.Manifest.Disabled = false;
|
||||
this.SaveManifest();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Disable this plugin, must be unloaded first.
|
||||
/// </summary>
|
||||
public void Disable()
|
||||
{
|
||||
// Allowed: Unloaded, UnloadError
|
||||
switch (this.State)
|
||||
/// <summary>
|
||||
/// Revert a disable. Must be unloaded first, does not load.
|
||||
/// </summary>
|
||||
public void Enable()
|
||||
{
|
||||
case PluginState.InProgress:
|
||||
case PluginState.Loaded:
|
||||
case PluginState.LoadError:
|
||||
throw new InvalidPluginOperationException($"Unable to disable {this.Name}, still loaded");
|
||||
// Allowed: Unloaded, UnloadError
|
||||
switch (this.State)
|
||||
{
|
||||
case PluginState.InProgress:
|
||||
case PluginState.Loaded:
|
||||
case PluginState.LoadError:
|
||||
throw new InvalidPluginOperationException($"Unable to enable {this.Name}, still loaded");
|
||||
}
|
||||
|
||||
if (!this.Manifest.Disabled)
|
||||
throw new InvalidPluginOperationException($"Unable to enable {this.Name}, not disabled");
|
||||
|
||||
this.Manifest.Disabled = false;
|
||||
this.SaveManifest();
|
||||
}
|
||||
|
||||
if (this.Manifest.Disabled)
|
||||
throw new InvalidPluginOperationException($"Unable to disable {this.Name}, already disabled");
|
||||
/// <summary>
|
||||
/// Disable this plugin, must be unloaded first.
|
||||
/// </summary>
|
||||
public void Disable()
|
||||
{
|
||||
// Allowed: Unloaded, UnloadError
|
||||
switch (this.State)
|
||||
{
|
||||
case PluginState.InProgress:
|
||||
case PluginState.Loaded:
|
||||
case PluginState.LoadError:
|
||||
throw new InvalidPluginOperationException($"Unable to disable {this.Name}, still loaded");
|
||||
}
|
||||
|
||||
this.Manifest.Disabled = true;
|
||||
this.SaveManifest();
|
||||
if (this.Manifest.Disabled)
|
||||
throw new InvalidPluginOperationException($"Unable to disable {this.Name}, already disabled");
|
||||
|
||||
this.Manifest.Disabled = true;
|
||||
this.SaveManifest();
|
||||
}
|
||||
|
||||
private void SetupLoaderConfig(LoaderConfig config)
|
||||
{
|
||||
config.IsUnloadable = true;
|
||||
config.LoadInMemory = true;
|
||||
config.PreferSharedTypes = false;
|
||||
config.SharedAssemblies.Add(typeof(Lumina.GameData).Assembly.GetName());
|
||||
config.SharedAssemblies.Add(typeof(Lumina.Excel.ExcelSheetImpl).Assembly.GetName());
|
||||
}
|
||||
|
||||
private void SaveManifest() => this.Manifest.Save(this.manifestFile);
|
||||
}
|
||||
|
||||
private void SetupLoaderConfig(LoaderConfig config)
|
||||
{
|
||||
config.IsUnloadable = true;
|
||||
config.LoadInMemory = true;
|
||||
config.PreferSharedTypes = false;
|
||||
config.SharedAssemblies.Add(typeof(Lumina.GameData).Assembly.GetName());
|
||||
config.SharedAssemblies.Add(typeof(Lumina.Excel.ExcelSheetImpl).Assembly.GetName());
|
||||
}
|
||||
|
||||
private void SaveManifest() => this.Manifest.Save(this.manifestFile);
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -9,102 +9,103 @@ using Dalamud.Plugin.Internal.Types;
|
|||
using Dalamud.Utility;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Dalamud.Plugin.Internal;
|
||||
|
||||
/// <summary>
|
||||
/// This class represents a single plugin repository.
|
||||
/// </summary>
|
||||
internal partial class PluginRepository
|
||||
namespace Dalamud.Plugin.Internal
|
||||
{
|
||||
// TODO: Change back to master after api4 release
|
||||
private const string DalamudPluginsMasterUrl = "https://raw.githubusercontent.com/goatcorp/DalamudPlugins/api4/pluginmaster.json";
|
||||
|
||||
private static readonly ModuleLog Log = new("PLUGINR");
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="PluginRepository"/> class.
|
||||
/// This class represents a single plugin repository.
|
||||
/// </summary>
|
||||
/// <param name="pluginMasterUrl">The plugin master URL.</param>
|
||||
/// <param name="isEnabled">Whether the plugin repo is enabled.</param>
|
||||
public PluginRepository(string pluginMasterUrl, bool isEnabled)
|
||||
internal partial class PluginRepository
|
||||
{
|
||||
this.PluginMasterUrl = pluginMasterUrl;
|
||||
this.IsThirdParty = pluginMasterUrl != DalamudPluginsMasterUrl;
|
||||
this.IsEnabled = isEnabled;
|
||||
}
|
||||
// TODO: Change back to master after api4 release
|
||||
private const string DalamudPluginsMasterUrl = "https://raw.githubusercontent.com/goatcorp/DalamudPlugins/api4/pluginmaster.json";
|
||||
|
||||
/// <summary>
|
||||
/// Gets a new instance of the <see cref="PluginRepository"/> class for the main repo.
|
||||
/// </summary>
|
||||
public static PluginRepository MainRepo => new(DalamudPluginsMasterUrl, true);
|
||||
private static readonly ModuleLog Log = new("PLUGINR");
|
||||
|
||||
/// <summary>
|
||||
/// Gets the pluginmaster.json URL.
|
||||
/// </summary>
|
||||
public string PluginMasterUrl { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this plugin repository is from a third party.
|
||||
/// </summary>
|
||||
public bool IsThirdParty { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this repo is enabled.
|
||||
/// </summary>
|
||||
public bool IsEnabled { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the plugin master list of available plugins.
|
||||
/// </summary>
|
||||
public ReadOnlyCollection<RemotePluginManifest>? PluginMaster { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the initialization state of the plugin repository.
|
||||
/// </summary>
|
||||
public PluginRepositoryState State { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Reload the plugin master asynchronously in a task.
|
||||
/// </summary>
|
||||
/// <returns>The new state.</returns>
|
||||
public async Task ReloadPluginMasterAsync()
|
||||
{
|
||||
this.State = PluginRepositoryState.InProgress;
|
||||
this.PluginMaster = new List<RemotePluginManifest>().AsReadOnly();
|
||||
|
||||
try
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="PluginRepository"/> class.
|
||||
/// </summary>
|
||||
/// <param name="pluginMasterUrl">The plugin master URL.</param>
|
||||
/// <param name="isEnabled">Whether the plugin repo is enabled.</param>
|
||||
public PluginRepository(string pluginMasterUrl, bool isEnabled)
|
||||
{
|
||||
Log.Information($"Fetching repo: {this.PluginMasterUrl}");
|
||||
|
||||
// ?ticks causes a cache invalidation. Get a fresh repo every time.
|
||||
using var response = await Util.HttpClient.GetAsync(this.PluginMasterUrl + "?" + DateTime.Now.Ticks);
|
||||
response.EnsureSuccessStatusCode();
|
||||
|
||||
var data = await response.Content.ReadAsStringAsync();
|
||||
var pluginMaster = JsonConvert.DeserializeObject<List<RemotePluginManifest>>(data);
|
||||
|
||||
if (pluginMaster == null)
|
||||
{
|
||||
throw new Exception("Deserialized PluginMaster was null.");
|
||||
}
|
||||
|
||||
pluginMaster.Sort((pm1, pm2) => pm1.Name.CompareTo(pm2.Name));
|
||||
|
||||
// Set the source for each remote manifest. Allows for checking if is 3rd party.
|
||||
foreach (var manifest in pluginMaster)
|
||||
{
|
||||
manifest.SourceRepo = this;
|
||||
}
|
||||
|
||||
this.PluginMaster = pluginMaster.AsReadOnly();
|
||||
|
||||
Log.Debug($"Successfully fetched repo: {this.PluginMasterUrl}");
|
||||
this.State = PluginRepositoryState.Success;
|
||||
this.PluginMasterUrl = pluginMasterUrl;
|
||||
this.IsThirdParty = pluginMasterUrl != DalamudPluginsMasterUrl;
|
||||
this.IsEnabled = isEnabled;
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
||||
/// <summary>
|
||||
/// Gets a new instance of the <see cref="PluginRepository"/> class for the main repo.
|
||||
/// </summary>
|
||||
public static PluginRepository MainRepo => new(DalamudPluginsMasterUrl, true);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the pluginmaster.json URL.
|
||||
/// </summary>
|
||||
public string PluginMasterUrl { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this plugin repository is from a third party.
|
||||
/// </summary>
|
||||
public bool IsThirdParty { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this repo is enabled.
|
||||
/// </summary>
|
||||
public bool IsEnabled { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the plugin master list of available plugins.
|
||||
/// </summary>
|
||||
public ReadOnlyCollection<RemotePluginManifest>? PluginMaster { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the initialization state of the plugin repository.
|
||||
/// </summary>
|
||||
public PluginRepositoryState State { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Reload the plugin master asynchronously in a task.
|
||||
/// </summary>
|
||||
/// <returns>The new state.</returns>
|
||||
public async Task ReloadPluginMasterAsync()
|
||||
{
|
||||
Log.Error(ex, $"PluginMaster failed: {this.PluginMasterUrl}");
|
||||
this.State = PluginRepositoryState.Fail;
|
||||
this.State = PluginRepositoryState.InProgress;
|
||||
this.PluginMaster = new List<RemotePluginManifest>().AsReadOnly();
|
||||
|
||||
try
|
||||
{
|
||||
Log.Information($"Fetching repo: {this.PluginMasterUrl}");
|
||||
|
||||
// ?ticks causes a cache invalidation. Get a fresh repo every time.
|
||||
using var response = await Util.HttpClient.GetAsync(this.PluginMasterUrl + "?" + DateTime.Now.Ticks);
|
||||
response.EnsureSuccessStatusCode();
|
||||
|
||||
var data = await response.Content.ReadAsStringAsync();
|
||||
var pluginMaster = JsonConvert.DeserializeObject<List<RemotePluginManifest>>(data);
|
||||
|
||||
if (pluginMaster == null)
|
||||
{
|
||||
throw new Exception("Deserialized PluginMaster was null.");
|
||||
}
|
||||
|
||||
pluginMaster.Sort((pm1, pm2) => pm1.Name.CompareTo(pm2.Name));
|
||||
|
||||
// Set the source for each remote manifest. Allows for checking if is 3rd party.
|
||||
foreach (var manifest in pluginMaster)
|
||||
{
|
||||
manifest.SourceRepo = this;
|
||||
}
|
||||
|
||||
this.PluginMaster = pluginMaster.AsReadOnly();
|
||||
|
||||
Log.Debug($"Successfully fetched repo: {this.PluginMasterUrl}");
|
||||
this.State = PluginRepositoryState.Success;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex, $"PluginMaster failed: {this.PluginMasterUrl}");
|
||||
this.State = PluginRepositoryState.Fail;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,35 +1,36 @@
|
|||
namespace Dalamud.Plugin.Internal.Types;
|
||||
|
||||
/// <summary>
|
||||
/// Information about an available plugin update.
|
||||
/// </summary>
|
||||
internal record AvailablePluginUpdate
|
||||
namespace Dalamud.Plugin.Internal.Types
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="AvailablePluginUpdate"/> class.
|
||||
/// Information about an available plugin update.
|
||||
/// </summary>
|
||||
/// <param name="installedPlugin">The installed plugin to update.</param>
|
||||
/// <param name="updateManifest">The manifest to use for the update.</param>
|
||||
/// <param name="useTesting">If the testing version should be used for the update.</param>
|
||||
public AvailablePluginUpdate(LocalPlugin installedPlugin, RemotePluginManifest updateManifest, bool useTesting)
|
||||
internal record AvailablePluginUpdate
|
||||
{
|
||||
this.InstalledPlugin = installedPlugin;
|
||||
this.UpdateManifest = updateManifest;
|
||||
this.UseTesting = useTesting;
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="AvailablePluginUpdate"/> class.
|
||||
/// </summary>
|
||||
/// <param name="installedPlugin">The installed plugin to update.</param>
|
||||
/// <param name="updateManifest">The manifest to use for the update.</param>
|
||||
/// <param name="useTesting">If the testing version should be used for the update.</param>
|
||||
public AvailablePluginUpdate(LocalPlugin installedPlugin, RemotePluginManifest updateManifest, bool useTesting)
|
||||
{
|
||||
this.InstalledPlugin = installedPlugin;
|
||||
this.UpdateManifest = updateManifest;
|
||||
this.UseTesting = useTesting;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the currently installed plugin.
|
||||
/// </summary>
|
||||
public LocalPlugin InstalledPlugin { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the available update manifest.
|
||||
/// </summary>
|
||||
public RemotePluginManifest UpdateManifest { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the update should use the testing URL.
|
||||
/// </summary>
|
||||
public bool UseTesting { get; init; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the currently installed plugin.
|
||||
/// </summary>
|
||||
public LocalPlugin InstalledPlugin { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the available update manifest.
|
||||
/// </summary>
|
||||
public RemotePluginManifest UpdateManifest { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the update should use the testing URL.
|
||||
/// </summary>
|
||||
public bool UseTesting { get; init; }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,78 +2,79 @@ using System.IO;
|
|||
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Dalamud.Plugin.Internal.Types;
|
||||
|
||||
/// <summary>
|
||||
/// Information about a plugin, packaged in a json file with the DLL. This variant includes additional information such as
|
||||
/// if the plugin is disabled and if it was installed from a testing URL. This is designed for use with manifests on disk.
|
||||
/// </summary>
|
||||
internal record LocalPluginManifest : PluginManifest
|
||||
namespace Dalamud.Plugin.Internal.Types
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether the plugin is disabled and should not be loaded.
|
||||
/// This value supercedes the ".disabled" file functionality and should not be included in the plugin master.
|
||||
/// Information about a plugin, packaged in a json file with the DLL. This variant includes additional information such as
|
||||
/// if the plugin is disabled and if it was installed from a testing URL. This is designed for use with manifests on disk.
|
||||
/// </summary>
|
||||
public bool Disabled { get; set; } = false;
|
||||
internal record LocalPluginManifest : PluginManifest
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether the plugin is disabled and should not be loaded.
|
||||
/// This value supercedes the ".disabled" file functionality and should not be included in the plugin master.
|
||||
/// </summary>
|
||||
public bool Disabled { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether the plugin should only be loaded when testing is enabled.
|
||||
/// This value supercedes the ".testing" file functionality and should not be included in the plugin master.
|
||||
/// </summary>
|
||||
public bool Testing { get; set; } = false;
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether the plugin should only be loaded when testing is enabled.
|
||||
/// This value supercedes the ".testing" file functionality and should not be included in the plugin master.
|
||||
/// </summary>
|
||||
public bool Testing { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the 3rd party repo URL that this plugin was installed from. Used to display where the plugin was
|
||||
/// sourced from on the installed plugin view. This should not be included in the plugin master. This value is null
|
||||
/// when installed from the main repo.
|
||||
/// </summary>
|
||||
public string InstalledFromUrl { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the 3rd party repo URL that this plugin was installed from. Used to display where the plugin was
|
||||
/// sourced from on the installed plugin view. This should not be included in the plugin master. This value is null
|
||||
/// when installed from the main repo.
|
||||
/// </summary>
|
||||
public string InstalledFromUrl { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this manifest is associated with a plugin that was installed from a third party
|
||||
/// repo. Unless the manifest has been manually modified, this is determined by the InstalledFromUrl being null.
|
||||
/// </summary>
|
||||
public bool IsThirdParty => !string.IsNullOrEmpty(this.InstalledFromUrl);
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this manifest is associated with a plugin that was installed from a third party
|
||||
/// repo. Unless the manifest has been manually modified, this is determined by the InstalledFromUrl being null.
|
||||
/// </summary>
|
||||
public bool IsThirdParty => !string.IsNullOrEmpty(this.InstalledFromUrl);
|
||||
|
||||
/// <summary>
|
||||
/// Save a plugin manifest to file.
|
||||
/// </summary>
|
||||
/// <param name="manifestFile">Path to save at.</param>
|
||||
public void Save(FileInfo manifestFile) => File.WriteAllText(manifestFile.FullName, JsonConvert.SerializeObject(this, Formatting.Indented));
|
||||
/// <summary>
|
||||
/// Save a plugin manifest to file.
|
||||
/// </summary>
|
||||
/// <param name="manifestFile">Path to save at.</param>
|
||||
public void Save(FileInfo manifestFile) => File.WriteAllText(manifestFile.FullName, JsonConvert.SerializeObject(this, Formatting.Indented));
|
||||
|
||||
/// <summary>
|
||||
/// Loads a plugin manifest from file.
|
||||
/// </summary>
|
||||
/// <param name="manifestFile">Path to the manifest.</param>
|
||||
/// <returns>A <see cref="PluginManifest"/> object.</returns>
|
||||
public static LocalPluginManifest Load(FileInfo manifestFile) => JsonConvert.DeserializeObject<LocalPluginManifest>(File.ReadAllText(manifestFile.FullName));
|
||||
/// <summary>
|
||||
/// Loads a plugin manifest from file.
|
||||
/// </summary>
|
||||
/// <param name="manifestFile">Path to the manifest.</param>
|
||||
/// <returns>A <see cref="PluginManifest"/> object.</returns>
|
||||
public static LocalPluginManifest Load(FileInfo manifestFile) => JsonConvert.DeserializeObject<LocalPluginManifest>(File.ReadAllText(manifestFile.FullName));
|
||||
|
||||
/// <summary>
|
||||
/// A standardized way to get the plugin DLL name that should accompany a manifest file. May not exist.
|
||||
/// </summary>
|
||||
/// <param name="dir">Manifest directory.</param>
|
||||
/// <param name="manifest">The manifest.</param>
|
||||
/// <returns>The <see cref="LocalPlugin"/> file.</returns>
|
||||
public static FileInfo GetPluginFile(DirectoryInfo dir, PluginManifest manifest) => new(Path.Combine(dir.FullName, $"{manifest.InternalName}.dll"));
|
||||
/// <summary>
|
||||
/// A standardized way to get the plugin DLL name that should accompany a manifest file. May not exist.
|
||||
/// </summary>
|
||||
/// <param name="dir">Manifest directory.</param>
|
||||
/// <param name="manifest">The manifest.</param>
|
||||
/// <returns>The <see cref="LocalPlugin"/> file.</returns>
|
||||
public static FileInfo GetPluginFile(DirectoryInfo dir, PluginManifest manifest) => new(Path.Combine(dir.FullName, $"{manifest.InternalName}.dll"));
|
||||
|
||||
/// <summary>
|
||||
/// A standardized way to get the manifest file that should accompany a plugin DLL. May not exist.
|
||||
/// </summary>
|
||||
/// <param name="dllFile">The plugin DLL.</param>
|
||||
/// <returns>The <see cref="PluginManifest"/> file.</returns>
|
||||
public static FileInfo GetManifestFile(FileInfo dllFile) => new(Path.Combine(dllFile.DirectoryName, Path.GetFileNameWithoutExtension(dllFile.Name) + ".json"));
|
||||
/// <summary>
|
||||
/// A standardized way to get the manifest file that should accompany a plugin DLL. May not exist.
|
||||
/// </summary>
|
||||
/// <param name="dllFile">The plugin DLL.</param>
|
||||
/// <returns>The <see cref="PluginManifest"/> file.</returns>
|
||||
public static FileInfo GetManifestFile(FileInfo dllFile) => new(Path.Combine(dllFile.DirectoryName, Path.GetFileNameWithoutExtension(dllFile.Name) + ".json"));
|
||||
|
||||
/// <summary>
|
||||
/// A standardized way to get the obsolete .disabled file that should accompany a plugin DLL. May not exist.
|
||||
/// </summary>
|
||||
/// <param name="dllFile">The plugin DLL.</param>
|
||||
/// <returns>The <see cref="PluginManifest"/> .disabled file.</returns>
|
||||
public static FileInfo GetDisabledFile(FileInfo dllFile) => new(Path.Combine(dllFile.DirectoryName, ".disabled"));
|
||||
/// <summary>
|
||||
/// A standardized way to get the obsolete .disabled file that should accompany a plugin DLL. May not exist.
|
||||
/// </summary>
|
||||
/// <param name="dllFile">The plugin DLL.</param>
|
||||
/// <returns>The <see cref="PluginManifest"/> .disabled file.</returns>
|
||||
public static FileInfo GetDisabledFile(FileInfo dllFile) => new(Path.Combine(dllFile.DirectoryName, ".disabled"));
|
||||
|
||||
/// <summary>
|
||||
/// A standardized way to get the obsolete .testing file that should accompany a plugin DLL. May not exist.
|
||||
/// </summary>
|
||||
/// <param name="dllFile">The plugin DLL.</param>
|
||||
/// <returns>The <see cref="PluginManifest"/> .testing file.</returns>
|
||||
public static FileInfo GetTestingFile(FileInfo dllFile) => new(Path.Combine(dllFile.DirectoryName, ".testing"));
|
||||
/// <summary>
|
||||
/// A standardized way to get the obsolete .testing file that should accompany a plugin DLL. May not exist.
|
||||
/// </summary>
|
||||
/// <param name="dllFile">The plugin DLL.</param>
|
||||
/// <returns>The <see cref="PluginManifest"/> .testing file.</returns>
|
||||
public static FileInfo GetTestingFile(FileInfo dllFile) => new(Path.Combine(dllFile.DirectoryName, ".testing"));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,161 +4,162 @@ using System.Collections.Generic;
|
|||
using Dalamud.Game;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Dalamud.Plugin.Internal.Types;
|
||||
|
||||
/// <summary>
|
||||
/// Information about a plugin, packaged in a json file with the DLL.
|
||||
/// </summary>
|
||||
internal record PluginManifest
|
||||
namespace Dalamud.Plugin.Internal.Types
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the author/s of the plugin.
|
||||
/// Information about a plugin, packaged in a json file with the DLL.
|
||||
/// </summary>
|
||||
[JsonProperty]
|
||||
public string Author { get; init; }
|
||||
internal record PluginManifest
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the author/s of the plugin.
|
||||
/// </summary>
|
||||
[JsonProperty]
|
||||
public string Author { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the public name of the plugin.
|
||||
/// </summary>
|
||||
[JsonProperty]
|
||||
public string Name { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the public name of the plugin.
|
||||
/// </summary>
|
||||
[JsonProperty]
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a punchline of the plugins functions.
|
||||
/// </summary>
|
||||
[JsonProperty]
|
||||
public string? Punchline { get; init; }
|
||||
/// <summary>
|
||||
/// Gets a punchline of the plugins functions.
|
||||
/// </summary>
|
||||
[JsonProperty]
|
||||
public string? Punchline { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a description of the plugins functions.
|
||||
/// </summary>
|
||||
[JsonProperty]
|
||||
public string? Description { get; init; }
|
||||
/// <summary>
|
||||
/// Gets a description of the plugins functions.
|
||||
/// </summary>
|
||||
[JsonProperty]
|
||||
public string? Description { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a changelog.
|
||||
/// </summary>
|
||||
[JsonProperty]
|
||||
public string? Changelog { get; init; }
|
||||
/// <summary>
|
||||
/// Gets a changelog.
|
||||
/// </summary>
|
||||
[JsonProperty]
|
||||
public string? Changelog { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a list of tags defined on the plugin.
|
||||
/// </summary>
|
||||
[JsonProperty]
|
||||
public List<string>? Tags { get; init; }
|
||||
/// <summary>
|
||||
/// Gets a list of tags defined on the plugin.
|
||||
/// </summary>
|
||||
[JsonProperty]
|
||||
public List<string>? Tags { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a list of category tags defined on the plugin.
|
||||
/// </summary>
|
||||
[JsonProperty]
|
||||
public List<string>? CategoryTags { get; init; }
|
||||
/// <summary>
|
||||
/// Gets a list of category tags defined on the plugin.
|
||||
/// </summary>
|
||||
[JsonProperty]
|
||||
public List<string>? CategoryTags { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether or not the plugin is hidden in the plugin installer.
|
||||
/// This value comes from the plugin master and is in addition to the list of hidden names kept by Dalamud.
|
||||
/// </summary>
|
||||
[JsonProperty]
|
||||
public bool IsHide { get; init; }
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether or not the plugin is hidden in the plugin installer.
|
||||
/// This value comes from the plugin master and is in addition to the list of hidden names kept by Dalamud.
|
||||
/// </summary>
|
||||
[JsonProperty]
|
||||
public bool IsHide { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the internal name of the plugin, which should match the assembly name of the plugin.
|
||||
/// </summary>
|
||||
[JsonProperty]
|
||||
public string InternalName { get; init; }
|
||||
/// <summary>
|
||||
/// Gets the internal name of the plugin, which should match the assembly name of the plugin.
|
||||
/// </summary>
|
||||
[JsonProperty]
|
||||
public string InternalName { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current assembly version of the plugin.
|
||||
/// </summary>
|
||||
[JsonProperty]
|
||||
public Version AssemblyVersion { get; init; }
|
||||
/// <summary>
|
||||
/// Gets the current assembly version of the plugin.
|
||||
/// </summary>
|
||||
[JsonProperty]
|
||||
public Version AssemblyVersion { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current testing assembly version of the plugin.
|
||||
/// </summary>
|
||||
[JsonProperty]
|
||||
public Version? TestingAssemblyVersion { get; init; }
|
||||
/// <summary>
|
||||
/// Gets the current testing assembly version of the plugin.
|
||||
/// </summary>
|
||||
[JsonProperty]
|
||||
public Version? TestingAssemblyVersion { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the <see cref="AssemblyVersion"/> is not null.
|
||||
/// </summary>
|
||||
[JsonIgnore]
|
||||
public bool HasAssemblyVersion => this.AssemblyVersion != null;
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the <see cref="AssemblyVersion"/> is not null.
|
||||
/// </summary>
|
||||
[JsonIgnore]
|
||||
public bool HasAssemblyVersion => this.AssemblyVersion != null;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the <see cref="TestingAssemblyVersion"/> is not null.
|
||||
/// </summary>
|
||||
[JsonIgnore]
|
||||
public bool HasTestingAssemblyVersion => this.TestingAssemblyVersion != null;
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the <see cref="TestingAssemblyVersion"/> is not null.
|
||||
/// </summary>
|
||||
[JsonIgnore]
|
||||
public bool HasTestingAssemblyVersion => this.TestingAssemblyVersion != null;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the plugin is only available for testing.
|
||||
/// </summary>
|
||||
[JsonProperty]
|
||||
public bool IsTestingExclusive { get; init; }
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the plugin is only available for testing.
|
||||
/// </summary>
|
||||
[JsonProperty]
|
||||
public bool IsTestingExclusive { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets an URL to the website or source code of the plugin.
|
||||
/// </summary>
|
||||
[JsonProperty]
|
||||
public string? RepoUrl { get; init; }
|
||||
/// <summary>
|
||||
/// Gets an URL to the website or source code of the plugin.
|
||||
/// </summary>
|
||||
[JsonProperty]
|
||||
public string? RepoUrl { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the version of the game this plugin works with.
|
||||
/// </summary>
|
||||
[JsonProperty]
|
||||
[JsonConverter(typeof(GameVersionConverter))]
|
||||
public GameVersion? ApplicableVersion { get; init; } = GameVersion.Any;
|
||||
/// <summary>
|
||||
/// Gets the version of the game this plugin works with.
|
||||
/// </summary>
|
||||
[JsonProperty]
|
||||
[JsonConverter(typeof(GameVersionConverter))]
|
||||
public GameVersion? ApplicableVersion { get; init; } = GameVersion.Any;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the API level of this plugin. For the current API level, please see <see cref="PluginManager.DalamudApiLevel"/>
|
||||
/// for the currently used API level.
|
||||
/// </summary>
|
||||
[JsonProperty]
|
||||
public int DalamudApiLevel { get; init; } = PluginManager.DalamudApiLevel;
|
||||
/// <summary>
|
||||
/// Gets the API level of this plugin. For the current API level, please see <see cref="PluginManager.DalamudApiLevel"/>
|
||||
/// for the currently used API level.
|
||||
/// </summary>
|
||||
[JsonProperty]
|
||||
public int DalamudApiLevel { get; init; } = PluginManager.DalamudApiLevel;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the number of downloads this plugin has.
|
||||
/// </summary>
|
||||
[JsonProperty]
|
||||
public long DownloadCount { get; init; }
|
||||
/// <summary>
|
||||
/// Gets the number of downloads this plugin has.
|
||||
/// </summary>
|
||||
[JsonProperty]
|
||||
public long DownloadCount { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the last time this plugin was updated.
|
||||
/// </summary>
|
||||
[JsonProperty]
|
||||
public long LastUpdate { get; init; }
|
||||
/// <summary>
|
||||
/// Gets the last time this plugin was updated.
|
||||
/// </summary>
|
||||
[JsonProperty]
|
||||
public long LastUpdate { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the download link used to install the plugin.
|
||||
/// </summary>
|
||||
[JsonProperty]
|
||||
public string DownloadLinkInstall { get; init; }
|
||||
/// <summary>
|
||||
/// Gets the download link used to install the plugin.
|
||||
/// </summary>
|
||||
[JsonProperty]
|
||||
public string DownloadLinkInstall { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the download link used to update the plugin.
|
||||
/// </summary>
|
||||
[JsonProperty]
|
||||
public string DownloadLinkUpdate { get; init; }
|
||||
/// <summary>
|
||||
/// Gets the download link used to update the plugin.
|
||||
/// </summary>
|
||||
[JsonProperty]
|
||||
public string DownloadLinkUpdate { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the download link used to get testing versions of the plugin.
|
||||
/// </summary>
|
||||
[JsonProperty]
|
||||
public string DownloadLinkTesting { get; init; }
|
||||
/// <summary>
|
||||
/// Gets the download link used to get testing versions of the plugin.
|
||||
/// </summary>
|
||||
[JsonProperty]
|
||||
public string DownloadLinkTesting { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the load priority for this plugin. Higher values means higher priority. 0 is default priority.
|
||||
/// </summary>
|
||||
[JsonProperty]
|
||||
public int LoadPriority { get; init; }
|
||||
/// <summary>
|
||||
/// Gets the load priority for this plugin. Higher values means higher priority. 0 is default priority.
|
||||
/// </summary>
|
||||
[JsonProperty]
|
||||
public int LoadPriority { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a list of screenshot image URLs to show in the plugin installer.
|
||||
/// </summary>
|
||||
public List<string>? ImageUrls { get; init; }
|
||||
/// <summary>
|
||||
/// Gets a list of screenshot image URLs to show in the plugin installer.
|
||||
/// </summary>
|
||||
public List<string>? ImageUrls { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets an URL for the plugin's icon.
|
||||
/// </summary>
|
||||
public string? IconUrl { get; init; }
|
||||
/// <summary>
|
||||
/// Gets an URL for the plugin's icon.
|
||||
/// </summary>
|
||||
public string? IconUrl { get; init; }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,27 +1,28 @@
|
|||
namespace Dalamud.Plugin.Internal.Types;
|
||||
|
||||
/// <summary>
|
||||
/// Values representing plugin repository state.
|
||||
/// </summary>
|
||||
internal enum PluginRepositoryState
|
||||
namespace Dalamud.Plugin.Internal.Types
|
||||
{
|
||||
/// <summary>
|
||||
/// State is unknown.
|
||||
/// Values representing plugin repository state.
|
||||
/// </summary>
|
||||
Unknown,
|
||||
internal enum PluginRepositoryState
|
||||
{
|
||||
/// <summary>
|
||||
/// State is unknown.
|
||||
/// </summary>
|
||||
Unknown,
|
||||
|
||||
/// <summary>
|
||||
/// Currently loading.
|
||||
/// </summary>
|
||||
InProgress,
|
||||
/// <summary>
|
||||
/// Currently loading.
|
||||
/// </summary>
|
||||
InProgress,
|
||||
|
||||
/// <summary>
|
||||
/// Load was successful.
|
||||
/// </summary>
|
||||
Success,
|
||||
/// <summary>
|
||||
/// Load was successful.
|
||||
/// </summary>
|
||||
Success,
|
||||
|
||||
/// <summary>
|
||||
/// Load failed.
|
||||
/// </summary>
|
||||
Fail,
|
||||
/// <summary>
|
||||
/// Load failed.
|
||||
/// </summary>
|
||||
Fail,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,32 +1,33 @@
|
|||
namespace Dalamud.Plugin.Internal.Types;
|
||||
|
||||
/// <summary>
|
||||
/// Values representing plugin load state.
|
||||
/// </summary>
|
||||
internal enum PluginState
|
||||
namespace Dalamud.Plugin.Internal.Types
|
||||
{
|
||||
/// <summary>
|
||||
/// Plugin is defined, but unloaded.
|
||||
/// Values representing plugin load state.
|
||||
/// </summary>
|
||||
Unloaded,
|
||||
internal enum PluginState
|
||||
{
|
||||
/// <summary>
|
||||
/// Plugin is defined, but unloaded.
|
||||
/// </summary>
|
||||
Unloaded,
|
||||
|
||||
/// <summary>
|
||||
/// Plugin has thrown an error during unload.
|
||||
/// </summary>
|
||||
UnloadError,
|
||||
/// <summary>
|
||||
/// Plugin has thrown an error during unload.
|
||||
/// </summary>
|
||||
UnloadError,
|
||||
|
||||
/// <summary>
|
||||
/// Currently loading.
|
||||
/// </summary>
|
||||
InProgress,
|
||||
/// <summary>
|
||||
/// Currently loading.
|
||||
/// </summary>
|
||||
InProgress,
|
||||
|
||||
/// <summary>
|
||||
/// Load is successful.
|
||||
/// </summary>
|
||||
Loaded,
|
||||
/// <summary>
|
||||
/// Load is successful.
|
||||
/// </summary>
|
||||
Loaded,
|
||||
|
||||
/// <summary>
|
||||
/// Plugin has thrown an error during loading.
|
||||
/// </summary>
|
||||
LoadError,
|
||||
/// <summary>
|
||||
/// Plugin has thrown an error during loading.
|
||||
/// </summary>
|
||||
LoadError,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,29 +1,30 @@
|
|||
using System;
|
||||
|
||||
namespace Dalamud.Plugin.Internal.Types;
|
||||
|
||||
/// <summary>
|
||||
/// Plugin update status.
|
||||
/// </summary>
|
||||
internal class PluginUpdateStatus
|
||||
namespace Dalamud.Plugin.Internal.Types
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the plugin internal name.
|
||||
/// Plugin update status.
|
||||
/// </summary>
|
||||
public string InternalName { get; set; }
|
||||
internal class PluginUpdateStatus
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the plugin internal name.
|
||||
/// </summary>
|
||||
public string InternalName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the plugin name.
|
||||
/// </summary>
|
||||
public string Name { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the plugin name.
|
||||
/// </summary>
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the plugin version.
|
||||
/// </summary>
|
||||
public Version Version { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the plugin version.
|
||||
/// </summary>
|
||||
public Version Version { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether the plugin was updated.
|
||||
/// </summary>
|
||||
public bool WasUpdated { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether the plugin was updated.
|
||||
/// </summary>
|
||||
public bool WasUpdated { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,17 +1,18 @@
|
|||
using Newtonsoft.Json;
|
||||
|
||||
namespace Dalamud.Plugin.Internal.Types;
|
||||
|
||||
/// <summary>
|
||||
/// Information about a plugin, packaged in a json file with the DLL. This variant includes additional information such as
|
||||
/// if the plugin is disabled and if it was installed from a testing URL. This is designed for use with manifests on disk.
|
||||
/// </summary>
|
||||
internal record RemotePluginManifest : PluginManifest
|
||||
namespace Dalamud.Plugin.Internal.Types
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the plugin repository this manifest came from. Used in reporting which third party repo a manifest
|
||||
/// may have come from in the plugins available view. This functionality should not be included in the plugin master.
|
||||
/// Information about a plugin, packaged in a json file with the DLL. This variant includes additional information such as
|
||||
/// if the plugin is disabled and if it was installed from a testing URL. This is designed for use with manifests on disk.
|
||||
/// </summary>
|
||||
[JsonIgnore]
|
||||
public PluginRepository SourceRepo { get; set; } = null;
|
||||
internal record RemotePluginManifest : PluginManifest
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the plugin repository this manifest came from. Used in reporting which third party repo a manifest
|
||||
/// may have come from in the plugins available view. This functionality should not be included in the plugin master.
|
||||
/// </summary>
|
||||
[JsonIgnore]
|
||||
public PluginRepository SourceRepo { get; set; } = null;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,35 +1,36 @@
|
|||
using System;
|
||||
|
||||
namespace Dalamud.Plugin.Ipc.Exceptions;
|
||||
|
||||
/// <summary>
|
||||
/// This exception is thrown when an IPC errors are encountered.
|
||||
/// </summary>
|
||||
public abstract class IpcError : Exception
|
||||
namespace Dalamud.Plugin.Ipc.Exceptions
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="IpcError"/> class.
|
||||
/// This exception is thrown when an IPC errors are encountered.
|
||||
/// </summary>
|
||||
public IpcError()
|
||||
public abstract class IpcError : Exception
|
||||
{
|
||||
}
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="IpcError"/> class.
|
||||
/// </summary>
|
||||
public IpcError()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="IpcError"/> class.
|
||||
/// </summary>
|
||||
/// <param name="message">The message that describes the error.</param>
|
||||
public IpcError(string message)
|
||||
: base(message)
|
||||
{
|
||||
}
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="IpcError"/> class.
|
||||
/// </summary>
|
||||
/// <param name="message">The message that describes the error.</param>
|
||||
public IpcError(string message)
|
||||
: base(message)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="IpcError"/> class.
|
||||
/// </summary>
|
||||
/// <param name="message">The message that describes the error.</param>
|
||||
/// <param name="ex">The exception that is the cause of the current exception.</param>
|
||||
public IpcError(string message, Exception ex)
|
||||
: base(message, ex)
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="IpcError"/> class.
|
||||
/// </summary>
|
||||
/// <param name="message">The message that describes the error.</param>
|
||||
/// <param name="ex">The exception that is the cause of the current exception.</param>
|
||||
public IpcError(string message, Exception ex)
|
||||
: base(message, ex)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,18 +1,19 @@
|
|||
namespace Dalamud.Plugin.Ipc.Exceptions;
|
||||
|
||||
/// <summary>
|
||||
/// This exception is thrown when an IPC method is invoked and the number of types does not match what was previously registered.
|
||||
/// </summary>
|
||||
public class IpcLengthMismatchError : IpcError
|
||||
namespace Dalamud.Plugin.Ipc.Exceptions
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="IpcLengthMismatchError"/> class.
|
||||
/// This exception is thrown when an IPC method is invoked and the number of types does not match what was previously registered.
|
||||
/// </summary>
|
||||
/// <param name="name">Name of the IPC method.</param>
|
||||
/// <param name="requestedLength">The amount of types requested when checking out the IPC.</param>
|
||||
/// <param name="actualLength">The amount of types registered by the IPC.</param>
|
||||
public IpcLengthMismatchError(string name, int requestedLength, int actualLength)
|
||||
: base($"IPC method {name} has a different number of types than was requested. {requestedLength} != {actualLength}")
|
||||
public class IpcLengthMismatchError : IpcError
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="IpcLengthMismatchError"/> class.
|
||||
/// </summary>
|
||||
/// <param name="name">Name of the IPC method.</param>
|
||||
/// <param name="requestedLength">The amount of types requested when checking out the IPC.</param>
|
||||
/// <param name="actualLength">The amount of types registered by the IPC.</param>
|
||||
public IpcLengthMismatchError(string name, int requestedLength, int actualLength)
|
||||
: base($"IPC method {name} has a different number of types than was requested. {requestedLength} != {actualLength}")
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,16 +1,17 @@
|
|||
namespace Dalamud.Plugin.Ipc.Exceptions;
|
||||
|
||||
/// <summary>
|
||||
/// This exception is thrown when an IPC method is invoked, but no actions or funcs have been registered yet.
|
||||
/// </summary>
|
||||
public class IpcNotReadyError : IpcError
|
||||
namespace Dalamud.Plugin.Ipc.Exceptions
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="IpcNotReadyError"/> class.
|
||||
/// This exception is thrown when an IPC method is invoked, but no actions or funcs have been registered yet.
|
||||
/// </summary>
|
||||
/// <param name="name">Name of the IPC method.</param>
|
||||
public IpcNotReadyError(string name)
|
||||
: base($"IPC method {name} was not registered yet")
|
||||
public class IpcNotReadyError : IpcError
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="IpcNotReadyError"/> class.
|
||||
/// </summary>
|
||||
/// <param name="name">Name of the IPC method.</param>
|
||||
public IpcNotReadyError(string name)
|
||||
: base($"IPC method {name} was not registered yet")
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,21 +1,22 @@
|
|||
using System;
|
||||
|
||||
namespace Dalamud.Plugin.Ipc.Exceptions;
|
||||
|
||||
/// <summary>
|
||||
/// This exception is thrown when an IPC method is checked out, but the type does not match what was previously registered.
|
||||
/// </summary>
|
||||
public class IpcTypeMismatchError : IpcError
|
||||
namespace Dalamud.Plugin.Ipc.Exceptions
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="IpcTypeMismatchError"/> class.
|
||||
/// This exception is thrown when an IPC method is checked out, but the type does not match what was previously registered.
|
||||
/// </summary>
|
||||
/// <param name="name">Name of the IPC method.</param>
|
||||
/// <param name="requestedType">The before type.</param>
|
||||
/// <param name="actualType">The after type.</param>
|
||||
/// <param name="ex">The exception that is the cause of the current exception.</param>
|
||||
public IpcTypeMismatchError(string name, Type requestedType, Type actualType, Exception ex)
|
||||
: base($"IPC method {name} blew up when converting from {requestedType.Name} to {actualType}", ex)
|
||||
public class IpcTypeMismatchError : IpcError
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="IpcTypeMismatchError"/> class.
|
||||
/// </summary>
|
||||
/// <param name="name">Name of the IPC method.</param>
|
||||
/// <param name="requestedType">The before type.</param>
|
||||
/// <param name="actualType">The after type.</param>
|
||||
/// <param name="ex">The exception that is the cause of the current exception.</param>
|
||||
public IpcTypeMismatchError(string name, Type requestedType, Type actualType, Exception ex)
|
||||
: base($"IPC method {name} blew up when converting from {requestedType.Name} to {actualType}", ex)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,177 +4,178 @@ using Dalamud.Plugin.Ipc.Internal;
|
|||
|
||||
#pragma warning disable SA1402 // File may only contain a single type
|
||||
|
||||
namespace Dalamud.Plugin.Ipc;
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase"/>
|
||||
public interface ICallGateProvider<TRet>
|
||||
namespace Dalamud.Plugin.Ipc
|
||||
{
|
||||
/// <inheritdoc cref="CallGatePubSubBase.RegisterAction"/>
|
||||
public void RegisterAction(Action action);
|
||||
/// <inheritdoc cref="CallGatePubSubBase"/>
|
||||
public interface ICallGateProvider<TRet>
|
||||
{
|
||||
/// <inheritdoc cref="CallGatePubSubBase.RegisterAction"/>
|
||||
public void RegisterAction(Action action);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.RegisterFunc"/>
|
||||
public void RegisterFunc(Func<TRet> func);
|
||||
/// <inheritdoc cref="CallGatePubSubBase.RegisterFunc"/>
|
||||
public void RegisterFunc(Func<TRet> func);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.UnregisterAction"/>
|
||||
public void UnregisterAction();
|
||||
/// <inheritdoc cref="CallGatePubSubBase.UnregisterAction"/>
|
||||
public void UnregisterAction();
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.UnregisterFunc"/>
|
||||
public void UnregisterFunc();
|
||||
/// <inheritdoc cref="CallGatePubSubBase.UnregisterFunc"/>
|
||||
public void UnregisterFunc();
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.SendMessage"/>
|
||||
public void SendMessage();
|
||||
}
|
||||
/// <inheritdoc cref="CallGatePubSubBase.SendMessage"/>
|
||||
public void SendMessage();
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase"/>
|
||||
public interface ICallGateProvider<T1, TRet>
|
||||
{
|
||||
/// <inheritdoc cref="CallGatePubSubBase.RegisterAction"/>
|
||||
public void RegisterAction(Action<T1> action);
|
||||
/// <inheritdoc cref="CallGatePubSubBase"/>
|
||||
public interface ICallGateProvider<T1, TRet>
|
||||
{
|
||||
/// <inheritdoc cref="CallGatePubSubBase.RegisterAction"/>
|
||||
public void RegisterAction(Action<T1> action);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.RegisterFunc"/>
|
||||
public void RegisterFunc(Func<T1, TRet> func);
|
||||
/// <inheritdoc cref="CallGatePubSubBase.RegisterFunc"/>
|
||||
public void RegisterFunc(Func<T1, TRet> func);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.UnregisterAction"/>
|
||||
public void UnregisterAction();
|
||||
/// <inheritdoc cref="CallGatePubSubBase.UnregisterAction"/>
|
||||
public void UnregisterAction();
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.UnregisterFunc"/>
|
||||
public void UnregisterFunc();
|
||||
/// <inheritdoc cref="CallGatePubSubBase.UnregisterFunc"/>
|
||||
public void UnregisterFunc();
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.SendMessage"/>
|
||||
public void SendMessage(T1 arg1);
|
||||
}
|
||||
/// <inheritdoc cref="CallGatePubSubBase.SendMessage"/>
|
||||
public void SendMessage(T1 arg1);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase"/>
|
||||
public interface ICallGateProvider<T1, T2, TRet>
|
||||
{
|
||||
/// <inheritdoc cref="CallGatePubSubBase.RegisterAction"/>
|
||||
public void RegisterAction(Action<T1, T2> action);
|
||||
/// <inheritdoc cref="CallGatePubSubBase"/>
|
||||
public interface ICallGateProvider<T1, T2, TRet>
|
||||
{
|
||||
/// <inheritdoc cref="CallGatePubSubBase.RegisterAction"/>
|
||||
public void RegisterAction(Action<T1, T2> action);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.RegisterFunc"/>
|
||||
public void RegisterFunc(Func<T1, T2, TRet> func);
|
||||
/// <inheritdoc cref="CallGatePubSubBase.RegisterFunc"/>
|
||||
public void RegisterFunc(Func<T1, T2, TRet> func);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.UnregisterAction"/>
|
||||
public void UnregisterAction();
|
||||
/// <inheritdoc cref="CallGatePubSubBase.UnregisterAction"/>
|
||||
public void UnregisterAction();
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.UnregisterFunc"/>
|
||||
public void UnregisterFunc();
|
||||
/// <inheritdoc cref="CallGatePubSubBase.UnregisterFunc"/>
|
||||
public void UnregisterFunc();
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.SendMessage"/>
|
||||
public void SendMessage(T1 arg1, T2 arg2);
|
||||
}
|
||||
/// <inheritdoc cref="CallGatePubSubBase.SendMessage"/>
|
||||
public void SendMessage(T1 arg1, T2 arg2);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase"/>
|
||||
public interface ICallGateProvider<T1, T2, T3, TRet>
|
||||
{
|
||||
/// <inheritdoc cref="CallGatePubSubBase.RegisterAction"/>
|
||||
public void RegisterAction(Action<T1, T2, T3> action);
|
||||
/// <inheritdoc cref="CallGatePubSubBase"/>
|
||||
public interface ICallGateProvider<T1, T2, T3, TRet>
|
||||
{
|
||||
/// <inheritdoc cref="CallGatePubSubBase.RegisterAction"/>
|
||||
public void RegisterAction(Action<T1, T2, T3> action);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.RegisterFunc"/>
|
||||
public void RegisterFunc(Func<T1, T2, T3, TRet> func);
|
||||
/// <inheritdoc cref="CallGatePubSubBase.RegisterFunc"/>
|
||||
public void RegisterFunc(Func<T1, T2, T3, TRet> func);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.UnregisterAction"/>
|
||||
public void UnregisterAction();
|
||||
/// <inheritdoc cref="CallGatePubSubBase.UnregisterAction"/>
|
||||
public void UnregisterAction();
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.UnregisterFunc"/>
|
||||
public void UnregisterFunc();
|
||||
/// <inheritdoc cref="CallGatePubSubBase.UnregisterFunc"/>
|
||||
public void UnregisterFunc();
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.SendMessage"/>
|
||||
public void SendMessage(T1 arg1, T2 arg2, T3 arg3);
|
||||
}
|
||||
/// <inheritdoc cref="CallGatePubSubBase.SendMessage"/>
|
||||
public void SendMessage(T1 arg1, T2 arg2, T3 arg3);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase"/>
|
||||
public interface ICallGateProvider<T1, T2, T3, T4, TRet>
|
||||
{
|
||||
/// <inheritdoc cref="CallGatePubSubBase.RegisterAction"/>
|
||||
public void RegisterAction(Action<T1, T2, T3, T4> action);
|
||||
/// <inheritdoc cref="CallGatePubSubBase"/>
|
||||
public interface ICallGateProvider<T1, T2, T3, T4, TRet>
|
||||
{
|
||||
/// <inheritdoc cref="CallGatePubSubBase.RegisterAction"/>
|
||||
public void RegisterAction(Action<T1, T2, T3, T4> action);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.RegisterFunc"/>
|
||||
public void RegisterFunc(Func<T1, T2, T3, T4, TRet> func);
|
||||
/// <inheritdoc cref="CallGatePubSubBase.RegisterFunc"/>
|
||||
public void RegisterFunc(Func<T1, T2, T3, T4, TRet> func);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.UnregisterAction"/>
|
||||
public void UnregisterAction();
|
||||
/// <inheritdoc cref="CallGatePubSubBase.UnregisterAction"/>
|
||||
public void UnregisterAction();
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.UnregisterFunc"/>
|
||||
public void UnregisterFunc();
|
||||
/// <inheritdoc cref="CallGatePubSubBase.UnregisterFunc"/>
|
||||
public void UnregisterFunc();
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.SendMessage"/>
|
||||
public void SendMessage(T1 arg1, T2 arg2, T3 arg3, T4 arg4);
|
||||
}
|
||||
/// <inheritdoc cref="CallGatePubSubBase.SendMessage"/>
|
||||
public void SendMessage(T1 arg1, T2 arg2, T3 arg3, T4 arg4);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase"/>
|
||||
public interface ICallGateProvider<T1, T2, T3, T4, T5, TRet>
|
||||
{
|
||||
/// <inheritdoc cref="CallGatePubSubBase.RegisterAction"/>
|
||||
public void RegisterAction(Action<T1, T2, T3, T4, T5> action);
|
||||
/// <inheritdoc cref="CallGatePubSubBase"/>
|
||||
public interface ICallGateProvider<T1, T2, T3, T4, T5, TRet>
|
||||
{
|
||||
/// <inheritdoc cref="CallGatePubSubBase.RegisterAction"/>
|
||||
public void RegisterAction(Action<T1, T2, T3, T4, T5> action);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.RegisterFunc"/>
|
||||
public void RegisterFunc(Func<T1, T2, T3, T4, T5, TRet> func);
|
||||
/// <inheritdoc cref="CallGatePubSubBase.RegisterFunc"/>
|
||||
public void RegisterFunc(Func<T1, T2, T3, T4, T5, TRet> func);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.UnregisterAction"/>
|
||||
public void UnregisterAction();
|
||||
/// <inheritdoc cref="CallGatePubSubBase.UnregisterAction"/>
|
||||
public void UnregisterAction();
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.UnregisterFunc"/>
|
||||
public void UnregisterFunc();
|
||||
/// <inheritdoc cref="CallGatePubSubBase.UnregisterFunc"/>
|
||||
public void UnregisterFunc();
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.SendMessage"/>
|
||||
public void SendMessage(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5);
|
||||
}
|
||||
/// <inheritdoc cref="CallGatePubSubBase.SendMessage"/>
|
||||
public void SendMessage(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase"/>
|
||||
public interface ICallGateProvider<T1, T2, T3, T4, T5, T6, TRet>
|
||||
{
|
||||
/// <inheritdoc cref="CallGatePubSubBase.RegisterAction"/>
|
||||
public void RegisterAction(Action<T1, T2, T3, T4, T5, T6> action);
|
||||
/// <inheritdoc cref="CallGatePubSubBase"/>
|
||||
public interface ICallGateProvider<T1, T2, T3, T4, T5, T6, TRet>
|
||||
{
|
||||
/// <inheritdoc cref="CallGatePubSubBase.RegisterAction"/>
|
||||
public void RegisterAction(Action<T1, T2, T3, T4, T5, T6> action);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.RegisterFunc"/>
|
||||
public void RegisterFunc(Func<T1, T2, T3, T4, T5, T6, TRet> func);
|
||||
/// <inheritdoc cref="CallGatePubSubBase.RegisterFunc"/>
|
||||
public void RegisterFunc(Func<T1, T2, T3, T4, T5, T6, TRet> func);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.UnregisterAction"/>
|
||||
public void UnregisterAction();
|
||||
/// <inheritdoc cref="CallGatePubSubBase.UnregisterAction"/>
|
||||
public void UnregisterAction();
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.UnregisterFunc"/>
|
||||
public void UnregisterFunc();
|
||||
/// <inheritdoc cref="CallGatePubSubBase.UnregisterFunc"/>
|
||||
public void UnregisterFunc();
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.SendMessage"/>
|
||||
public void SendMessage(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6);
|
||||
}
|
||||
/// <inheritdoc cref="CallGatePubSubBase.SendMessage"/>
|
||||
public void SendMessage(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase"/>
|
||||
public interface ICallGateProvider<T1, T2, T3, T4, T5, T6, T7, TRet>
|
||||
{
|
||||
/// <inheritdoc cref="CallGatePubSubBase.RegisterAction"/>
|
||||
public void RegisterAction(Action<T1, T2, T3, T4, T5, T6, T7> action);
|
||||
/// <inheritdoc cref="CallGatePubSubBase"/>
|
||||
public interface ICallGateProvider<T1, T2, T3, T4, T5, T6, T7, TRet>
|
||||
{
|
||||
/// <inheritdoc cref="CallGatePubSubBase.RegisterAction"/>
|
||||
public void RegisterAction(Action<T1, T2, T3, T4, T5, T6, T7> action);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.RegisterFunc"/>
|
||||
public void RegisterFunc(Func<T1, T2, T3, T4, T5, T6, T7, TRet> func);
|
||||
/// <inheritdoc cref="CallGatePubSubBase.RegisterFunc"/>
|
||||
public void RegisterFunc(Func<T1, T2, T3, T4, T5, T6, T7, TRet> func);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.UnregisterAction"/>
|
||||
public void UnregisterAction();
|
||||
/// <inheritdoc cref="CallGatePubSubBase.UnregisterAction"/>
|
||||
public void UnregisterAction();
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.UnregisterFunc"/>
|
||||
public void UnregisterFunc();
|
||||
/// <inheritdoc cref="CallGatePubSubBase.UnregisterFunc"/>
|
||||
public void UnregisterFunc();
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.SendMessage"/>
|
||||
public void SendMessage(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7);
|
||||
}
|
||||
/// <inheritdoc cref="CallGatePubSubBase.SendMessage"/>
|
||||
public void SendMessage(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase"/>
|
||||
public interface ICallGateProvider<T1, T2, T3, T4, T5, T6, T7, T8, TRet>
|
||||
{
|
||||
/// <inheritdoc cref="CallGatePubSubBase.RegisterAction"/>
|
||||
public void RegisterAction(Action<T1, T2, T3, T4, T5, T6, T7, T8> action);
|
||||
/// <inheritdoc cref="CallGatePubSubBase"/>
|
||||
public interface ICallGateProvider<T1, T2, T3, T4, T5, T6, T7, T8, TRet>
|
||||
{
|
||||
/// <inheritdoc cref="CallGatePubSubBase.RegisterAction"/>
|
||||
public void RegisterAction(Action<T1, T2, T3, T4, T5, T6, T7, T8> action);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.RegisterFunc"/>
|
||||
public void RegisterFunc(Func<T1, T2, T3, T4, T5, T6, T7, T8, TRet> func);
|
||||
/// <inheritdoc cref="CallGatePubSubBase.RegisterFunc"/>
|
||||
public void RegisterFunc(Func<T1, T2, T3, T4, T5, T6, T7, T8, TRet> func);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.UnregisterAction"/>
|
||||
public void UnregisterAction();
|
||||
/// <inheritdoc cref="CallGatePubSubBase.UnregisterAction"/>
|
||||
public void UnregisterAction();
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.UnregisterFunc"/>
|
||||
public void UnregisterFunc();
|
||||
/// <inheritdoc cref="CallGatePubSubBase.UnregisterFunc"/>
|
||||
public void UnregisterFunc();
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.SendMessage"/>
|
||||
public void SendMessage(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8);
|
||||
/// <inheritdoc cref="CallGatePubSubBase.SendMessage"/>
|
||||
public void SendMessage(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8);
|
||||
}
|
||||
}
|
||||
|
||||
#pragma warning restore SA1402 // File may only contain a single type
|
||||
|
|
|
|||
|
|
@ -4,150 +4,151 @@ using Dalamud.Plugin.Ipc.Internal;
|
|||
|
||||
#pragma warning disable SA1402 // File may only contain a single type
|
||||
|
||||
namespace Dalamud.Plugin.Ipc;
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase"/>
|
||||
public interface ICallGateSubscriber<TRet>
|
||||
namespace Dalamud.Plugin.Ipc
|
||||
{
|
||||
/// <inheritdoc cref="CallGatePubSubBase.Subscribe"/>
|
||||
public void Subscribe(Action action);
|
||||
/// <inheritdoc cref="CallGatePubSubBase"/>
|
||||
public interface ICallGateSubscriber<TRet>
|
||||
{
|
||||
/// <inheritdoc cref="CallGatePubSubBase.Subscribe"/>
|
||||
public void Subscribe(Action action);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.Unsubscribe"/>
|
||||
public void Unsubscribe(Action action);
|
||||
/// <inheritdoc cref="CallGatePubSubBase.Unsubscribe"/>
|
||||
public void Unsubscribe(Action action);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.InvokeAction"/>
|
||||
public void InvokeAction();
|
||||
/// <inheritdoc cref="CallGatePubSubBase.InvokeAction"/>
|
||||
public void InvokeAction();
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.InvokeFunc"/>
|
||||
public TRet InvokeFunc();
|
||||
}
|
||||
/// <inheritdoc cref="CallGatePubSubBase.InvokeFunc"/>
|
||||
public TRet InvokeFunc();
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase"/>
|
||||
public interface ICallGateSubscriber<T1, TRet>
|
||||
{
|
||||
/// <inheritdoc cref="CallGatePubSubBase.Subscribe"/>
|
||||
public void Subscribe(Action<T1> action);
|
||||
/// <inheritdoc cref="CallGatePubSubBase"/>
|
||||
public interface ICallGateSubscriber<T1, TRet>
|
||||
{
|
||||
/// <inheritdoc cref="CallGatePubSubBase.Subscribe"/>
|
||||
public void Subscribe(Action<T1> action);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.Unsubscribe"/>
|
||||
public void Unsubscribe(Action<T1> action);
|
||||
/// <inheritdoc cref="CallGatePubSubBase.Unsubscribe"/>
|
||||
public void Unsubscribe(Action<T1> action);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.InvokeAction"/>
|
||||
public void InvokeAction(T1 arg1);
|
||||
/// <inheritdoc cref="CallGatePubSubBase.InvokeAction"/>
|
||||
public void InvokeAction(T1 arg1);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.InvokeFunc"/>
|
||||
public TRet InvokeFunc(T1 arg1);
|
||||
}
|
||||
/// <inheritdoc cref="CallGatePubSubBase.InvokeFunc"/>
|
||||
public TRet InvokeFunc(T1 arg1);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase"/>
|
||||
public interface ICallGateSubscriber<T1, T2, TRet>
|
||||
{
|
||||
/// <inheritdoc cref="CallGatePubSubBase.Subscribe"/>
|
||||
public void Subscribe(Action<T1, T2> action);
|
||||
/// <inheritdoc cref="CallGatePubSubBase"/>
|
||||
public interface ICallGateSubscriber<T1, T2, TRet>
|
||||
{
|
||||
/// <inheritdoc cref="CallGatePubSubBase.Subscribe"/>
|
||||
public void Subscribe(Action<T1, T2> action);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.Unsubscribe"/>
|
||||
public void Unsubscribe(Action<T1, T2> action);
|
||||
/// <inheritdoc cref="CallGatePubSubBase.Unsubscribe"/>
|
||||
public void Unsubscribe(Action<T1, T2> action);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.InvokeAction"/>
|
||||
public void InvokeAction(T1 arg1, T2 arg2);
|
||||
/// <inheritdoc cref="CallGatePubSubBase.InvokeAction"/>
|
||||
public void InvokeAction(T1 arg1, T2 arg2);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.InvokeFunc"/>
|
||||
public TRet InvokeFunc(T1 arg1, T2 arg2);
|
||||
}
|
||||
/// <inheritdoc cref="CallGatePubSubBase.InvokeFunc"/>
|
||||
public TRet InvokeFunc(T1 arg1, T2 arg2);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase"/>
|
||||
public interface ICallGateSubscriber<T1, T2, T3, TRet>
|
||||
{
|
||||
/// <inheritdoc cref="CallGatePubSubBase.Subscribe"/>
|
||||
public void Subscribe(Action<T1, T2, T3> action);
|
||||
/// <inheritdoc cref="CallGatePubSubBase"/>
|
||||
public interface ICallGateSubscriber<T1, T2, T3, TRet>
|
||||
{
|
||||
/// <inheritdoc cref="CallGatePubSubBase.Subscribe"/>
|
||||
public void Subscribe(Action<T1, T2, T3> action);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.Unsubscribe"/>
|
||||
public void Unsubscribe(Action<T1, T2, T3> action);
|
||||
/// <inheritdoc cref="CallGatePubSubBase.Unsubscribe"/>
|
||||
public void Unsubscribe(Action<T1, T2, T3> action);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.InvokeAction"/>
|
||||
public void InvokeAction(T1 arg1, T2 arg2, T3 arg3);
|
||||
/// <inheritdoc cref="CallGatePubSubBase.InvokeAction"/>
|
||||
public void InvokeAction(T1 arg1, T2 arg2, T3 arg3);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.InvokeFunc"/>
|
||||
public TRet InvokeFunc(T1 arg1, T2 arg2, T3 arg3);
|
||||
}
|
||||
/// <inheritdoc cref="CallGatePubSubBase.InvokeFunc"/>
|
||||
public TRet InvokeFunc(T1 arg1, T2 arg2, T3 arg3);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase"/>
|
||||
public interface ICallGateSubscriber<T1, T2, T3, T4, TRet>
|
||||
{
|
||||
/// <inheritdoc cref="CallGatePubSubBase.Subscribe"/>
|
||||
public void Subscribe(Action<T1, T2, T3, T4> action);
|
||||
/// <inheritdoc cref="CallGatePubSubBase"/>
|
||||
public interface ICallGateSubscriber<T1, T2, T3, T4, TRet>
|
||||
{
|
||||
/// <inheritdoc cref="CallGatePubSubBase.Subscribe"/>
|
||||
public void Subscribe(Action<T1, T2, T3, T4> action);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.Unsubscribe"/>
|
||||
public void Unsubscribe(Action<T1, T2, T3, T4> action);
|
||||
/// <inheritdoc cref="CallGatePubSubBase.Unsubscribe"/>
|
||||
public void Unsubscribe(Action<T1, T2, T3, T4> action);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.InvokeAction"/>
|
||||
public void InvokeAction(T1 arg1, T2 arg2, T3 arg3, T4 arg4);
|
||||
/// <inheritdoc cref="CallGatePubSubBase.InvokeAction"/>
|
||||
public void InvokeAction(T1 arg1, T2 arg2, T3 arg3, T4 arg4);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.InvokeFunc"/>
|
||||
public TRet InvokeFunc(T1 arg1, T2 arg2, T3 arg3, T4 arg4);
|
||||
}
|
||||
/// <inheritdoc cref="CallGatePubSubBase.InvokeFunc"/>
|
||||
public TRet InvokeFunc(T1 arg1, T2 arg2, T3 arg3, T4 arg4);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase"/>
|
||||
public interface ICallGateSubscriber<T1, T2, T3, T4, T5, TRet>
|
||||
{
|
||||
/// <inheritdoc cref="CallGatePubSubBase.Subscribe"/>
|
||||
public void Subscribe(Action<T1, T2, T3, T4, T5> action);
|
||||
/// <inheritdoc cref="CallGatePubSubBase"/>
|
||||
public interface ICallGateSubscriber<T1, T2, T3, T4, T5, TRet>
|
||||
{
|
||||
/// <inheritdoc cref="CallGatePubSubBase.Subscribe"/>
|
||||
public void Subscribe(Action<T1, T2, T3, T4, T5> action);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.Unsubscribe"/>
|
||||
public void Unsubscribe(Action<T1, T2, T3, T4, T5> action);
|
||||
/// <inheritdoc cref="CallGatePubSubBase.Unsubscribe"/>
|
||||
public void Unsubscribe(Action<T1, T2, T3, T4, T5> action);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.InvokeAction"/>
|
||||
public void InvokeAction(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5);
|
||||
/// <inheritdoc cref="CallGatePubSubBase.InvokeAction"/>
|
||||
public void InvokeAction(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.InvokeFunc"/>
|
||||
public TRet InvokeFunc(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5);
|
||||
}
|
||||
/// <inheritdoc cref="CallGatePubSubBase.InvokeFunc"/>
|
||||
public TRet InvokeFunc(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase"/>
|
||||
public interface ICallGateSubscriber<T1, T2, T3, T4, T5, T6, TRet>
|
||||
{
|
||||
/// <inheritdoc cref="CallGatePubSubBase.Subscribe"/>
|
||||
public void Subscribe(Action<T1, T2, T3, T4, T5, T6> action);
|
||||
/// <inheritdoc cref="CallGatePubSubBase"/>
|
||||
public interface ICallGateSubscriber<T1, T2, T3, T4, T5, T6, TRet>
|
||||
{
|
||||
/// <inheritdoc cref="CallGatePubSubBase.Subscribe"/>
|
||||
public void Subscribe(Action<T1, T2, T3, T4, T5, T6> action);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.Unsubscribe"/>
|
||||
public void Unsubscribe(Action<T1, T2, T3, T4, T5, T6> action);
|
||||
/// <inheritdoc cref="CallGatePubSubBase.Unsubscribe"/>
|
||||
public void Unsubscribe(Action<T1, T2, T3, T4, T5, T6> action);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.InvokeAction"/>
|
||||
public void InvokeAction(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6);
|
||||
/// <inheritdoc cref="CallGatePubSubBase.InvokeAction"/>
|
||||
public void InvokeAction(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.InvokeFunc"/>
|
||||
public TRet InvokeFunc(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6);
|
||||
}
|
||||
/// <inheritdoc cref="CallGatePubSubBase.InvokeFunc"/>
|
||||
public TRet InvokeFunc(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase"/>
|
||||
public interface ICallGateSubscriber<T1, T2, T3, T4, T5, T6, T7, TRet>
|
||||
{
|
||||
/// <inheritdoc cref="CallGatePubSubBase.Subscribe"/>
|
||||
public void Subscribe(Action<T1, T2, T3, T4, T5, T6, T7> action);
|
||||
/// <inheritdoc cref="CallGatePubSubBase"/>
|
||||
public interface ICallGateSubscriber<T1, T2, T3, T4, T5, T6, T7, TRet>
|
||||
{
|
||||
/// <inheritdoc cref="CallGatePubSubBase.Subscribe"/>
|
||||
public void Subscribe(Action<T1, T2, T3, T4, T5, T6, T7> action);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.Unsubscribe"/>
|
||||
public void Unsubscribe(Action<T1, T2, T3, T4, T5, T6, T7> action);
|
||||
/// <inheritdoc cref="CallGatePubSubBase.Unsubscribe"/>
|
||||
public void Unsubscribe(Action<T1, T2, T3, T4, T5, T6, T7> action);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.InvokeAction"/>
|
||||
public void InvokeAction(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7);
|
||||
/// <inheritdoc cref="CallGatePubSubBase.InvokeAction"/>
|
||||
public void InvokeAction(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.InvokeFunc"/>
|
||||
public TRet InvokeFunc(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7);
|
||||
}
|
||||
/// <inheritdoc cref="CallGatePubSubBase.InvokeFunc"/>
|
||||
public TRet InvokeFunc(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase"/>
|
||||
public interface ICallGateSubscriber<T1, T2, T3, T4, T5, T6, T7, T8, TRet>
|
||||
{
|
||||
/// <inheritdoc cref="CallGatePubSubBase.Subscribe"/>
|
||||
public void Subscribe(Action<T1, T2, T3, T4, T5, T6, T7, T8> action);
|
||||
/// <inheritdoc cref="CallGatePubSubBase"/>
|
||||
public interface ICallGateSubscriber<T1, T2, T3, T4, T5, T6, T7, T8, TRet>
|
||||
{
|
||||
/// <inheritdoc cref="CallGatePubSubBase.Subscribe"/>
|
||||
public void Subscribe(Action<T1, T2, T3, T4, T5, T6, T7, T8> action);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.Unsubscribe"/>
|
||||
public void Unsubscribe(Action<T1, T2, T3, T4, T5, T6, T7, T8> action);
|
||||
/// <inheritdoc cref="CallGatePubSubBase.Unsubscribe"/>
|
||||
public void Unsubscribe(Action<T1, T2, T3, T4, T5, T6, T7, T8> action);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.InvokeAction"/>
|
||||
public void InvokeAction(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8);
|
||||
/// <inheritdoc cref="CallGatePubSubBase.InvokeAction"/>
|
||||
public void InvokeAction(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.InvokeFunc"/>
|
||||
public TRet InvokeFunc(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8);
|
||||
/// <inheritdoc cref="CallGatePubSubBase.InvokeFunc"/>
|
||||
public TRet InvokeFunc(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8);
|
||||
}
|
||||
}
|
||||
|
||||
#pragma warning restore SA1402 // File may only contain a single type
|
||||
|
|
|
|||
|
|
@ -1,30 +1,31 @@
|
|||
using System.Collections.Generic;
|
||||
|
||||
namespace Dalamud.Plugin.Ipc.Internal;
|
||||
|
||||
/// <summary>
|
||||
/// This class facilitates inter-plugin communication.
|
||||
/// </summary>
|
||||
internal class CallGate
|
||||
namespace Dalamud.Plugin.Ipc.Internal
|
||||
{
|
||||
private readonly Dictionary<string, CallGateChannel> gates = new();
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="CallGate"/> class.
|
||||
/// This class facilitates inter-plugin communication.
|
||||
/// </summary>
|
||||
internal CallGate()
|
||||
internal class CallGate
|
||||
{
|
||||
}
|
||||
private readonly Dictionary<string, CallGateChannel> gates = new();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the provider associated with the specified name.
|
||||
/// </summary>
|
||||
/// <param name="name">Name of the IPC registration.</param>
|
||||
/// <returns>A CallGate registered under the given name.</returns>
|
||||
public CallGateChannel GetOrCreateChannel(string name)
|
||||
{
|
||||
if (!this.gates.TryGetValue(name, out var gate))
|
||||
gate = this.gates[name] = new CallGateChannel(name);
|
||||
return gate;
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="CallGate"/> class.
|
||||
/// </summary>
|
||||
internal CallGate()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the provider associated with the specified name.
|
||||
/// </summary>
|
||||
/// <param name="name">Name of the IPC registration.</param>
|
||||
/// <returns>A CallGate registered under the given name.</returns>
|
||||
public CallGateChannel GetOrCreateChannel(string name)
|
||||
{
|
||||
if (!this.gates.TryGetValue(name, out var gate))
|
||||
gate = this.gates[name] = new CallGateChannel(name);
|
||||
return gate;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,179 +7,180 @@ using Dalamud.Plugin.Ipc.Exceptions;
|
|||
using Newtonsoft.Json;
|
||||
using Serilog;
|
||||
|
||||
namespace Dalamud.Plugin.Ipc.Internal;
|
||||
|
||||
/// <summary>
|
||||
/// This class implements the channels and serialization needed for the typed gates to interact with each other.
|
||||
/// </summary>
|
||||
internal class CallGateChannel
|
||||
namespace Dalamud.Plugin.Ipc.Internal
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="CallGateChannel"/> class.
|
||||
/// This class implements the channels and serialization needed for the typed gates to interact with each other.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of this IPC registration.</param>
|
||||
public CallGateChannel(string name)
|
||||
internal class CallGateChannel
|
||||
{
|
||||
this.Name = name;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name of the IPC registration.
|
||||
/// </summary>
|
||||
public string Name { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a list of delegate subscriptions for when SendMessage is called.
|
||||
/// </summary>
|
||||
public List<Delegate> Subscriptions { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets an action for when InvokeAction is called.
|
||||
/// </summary>
|
||||
public Delegate Action { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a func for when InvokeFunc is called.
|
||||
/// </summary>
|
||||
public Delegate Func { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Invoke all actions that have subscribed to this IPC.
|
||||
/// </summary>
|
||||
/// <param name="args">Message arguments.</param>
|
||||
internal void SendMessage(object?[]? args)
|
||||
{
|
||||
if (this.Subscriptions.Count == 0)
|
||||
return;
|
||||
|
||||
foreach (var subscription in this.Subscriptions)
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="CallGateChannel"/> class.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of this IPC registration.</param>
|
||||
public CallGateChannel(string name)
|
||||
{
|
||||
var methodInfo = subscription.GetMethodInfo();
|
||||
this.Name = name;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name of the IPC registration.
|
||||
/// </summary>
|
||||
public string Name { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a list of delegate subscriptions for when SendMessage is called.
|
||||
/// </summary>
|
||||
public List<Delegate> Subscriptions { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets an action for when InvokeAction is called.
|
||||
/// </summary>
|
||||
public Delegate Action { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a func for when InvokeFunc is called.
|
||||
/// </summary>
|
||||
public Delegate Func { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Invoke all actions that have subscribed to this IPC.
|
||||
/// </summary>
|
||||
/// <param name="args">Message arguments.</param>
|
||||
internal void SendMessage(object?[]? args)
|
||||
{
|
||||
if (this.Subscriptions.Count == 0)
|
||||
return;
|
||||
|
||||
foreach (var subscription in this.Subscriptions)
|
||||
{
|
||||
var methodInfo = subscription.GetMethodInfo();
|
||||
this.CheckAndConvertArgs(args, methodInfo);
|
||||
|
||||
subscription.DynamicInvoke(args);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invoke an action registered for inter-plugin communication.
|
||||
/// </summary>
|
||||
/// <param name="args">Action arguments.</param>
|
||||
/// <exception cref="IpcNotReadyError">This is thrown when the IPC publisher has not registered a func for calling yet.</exception>
|
||||
internal void InvokeAction(object?[]? args)
|
||||
{
|
||||
if (this.Action == null)
|
||||
throw new IpcNotReadyError(this.Name);
|
||||
|
||||
var methodInfo = this.Action.GetMethodInfo();
|
||||
this.CheckAndConvertArgs(args, methodInfo);
|
||||
|
||||
subscription.DynamicInvoke(args);
|
||||
this.Action.DynamicInvoke(args);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invoke an action registered for inter-plugin communication.
|
||||
/// </summary>
|
||||
/// <param name="args">Action arguments.</param>
|
||||
/// <exception cref="IpcNotReadyError">This is thrown when the IPC publisher has not registered a func for calling yet.</exception>
|
||||
internal void InvokeAction(object?[]? args)
|
||||
{
|
||||
if (this.Action == null)
|
||||
throw new IpcNotReadyError(this.Name);
|
||||
|
||||
var methodInfo = this.Action.GetMethodInfo();
|
||||
this.CheckAndConvertArgs(args, methodInfo);
|
||||
|
||||
this.Action.DynamicInvoke(args);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invoke a function registered for inter-plugin communication.
|
||||
/// </summary>
|
||||
/// <param name="args">Func arguments.</param>
|
||||
/// <returns>The return value.</returns>
|
||||
/// <typeparam name="TRet">The return type.</typeparam>
|
||||
/// <exception cref="IpcNotReadyError">This is thrown when the IPC publisher has not registered a func for calling yet.</exception>
|
||||
internal TRet InvokeFunc<TRet>(object?[]? args)
|
||||
{
|
||||
if (this.Func == null)
|
||||
throw new IpcNotReadyError(this.Name);
|
||||
|
||||
var methodInfo = this.Func.GetMethodInfo();
|
||||
this.CheckAndConvertArgs(args, methodInfo);
|
||||
|
||||
var result = this.Func.DynamicInvoke(args);
|
||||
|
||||
if (typeof(TRet) != methodInfo.ReturnType)
|
||||
result = this.ConvertObject(result, typeof(TRet));
|
||||
|
||||
return (TRet)result;
|
||||
}
|
||||
|
||||
private void CheckAndConvertArgs(object?[]? args, MethodInfo methodInfo)
|
||||
{
|
||||
var paramTypes = methodInfo.GetParameters()
|
||||
.Select(pi => pi.ParameterType).ToArray();
|
||||
|
||||
if (args.Length != paramTypes.Length)
|
||||
throw new IpcLengthMismatchError(this.Name, args.Length, paramTypes.Length);
|
||||
|
||||
for (var i = 0; i < args.Length; i++)
|
||||
/// <summary>
|
||||
/// Invoke a function registered for inter-plugin communication.
|
||||
/// </summary>
|
||||
/// <param name="args">Func arguments.</param>
|
||||
/// <returns>The return value.</returns>
|
||||
/// <typeparam name="TRet">The return type.</typeparam>
|
||||
/// <exception cref="IpcNotReadyError">This is thrown when the IPC publisher has not registered a func for calling yet.</exception>
|
||||
internal TRet InvokeFunc<TRet>(object?[]? args)
|
||||
{
|
||||
var arg = args[i];
|
||||
var paramType = paramTypes[i];
|
||||
if (this.Func == null)
|
||||
throw new IpcNotReadyError(this.Name);
|
||||
|
||||
var argType = arg.GetType();
|
||||
if (argType != paramType)
|
||||
var methodInfo = this.Func.GetMethodInfo();
|
||||
this.CheckAndConvertArgs(args, methodInfo);
|
||||
|
||||
var result = this.Func.DynamicInvoke(args);
|
||||
|
||||
if (typeof(TRet) != methodInfo.ReturnType)
|
||||
result = this.ConvertObject(result, typeof(TRet));
|
||||
|
||||
return (TRet)result;
|
||||
}
|
||||
|
||||
private void CheckAndConvertArgs(object?[]? args, MethodInfo methodInfo)
|
||||
{
|
||||
var paramTypes = methodInfo.GetParameters()
|
||||
.Select(pi => pi.ParameterType).ToArray();
|
||||
|
||||
if (args.Length != paramTypes.Length)
|
||||
throw new IpcLengthMismatchError(this.Name, args.Length, paramTypes.Length);
|
||||
|
||||
for (var i = 0; i < args.Length; i++)
|
||||
{
|
||||
// check the inheritance tree
|
||||
var baseTypes = this.GenerateTypes(argType.BaseType);
|
||||
if (baseTypes.Any(t => t == paramType))
|
||||
var arg = args[i];
|
||||
var paramType = paramTypes[i];
|
||||
|
||||
var argType = arg.GetType();
|
||||
if (argType != paramType)
|
||||
{
|
||||
// The source type inherits from the destination type
|
||||
continue;
|
||||
// check the inheritance tree
|
||||
var baseTypes = this.GenerateTypes(argType.BaseType);
|
||||
if (baseTypes.Any(t => t == paramType))
|
||||
{
|
||||
// The source type inherits from the destination type
|
||||
continue;
|
||||
}
|
||||
|
||||
args[i] = this.ConvertObject(arg, paramType);
|
||||
}
|
||||
|
||||
args[i] = this.ConvertObject(arg, paramType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerable<Type> GenerateTypes(Type type)
|
||||
{
|
||||
while (type != null && type != typeof(object))
|
||||
private IEnumerable<Type> GenerateTypes(Type type)
|
||||
{
|
||||
yield return type;
|
||||
type = type.BaseType;
|
||||
}
|
||||
}
|
||||
|
||||
private object? ConvertObject(object? obj, Type type)
|
||||
{
|
||||
var json = JsonConvert.SerializeObject(obj);
|
||||
|
||||
try
|
||||
{
|
||||
return JsonConvert.DeserializeObject(json, type);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
Log.Verbose($"Could not convert {obj.GetType().Name} to {type.Name}, will look for compatible type instead");
|
||||
}
|
||||
|
||||
// If type -> type fails, try to find an object that matches.
|
||||
var sourceType = obj.GetType();
|
||||
var fieldNames = sourceType.GetFields(BindingFlags.Public | BindingFlags.Instance)
|
||||
.Select(f => f.Name);
|
||||
var propNames = sourceType.GetProperties(BindingFlags.Public | BindingFlags.Instance)
|
||||
.Select(p => p.Name);
|
||||
|
||||
var assignableTypes = type.Assembly.GetTypes()
|
||||
.Where(t => type.IsAssignableFrom(t) && type != t)
|
||||
.ToArray();
|
||||
|
||||
foreach (var assignableType in assignableTypes)
|
||||
{
|
||||
var matchesFields = assignableType.GetFields().All(f => fieldNames.Contains(f.Name));
|
||||
var matchesProps = assignableType.GetProperties().All(p => propNames.Contains(p.Name));
|
||||
if (matchesFields && matchesProps)
|
||||
while (type != null && type != typeof(object))
|
||||
{
|
||||
type = assignableType;
|
||||
break;
|
||||
yield return type;
|
||||
type = type.BaseType;
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
private object? ConvertObject(object? obj, Type type)
|
||||
{
|
||||
return JsonConvert.DeserializeObject(json, type);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new IpcTypeMismatchError(this.Name, obj.GetType(), type, ex);
|
||||
var json = JsonConvert.SerializeObject(obj);
|
||||
|
||||
try
|
||||
{
|
||||
return JsonConvert.DeserializeObject(json, type);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
Log.Verbose($"Could not convert {obj.GetType().Name} to {type.Name}, will look for compatible type instead");
|
||||
}
|
||||
|
||||
// If type -> type fails, try to find an object that matches.
|
||||
var sourceType = obj.GetType();
|
||||
var fieldNames = sourceType.GetFields(BindingFlags.Public | BindingFlags.Instance)
|
||||
.Select(f => f.Name);
|
||||
var propNames = sourceType.GetProperties(BindingFlags.Public | BindingFlags.Instance)
|
||||
.Select(p => p.Name);
|
||||
|
||||
var assignableTypes = type.Assembly.GetTypes()
|
||||
.Where(t => type.IsAssignableFrom(t) && type != t)
|
||||
.ToArray();
|
||||
|
||||
foreach (var assignableType in assignableTypes)
|
||||
{
|
||||
var matchesFields = assignableType.GetFields().All(f => fieldNames.Contains(f.Name));
|
||||
var matchesProps = assignableType.GetProperties().All(p => propNames.Contains(p.Name));
|
||||
if (matchesFields && matchesProps)
|
||||
{
|
||||
type = assignableType;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
return JsonConvert.DeserializeObject(json, type);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new IpcTypeMismatchError(this.Name, obj.GetType(), type, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,348 +2,349 @@ using System;
|
|||
|
||||
#pragma warning disable SA1402 // File may only contain a single type
|
||||
|
||||
namespace Dalamud.Plugin.Ipc.Internal;
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase"/>
|
||||
internal class CallGatePubSub<TRet> : CallGatePubSubBase, ICallGateProvider<TRet>, ICallGateSubscriber<TRet>
|
||||
namespace Dalamud.Plugin.Ipc.Internal
|
||||
{
|
||||
/// <inheritdoc cref="CallGatePubSubBase(string)"/>
|
||||
public CallGatePubSub(string name)
|
||||
: base(name)
|
||||
/// <inheritdoc cref="CallGatePubSubBase"/>
|
||||
internal class CallGatePubSub<TRet> : CallGatePubSubBase, ICallGateProvider<TRet>, ICallGateSubscriber<TRet>
|
||||
{
|
||||
/// <inheritdoc cref="CallGatePubSubBase(string)"/>
|
||||
public CallGatePubSub(string name)
|
||||
: base(name)
|
||||
{
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.RegisterAction"/>
|
||||
public void RegisterAction(Action action)
|
||||
=> base.RegisterAction(action);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.RegisterFunc"/>
|
||||
public void RegisterFunc(Func<TRet> func)
|
||||
=> base.RegisterFunc(func);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.SendMessage"/>
|
||||
public void SendMessage()
|
||||
=> base.SendMessage();
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.Subscribe"/>
|
||||
public void Subscribe(Action action)
|
||||
=> base.Subscribe(action);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.Unsubscribe"/>
|
||||
public void Unsubscribe(Action action)
|
||||
=> base.Unsubscribe(action);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.InvokeAction"/>
|
||||
public void InvokeAction()
|
||||
=> base.InvokeAction();
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.InvokeFunc"/>
|
||||
public TRet InvokeFunc()
|
||||
=> this.InvokeFunc<TRet>();
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.RegisterAction"/>
|
||||
public void RegisterAction(Action action)
|
||||
=> base.RegisterAction(action);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.RegisterFunc"/>
|
||||
public void RegisterFunc(Func<TRet> func)
|
||||
=> base.RegisterFunc(func);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.SendMessage"/>
|
||||
public void SendMessage()
|
||||
=> base.SendMessage();
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.Subscribe"/>
|
||||
public void Subscribe(Action action)
|
||||
=> base.Subscribe(action);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.Unsubscribe"/>
|
||||
public void Unsubscribe(Action action)
|
||||
=> base.Unsubscribe(action);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.InvokeAction"/>
|
||||
public void InvokeAction()
|
||||
=> base.InvokeAction();
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.InvokeFunc"/>
|
||||
public TRet InvokeFunc()
|
||||
=> this.InvokeFunc<TRet>();
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase"/>
|
||||
internal class CallGatePubSub<T1, TRet> : CallGatePubSubBase, ICallGateProvider<T1, TRet>, ICallGateSubscriber<T1, TRet>
|
||||
{
|
||||
/// <inheritdoc cref="CallGatePubSubBase(string)"/>
|
||||
public CallGatePubSub(string name)
|
||||
: base(name)
|
||||
/// <inheritdoc cref="CallGatePubSubBase"/>
|
||||
internal class CallGatePubSub<T1, TRet> : CallGatePubSubBase, ICallGateProvider<T1, TRet>, ICallGateSubscriber<T1, TRet>
|
||||
{
|
||||
/// <inheritdoc cref="CallGatePubSubBase(string)"/>
|
||||
public CallGatePubSub(string name)
|
||||
: base(name)
|
||||
{
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.RegisterAction"/>
|
||||
public void RegisterAction(Action<T1> action)
|
||||
=> base.RegisterAction(action);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.RegisterFunc"/>
|
||||
public void RegisterFunc(Func<T1, TRet> func)
|
||||
=> base.RegisterFunc(func);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.SendMessage"/>
|
||||
public void SendMessage(T1 arg1)
|
||||
=> base.SendMessage(arg1);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.Subscribe"/>
|
||||
public void Subscribe(Action<T1> action)
|
||||
=> base.Subscribe(action);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.Unsubscribe"/>
|
||||
public void Unsubscribe(Action<T1> action)
|
||||
=> base.Unsubscribe(action);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.InvokeAction"/>
|
||||
public void InvokeAction(T1 arg1)
|
||||
=> base.InvokeAction(arg1);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.InvokeFunc"/>
|
||||
public TRet InvokeFunc(T1 arg1)
|
||||
=> this.InvokeFunc<TRet>(arg1);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.RegisterAction"/>
|
||||
public void RegisterAction(Action<T1> action)
|
||||
=> base.RegisterAction(action);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.RegisterFunc"/>
|
||||
public void RegisterFunc(Func<T1, TRet> func)
|
||||
=> base.RegisterFunc(func);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.SendMessage"/>
|
||||
public void SendMessage(T1 arg1)
|
||||
=> base.SendMessage(arg1);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.Subscribe"/>
|
||||
public void Subscribe(Action<T1> action)
|
||||
=> base.Subscribe(action);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.Unsubscribe"/>
|
||||
public void Unsubscribe(Action<T1> action)
|
||||
=> base.Unsubscribe(action);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.InvokeAction"/>
|
||||
public void InvokeAction(T1 arg1)
|
||||
=> base.InvokeAction(arg1);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.InvokeFunc"/>
|
||||
public TRet InvokeFunc(T1 arg1)
|
||||
=> this.InvokeFunc<TRet>(arg1);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase"/>
|
||||
internal class CallGatePubSub<T1, T2, TRet> : CallGatePubSubBase, ICallGateProvider<T1, T2, TRet>, ICallGateSubscriber<T1, T2, TRet>
|
||||
{
|
||||
/// <inheritdoc cref="CallGatePubSubBase(string)"/>
|
||||
public CallGatePubSub(string name)
|
||||
: base(name)
|
||||
/// <inheritdoc cref="CallGatePubSubBase"/>
|
||||
internal class CallGatePubSub<T1, T2, TRet> : CallGatePubSubBase, ICallGateProvider<T1, T2, TRet>, ICallGateSubscriber<T1, T2, TRet>
|
||||
{
|
||||
/// <inheritdoc cref="CallGatePubSubBase(string)"/>
|
||||
public CallGatePubSub(string name)
|
||||
: base(name)
|
||||
{
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.RegisterAction"/>
|
||||
public void RegisterAction(Action<T1, T2> action)
|
||||
=> base.RegisterAction(action);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.RegisterFunc"/>
|
||||
public void RegisterFunc(Func<T1, T2, TRet> func)
|
||||
=> base.RegisterFunc(func);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.SendMessage"/>
|
||||
public void SendMessage(T1 arg1, T2 arg2)
|
||||
=> base.SendMessage(arg1, arg2);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.Subscribe"/>
|
||||
public void Subscribe(Action<T1, T2> action)
|
||||
=> base.Subscribe(action);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.Unsubscribe"/>
|
||||
public void Unsubscribe(Action<T1, T2> action)
|
||||
=> base.Unsubscribe(action);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.InvokeAction"/>
|
||||
public void InvokeAction(T1 arg1, T2 arg2)
|
||||
=> base.InvokeAction(arg1, arg2);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.InvokeFunc"/>
|
||||
public TRet InvokeFunc(T1 arg1, T2 arg2)
|
||||
=> this.InvokeFunc<TRet>(arg1, arg2);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.RegisterAction"/>
|
||||
public void RegisterAction(Action<T1, T2> action)
|
||||
=> base.RegisterAction(action);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.RegisterFunc"/>
|
||||
public void RegisterFunc(Func<T1, T2, TRet> func)
|
||||
=> base.RegisterFunc(func);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.SendMessage"/>
|
||||
public void SendMessage(T1 arg1, T2 arg2)
|
||||
=> base.SendMessage(arg1, arg2);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.Subscribe"/>
|
||||
public void Subscribe(Action<T1, T2> action)
|
||||
=> base.Subscribe(action);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.Unsubscribe"/>
|
||||
public void Unsubscribe(Action<T1, T2> action)
|
||||
=> base.Unsubscribe(action);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.InvokeAction"/>
|
||||
public void InvokeAction(T1 arg1, T2 arg2)
|
||||
=> base.InvokeAction(arg1, arg2);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.InvokeFunc"/>
|
||||
public TRet InvokeFunc(T1 arg1, T2 arg2)
|
||||
=> this.InvokeFunc<TRet>(arg1, arg2);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase"/>
|
||||
internal class CallGatePubSub<T1, T2, T3, TRet> : CallGatePubSubBase, ICallGateProvider<T1, T2, T3, TRet>, ICallGateSubscriber<T1, T2, T3, TRet>
|
||||
{
|
||||
/// <inheritdoc cref="CallGatePubSubBase(string)"/>
|
||||
public CallGatePubSub(string name)
|
||||
: base(name)
|
||||
/// <inheritdoc cref="CallGatePubSubBase"/>
|
||||
internal class CallGatePubSub<T1, T2, T3, TRet> : CallGatePubSubBase, ICallGateProvider<T1, T2, T3, TRet>, ICallGateSubscriber<T1, T2, T3, TRet>
|
||||
{
|
||||
/// <inheritdoc cref="CallGatePubSubBase(string)"/>
|
||||
public CallGatePubSub(string name)
|
||||
: base(name)
|
||||
{
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.RegisterAction"/>
|
||||
public void RegisterAction(Action<T1, T2, T3> action)
|
||||
=> base.RegisterAction(action);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.RegisterFunc"/>
|
||||
public void RegisterFunc(Func<T1, T2, T3, TRet> func)
|
||||
=> base.RegisterFunc(func);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.SendMessage"/>
|
||||
public void SendMessage(T1 arg1, T2 arg2, T3 arg3)
|
||||
=> base.SendMessage(arg1, arg2, arg3);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.Subscribe"/>
|
||||
public void Subscribe(Action<T1, T2, T3> action)
|
||||
=> base.Subscribe(action);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.Unsubscribe"/>
|
||||
public void Unsubscribe(Action<T1, T2, T3> action)
|
||||
=> base.Unsubscribe(action);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.InvokeAction"/>
|
||||
public void InvokeAction(T1 arg1, T2 arg2, T3 arg3)
|
||||
=> base.InvokeAction(arg1, arg2, arg3);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.InvokeFunc"/>
|
||||
public TRet InvokeFunc(T1 arg1, T2 arg2, T3 arg3)
|
||||
=> this.InvokeFunc<TRet>(arg1, arg2, arg3);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.RegisterAction"/>
|
||||
public void RegisterAction(Action<T1, T2, T3> action)
|
||||
=> base.RegisterAction(action);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.RegisterFunc"/>
|
||||
public void RegisterFunc(Func<T1, T2, T3, TRet> func)
|
||||
=> base.RegisterFunc(func);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.SendMessage"/>
|
||||
public void SendMessage(T1 arg1, T2 arg2, T3 arg3)
|
||||
=> base.SendMessage(arg1, arg2, arg3);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.Subscribe"/>
|
||||
public void Subscribe(Action<T1, T2, T3> action)
|
||||
=> base.Subscribe(action);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.Unsubscribe"/>
|
||||
public void Unsubscribe(Action<T1, T2, T3> action)
|
||||
=> base.Unsubscribe(action);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.InvokeAction"/>
|
||||
public void InvokeAction(T1 arg1, T2 arg2, T3 arg3)
|
||||
=> base.InvokeAction(arg1, arg2, arg3);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.InvokeFunc"/>
|
||||
public TRet InvokeFunc(T1 arg1, T2 arg2, T3 arg3)
|
||||
=> this.InvokeFunc<TRet>(arg1, arg2, arg3);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase"/>
|
||||
internal class CallGatePubSub<T1, T2, T3, T4, TRet> : CallGatePubSubBase, ICallGateProvider<T1, T2, T3, T4, TRet>, ICallGateSubscriber<T1, T2, T3, T4, TRet>
|
||||
{
|
||||
/// <inheritdoc cref="CallGatePubSubBase(string)"/>
|
||||
public CallGatePubSub(string name)
|
||||
: base(name)
|
||||
/// <inheritdoc cref="CallGatePubSubBase"/>
|
||||
internal class CallGatePubSub<T1, T2, T3, T4, TRet> : CallGatePubSubBase, ICallGateProvider<T1, T2, T3, T4, TRet>, ICallGateSubscriber<T1, T2, T3, T4, TRet>
|
||||
{
|
||||
/// <inheritdoc cref="CallGatePubSubBase(string)"/>
|
||||
public CallGatePubSub(string name)
|
||||
: base(name)
|
||||
{
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.RegisterAction"/>
|
||||
public void RegisterAction(Action<T1, T2, T3, T4> action)
|
||||
=> base.RegisterAction(action);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.RegisterFunc"/>
|
||||
public void RegisterFunc(Func<T1, T2, T3, T4, TRet> func)
|
||||
=> base.RegisterFunc(func);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.SendMessage"/>
|
||||
public void SendMessage(T1 arg1, T2 arg2, T3 arg3, T4 arg4)
|
||||
=> base.SendMessage(arg1, arg2, arg3, arg4);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.Subscribe"/>
|
||||
public void Subscribe(Action<T1, T2, T3, T4> action)
|
||||
=> base.Subscribe(action);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.Unsubscribe"/>
|
||||
public void Unsubscribe(Action<T1, T2, T3, T4> action)
|
||||
=> base.Unsubscribe(action);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.InvokeAction"/>
|
||||
public void InvokeAction(T1 arg1, T2 arg2, T3 arg3, T4 arg4)
|
||||
=> base.InvokeAction(arg1, arg2, arg3, arg4);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.InvokeFunc"/>
|
||||
public TRet InvokeFunc(T1 arg1, T2 arg2, T3 arg3, T4 arg4)
|
||||
=> this.InvokeFunc<TRet>(arg1, arg2, arg3, arg4);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.RegisterAction"/>
|
||||
public void RegisterAction(Action<T1, T2, T3, T4> action)
|
||||
=> base.RegisterAction(action);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.RegisterFunc"/>
|
||||
public void RegisterFunc(Func<T1, T2, T3, T4, TRet> func)
|
||||
=> base.RegisterFunc(func);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.SendMessage"/>
|
||||
public void SendMessage(T1 arg1, T2 arg2, T3 arg3, T4 arg4)
|
||||
=> base.SendMessage(arg1, arg2, arg3, arg4);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.Subscribe"/>
|
||||
public void Subscribe(Action<T1, T2, T3, T4> action)
|
||||
=> base.Subscribe(action);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.Unsubscribe"/>
|
||||
public void Unsubscribe(Action<T1, T2, T3, T4> action)
|
||||
=> base.Unsubscribe(action);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.InvokeAction"/>
|
||||
public void InvokeAction(T1 arg1, T2 arg2, T3 arg3, T4 arg4)
|
||||
=> base.InvokeAction(arg1, arg2, arg3, arg4);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.InvokeFunc"/>
|
||||
public TRet InvokeFunc(T1 arg1, T2 arg2, T3 arg3, T4 arg4)
|
||||
=> this.InvokeFunc<TRet>(arg1, arg2, arg3, arg4);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase"/>
|
||||
internal class CallGatePubSub<T1, T2, T3, T4, T5, TRet> : CallGatePubSubBase, ICallGateProvider<T1, T2, T3, T4, T5, TRet>, ICallGateSubscriber<T1, T2, T3, T4, T5, TRet>
|
||||
{
|
||||
/// <inheritdoc cref="CallGatePubSubBase(string)"/>
|
||||
public CallGatePubSub(string name)
|
||||
: base(name)
|
||||
/// <inheritdoc cref="CallGatePubSubBase"/>
|
||||
internal class CallGatePubSub<T1, T2, T3, T4, T5, TRet> : CallGatePubSubBase, ICallGateProvider<T1, T2, T3, T4, T5, TRet>, ICallGateSubscriber<T1, T2, T3, T4, T5, TRet>
|
||||
{
|
||||
/// <inheritdoc cref="CallGatePubSubBase(string)"/>
|
||||
public CallGatePubSub(string name)
|
||||
: base(name)
|
||||
{
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.RegisterAction"/>
|
||||
public void RegisterAction(Action<T1, T2, T3, T4, T5> action)
|
||||
=> base.RegisterAction(action);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.RegisterFunc"/>
|
||||
public void RegisterFunc(Func<T1, T2, T3, T4, T5, TRet> func)
|
||||
=> base.RegisterFunc(func);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.SendMessage"/>
|
||||
public void SendMessage(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5)
|
||||
=> base.SendMessage(arg1, arg2, arg3, arg4, arg5);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.Subscribe"/>
|
||||
public void Subscribe(Action<T1, T2, T3, T4, T5> action)
|
||||
=> base.Subscribe(action);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.Unsubscribe"/>
|
||||
public void Unsubscribe(Action<T1, T2, T3, T4, T5> action)
|
||||
=> base.Unsubscribe(action);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.InvokeAction"/>
|
||||
public void InvokeAction(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5)
|
||||
=> base.InvokeAction(arg1, arg2, arg3, arg4, arg5);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.InvokeFunc"/>
|
||||
public TRet InvokeFunc(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5)
|
||||
=> this.InvokeFunc<TRet>(arg1, arg2, arg3, arg4, arg5);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.RegisterAction"/>
|
||||
public void RegisterAction(Action<T1, T2, T3, T4, T5> action)
|
||||
=> base.RegisterAction(action);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.RegisterFunc"/>
|
||||
public void RegisterFunc(Func<T1, T2, T3, T4, T5, TRet> func)
|
||||
=> base.RegisterFunc(func);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.SendMessage"/>
|
||||
public void SendMessage(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5)
|
||||
=> base.SendMessage(arg1, arg2, arg3, arg4, arg5);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.Subscribe"/>
|
||||
public void Subscribe(Action<T1, T2, T3, T4, T5> action)
|
||||
=> base.Subscribe(action);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.Unsubscribe"/>
|
||||
public void Unsubscribe(Action<T1, T2, T3, T4, T5> action)
|
||||
=> base.Unsubscribe(action);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.InvokeAction"/>
|
||||
public void InvokeAction(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5)
|
||||
=> base.InvokeAction(arg1, arg2, arg3, arg4, arg5);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.InvokeFunc"/>
|
||||
public TRet InvokeFunc(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5)
|
||||
=> this.InvokeFunc<TRet>(arg1, arg2, arg3, arg4, arg5);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase"/>
|
||||
internal class CallGatePubSub<T1, T2, T3, T4, T5, T6, TRet> : CallGatePubSubBase, ICallGateProvider<T1, T2, T3, T4, T5, T6, TRet>, ICallGateSubscriber<T1, T2, T3, T4, T5, T6, TRet>
|
||||
{
|
||||
/// <inheritdoc cref="CallGatePubSubBase(string)"/>
|
||||
public CallGatePubSub(string name)
|
||||
: base(name)
|
||||
/// <inheritdoc cref="CallGatePubSubBase"/>
|
||||
internal class CallGatePubSub<T1, T2, T3, T4, T5, T6, TRet> : CallGatePubSubBase, ICallGateProvider<T1, T2, T3, T4, T5, T6, TRet>, ICallGateSubscriber<T1, T2, T3, T4, T5, T6, TRet>
|
||||
{
|
||||
/// <inheritdoc cref="CallGatePubSubBase(string)"/>
|
||||
public CallGatePubSub(string name)
|
||||
: base(name)
|
||||
{
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.RegisterAction"/>
|
||||
public void RegisterAction(Action<T1, T2, T3, T4, T5, T6> action)
|
||||
=> base.RegisterAction(action);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.RegisterFunc"/>
|
||||
public void RegisterFunc(Func<T1, T2, T3, T4, T5, T6, TRet> func)
|
||||
=> base.RegisterFunc(func);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.SendMessage"/>
|
||||
public void SendMessage(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6)
|
||||
=> base.SendMessage(arg1, arg2, arg3, arg4, arg5, arg6);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.Subscribe"/>
|
||||
public void Subscribe(Action<T1, T2, T3, T4, T5, T6> action)
|
||||
=> base.Subscribe(action);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.Unsubscribe"/>
|
||||
public void Unsubscribe(Action<T1, T2, T3, T4, T5, T6> action)
|
||||
=> base.Unsubscribe(action);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.InvokeAction"/>
|
||||
public void InvokeAction(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6)
|
||||
=> base.InvokeAction(arg1, arg2, arg3, arg4, arg5, arg6);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.InvokeFunc"/>
|
||||
public TRet InvokeFunc(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6)
|
||||
=> this.InvokeFunc<TRet>(arg1, arg2, arg3, arg4, arg5, arg6);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.RegisterAction"/>
|
||||
public void RegisterAction(Action<T1, T2, T3, T4, T5, T6> action)
|
||||
=> base.RegisterAction(action);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.RegisterFunc"/>
|
||||
public void RegisterFunc(Func<T1, T2, T3, T4, T5, T6, TRet> func)
|
||||
=> base.RegisterFunc(func);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.SendMessage"/>
|
||||
public void SendMessage(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6)
|
||||
=> base.SendMessage(arg1, arg2, arg3, arg4, arg5, arg6);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.Subscribe"/>
|
||||
public void Subscribe(Action<T1, T2, T3, T4, T5, T6> action)
|
||||
=> base.Subscribe(action);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.Unsubscribe"/>
|
||||
public void Unsubscribe(Action<T1, T2, T3, T4, T5, T6> action)
|
||||
=> base.Unsubscribe(action);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.InvokeAction"/>
|
||||
public void InvokeAction(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6)
|
||||
=> base.InvokeAction(arg1, arg2, arg3, arg4, arg5, arg6);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.InvokeFunc"/>
|
||||
public TRet InvokeFunc(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6)
|
||||
=> this.InvokeFunc<TRet>(arg1, arg2, arg3, arg4, arg5, arg6);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase"/>
|
||||
internal class CallGatePubSub<T1, T2, T3, T4, T5, T6, T7, TRet> : CallGatePubSubBase, ICallGateProvider<T1, T2, T3, T4, T5, T6, T7, TRet>, ICallGateSubscriber<T1, T2, T3, T4, T5, T6, T7, TRet>
|
||||
{
|
||||
/// <inheritdoc cref="CallGatePubSubBase(string)"/>
|
||||
public CallGatePubSub(string name)
|
||||
: base(name)
|
||||
/// <inheritdoc cref="CallGatePubSubBase"/>
|
||||
internal class CallGatePubSub<T1, T2, T3, T4, T5, T6, T7, TRet> : CallGatePubSubBase, ICallGateProvider<T1, T2, T3, T4, T5, T6, T7, TRet>, ICallGateSubscriber<T1, T2, T3, T4, T5, T6, T7, TRet>
|
||||
{
|
||||
/// <inheritdoc cref="CallGatePubSubBase(string)"/>
|
||||
public CallGatePubSub(string name)
|
||||
: base(name)
|
||||
{
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.RegisterAction"/>
|
||||
public void RegisterAction(Action<T1, T2, T3, T4, T5, T6, T7> action)
|
||||
=> base.RegisterAction(action);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.RegisterFunc"/>
|
||||
public void RegisterFunc(Func<T1, T2, T3, T4, T5, T6, T7, TRet> func)
|
||||
=> base.RegisterFunc(func);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.SendMessage"/>
|
||||
public void SendMessage(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7)
|
||||
=> base.SendMessage(arg1, arg2, arg3, arg4, arg5, arg6, arg7);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.Subscribe"/>
|
||||
public void Subscribe(Action<T1, T2, T3, T4, T5, T6, T7> action)
|
||||
=> base.Subscribe(action);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.Unsubscribe"/>
|
||||
public void Unsubscribe(Action<T1, T2, T3, T4, T5, T6, T7> action)
|
||||
=> base.Unsubscribe(action);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.InvokeAction"/>
|
||||
public void InvokeAction(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7)
|
||||
=> base.InvokeAction(arg1, arg2, arg3, arg4, arg5, arg6, arg7);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.InvokeFunc"/>
|
||||
public TRet InvokeFunc(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7)
|
||||
=> this.InvokeFunc<TRet>(arg1, arg2, arg3, arg4, arg5, arg6, arg7);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.RegisterAction"/>
|
||||
public void RegisterAction(Action<T1, T2, T3, T4, T5, T6, T7> action)
|
||||
=> base.RegisterAction(action);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.RegisterFunc"/>
|
||||
public void RegisterFunc(Func<T1, T2, T3, T4, T5, T6, T7, TRet> func)
|
||||
=> base.RegisterFunc(func);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.SendMessage"/>
|
||||
public void SendMessage(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7)
|
||||
=> base.SendMessage(arg1, arg2, arg3, arg4, arg5, arg6, arg7);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.Subscribe"/>
|
||||
public void Subscribe(Action<T1, T2, T3, T4, T5, T6, T7> action)
|
||||
=> base.Subscribe(action);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.Unsubscribe"/>
|
||||
public void Unsubscribe(Action<T1, T2, T3, T4, T5, T6, T7> action)
|
||||
=> base.Unsubscribe(action);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.InvokeAction"/>
|
||||
public void InvokeAction(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7)
|
||||
=> base.InvokeAction(arg1, arg2, arg3, arg4, arg5, arg6, arg7);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.InvokeFunc"/>
|
||||
public TRet InvokeFunc(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7)
|
||||
=> this.InvokeFunc<TRet>(arg1, arg2, arg3, arg4, arg5, arg6, arg7);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase"/>
|
||||
internal class CallGatePubSub<T1, T2, T3, T4, T5, T6, T7, T8, TRet> : CallGatePubSubBase, ICallGateProvider<T1, T2, T3, T4, T5, T6, T7, T8, TRet>, ICallGateSubscriber<T1, T2, T3, T4, T5, T6, T7, T8, TRet>
|
||||
{
|
||||
/// <inheritdoc cref="CallGatePubSubBase(string)"/>
|
||||
public CallGatePubSub(string name)
|
||||
: base(name)
|
||||
/// <inheritdoc cref="CallGatePubSubBase"/>
|
||||
internal class CallGatePubSub<T1, T2, T3, T4, T5, T6, T7, T8, TRet> : CallGatePubSubBase, ICallGateProvider<T1, T2, T3, T4, T5, T6, T7, T8, TRet>, ICallGateSubscriber<T1, T2, T3, T4, T5, T6, T7, T8, TRet>
|
||||
{
|
||||
/// <inheritdoc cref="CallGatePubSubBase(string)"/>
|
||||
public CallGatePubSub(string name)
|
||||
: base(name)
|
||||
{
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.RegisterAction"/>
|
||||
public void RegisterAction(Action<T1, T2, T3, T4, T5, T6, T7, T8> action)
|
||||
=> base.RegisterAction(action);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.RegisterFunc"/>
|
||||
public void RegisterFunc(Func<T1, T2, T3, T4, T5, T6, T7, T8, TRet> func)
|
||||
=> base.RegisterFunc(func);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.SendMessage"/>
|
||||
public void SendMessage(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8)
|
||||
=> base.SendMessage(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.Subscribe"/>
|
||||
public void Subscribe(Action<T1, T2, T3, T4, T5, T6, T7, T8> action)
|
||||
=> base.Subscribe(action);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.Unsubscribe"/>
|
||||
public void Unsubscribe(Action<T1, T2, T3, T4, T5, T6, T7, T8> action)
|
||||
=> base.Unsubscribe(action);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.InvokeAction"/>
|
||||
public void InvokeAction(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8)
|
||||
=> base.InvokeAction(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.InvokeFunc"/>
|
||||
public TRet InvokeFunc(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8)
|
||||
=> this.InvokeFunc<TRet>(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.RegisterAction"/>
|
||||
public void RegisterAction(Action<T1, T2, T3, T4, T5, T6, T7, T8> action)
|
||||
=> base.RegisterAction(action);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.RegisterFunc"/>
|
||||
public void RegisterFunc(Func<T1, T2, T3, T4, T5, T6, T7, T8, TRet> func)
|
||||
=> base.RegisterFunc(func);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.SendMessage"/>
|
||||
public void SendMessage(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8)
|
||||
=> base.SendMessage(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.Subscribe"/>
|
||||
public void Subscribe(Action<T1, T2, T3, T4, T5, T6, T7, T8> action)
|
||||
=> base.Subscribe(action);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.Unsubscribe"/>
|
||||
public void Unsubscribe(Action<T1, T2, T3, T4, T5, T6, T7, T8> action)
|
||||
=> base.Unsubscribe(action);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.InvokeAction"/>
|
||||
public void InvokeAction(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8)
|
||||
=> base.InvokeAction(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8);
|
||||
|
||||
/// <inheritdoc cref="CallGatePubSubBase.InvokeFunc"/>
|
||||
public TRet InvokeFunc(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8)
|
||||
=> this.InvokeFunc<TRet>(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8);
|
||||
}
|
||||
|
||||
#pragma warning restore SA1402 // File may only contain a single type
|
||||
|
|
|
|||
|
|
@ -2,89 +2,90 @@ using System;
|
|||
|
||||
using Dalamud.Plugin.Ipc.Exceptions;
|
||||
|
||||
namespace Dalamud.Plugin.Ipc.Internal;
|
||||
|
||||
/// <summary>
|
||||
/// This class facilitates inter-plugin communication.
|
||||
/// </summary>
|
||||
internal abstract class CallGatePubSubBase
|
||||
namespace Dalamud.Plugin.Ipc.Internal
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="CallGatePubSubBase"/> class.
|
||||
/// This class facilitates inter-plugin communication.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of the IPC registration.</param>
|
||||
public CallGatePubSubBase(string name)
|
||||
internal abstract class CallGatePubSubBase
|
||||
{
|
||||
this.Channel = Service<CallGate>.Get().GetOrCreateChannel(name);
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="CallGatePubSubBase"/> class.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of the IPC registration.</param>
|
||||
public CallGatePubSubBase(string name)
|
||||
{
|
||||
this.Channel = Service<CallGate>.Get().GetOrCreateChannel(name);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the underlying channel implementation.
|
||||
/// </summary>
|
||||
protected CallGateChannel Channel { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Removes a registered Action from inter-plugin communication.
|
||||
/// </summary>
|
||||
public void UnregisterAction()
|
||||
=> this.Channel.Action = null;
|
||||
|
||||
/// <summary>
|
||||
/// Removes a registered Func from inter-plugin communication.
|
||||
/// </summary>
|
||||
public void UnregisterFunc()
|
||||
=> this.Channel.Func = null;
|
||||
|
||||
/// <summary>
|
||||
/// Registers an Action for inter-plugin communication.
|
||||
/// </summary>
|
||||
/// <param name="action">Action to register.</param>
|
||||
private protected void RegisterAction(Delegate action)
|
||||
=> this.Channel.Action = action;
|
||||
|
||||
/// <summary>
|
||||
/// Registers a Func for inter-plugin communication.
|
||||
/// </summary>
|
||||
/// <param name="func">Func to register.</param>
|
||||
private protected void RegisterFunc(Delegate func)
|
||||
=> this.Channel.Func = func;
|
||||
|
||||
/// <summary>
|
||||
/// Subscribe an expression to this registration.
|
||||
/// </summary>
|
||||
/// <param name="action">Action to subscribe.</param>
|
||||
private protected void Subscribe(Delegate action)
|
||||
=> this.Channel.Subscriptions.Add(action);
|
||||
|
||||
/// <summary>
|
||||
/// Unsubscribe an expression from this registration.
|
||||
/// </summary>
|
||||
/// <param name="action">Action to unsubscribe.</param>
|
||||
private protected void Unsubscribe(Delegate action)
|
||||
=> this.Channel.Subscriptions.Remove(action);
|
||||
|
||||
/// <summary>
|
||||
/// Invoke an action registered for inter-plugin communication.
|
||||
/// </summary>
|
||||
/// <param name="args">Action arguments.</param>
|
||||
/// <exception cref="IpcNotReadyError">This is thrown when the IPC publisher has not registered an action for calling yet.</exception>
|
||||
private protected void InvokeAction(params object?[]? args)
|
||||
=> this.Channel.InvokeAction(args);
|
||||
|
||||
/// <summary>
|
||||
/// Invoke a function registered for inter-plugin communication.
|
||||
/// </summary>
|
||||
/// <param name="args">Parameter args.</param>
|
||||
/// <returns>The return value.</returns>
|
||||
/// <typeparam name="TRet">The return type.</typeparam>
|
||||
/// <exception cref="IpcNotReadyError">This is thrown when the IPC publisher has not registered a func for calling yet.</exception>
|
||||
private protected TRet InvokeFunc<TRet>(params object?[]? args)
|
||||
=> this.Channel.InvokeFunc<TRet>(args);
|
||||
|
||||
/// <summary>
|
||||
/// Invoke all actions that have subscribed to this IPC.
|
||||
/// </summary>
|
||||
/// <param name="args">Delegate arguments.</param>
|
||||
private protected void SendMessage(params object?[]? args)
|
||||
=> this.Channel.SendMessage(args);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the underlying channel implementation.
|
||||
/// </summary>
|
||||
protected CallGateChannel Channel { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Removes a registered Action from inter-plugin communication.
|
||||
/// </summary>
|
||||
public void UnregisterAction()
|
||||
=> this.Channel.Action = null;
|
||||
|
||||
/// <summary>
|
||||
/// Removes a registered Func from inter-plugin communication.
|
||||
/// </summary>
|
||||
public void UnregisterFunc()
|
||||
=> this.Channel.Func = null;
|
||||
|
||||
/// <summary>
|
||||
/// Registers an Action for inter-plugin communication.
|
||||
/// </summary>
|
||||
/// <param name="action">Action to register.</param>
|
||||
private protected void RegisterAction(Delegate action)
|
||||
=> this.Channel.Action = action;
|
||||
|
||||
/// <summary>
|
||||
/// Registers a Func for inter-plugin communication.
|
||||
/// </summary>
|
||||
/// <param name="func">Func to register.</param>
|
||||
private protected void RegisterFunc(Delegate func)
|
||||
=> this.Channel.Func = func;
|
||||
|
||||
/// <summary>
|
||||
/// Subscribe an expression to this registration.
|
||||
/// </summary>
|
||||
/// <param name="action">Action to subscribe.</param>
|
||||
private protected void Subscribe(Delegate action)
|
||||
=> this.Channel.Subscriptions.Add(action);
|
||||
|
||||
/// <summary>
|
||||
/// Unsubscribe an expression from this registration.
|
||||
/// </summary>
|
||||
/// <param name="action">Action to unsubscribe.</param>
|
||||
private protected void Unsubscribe(Delegate action)
|
||||
=> this.Channel.Subscriptions.Remove(action);
|
||||
|
||||
/// <summary>
|
||||
/// Invoke an action registered for inter-plugin communication.
|
||||
/// </summary>
|
||||
/// <param name="args">Action arguments.</param>
|
||||
/// <exception cref="IpcNotReadyError">This is thrown when the IPC publisher has not registered an action for calling yet.</exception>
|
||||
private protected void InvokeAction(params object?[]? args)
|
||||
=> this.Channel.InvokeAction(args);
|
||||
|
||||
/// <summary>
|
||||
/// Invoke a function registered for inter-plugin communication.
|
||||
/// </summary>
|
||||
/// <param name="args">Parameter args.</param>
|
||||
/// <returns>The return value.</returns>
|
||||
/// <typeparam name="TRet">The return type.</typeparam>
|
||||
/// <exception cref="IpcNotReadyError">This is thrown when the IPC publisher has not registered a func for calling yet.</exception>
|
||||
private protected TRet InvokeFunc<TRet>(params object?[]? args)
|
||||
=> this.Channel.InvokeFunc<TRet>(args);
|
||||
|
||||
/// <summary>
|
||||
/// Invoke all actions that have subscribed to this IPC.
|
||||
/// </summary>
|
||||
/// <param name="args">Delegate arguments.</param>
|
||||
private protected void SendMessage(params object?[]? args)
|
||||
=> this.Channel.SendMessage(args);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,32 +1,33 @@
|
|||
namespace Dalamud.Plugin;
|
||||
|
||||
/// <summary>
|
||||
/// This enum reflects reasons for loading a plugin.
|
||||
/// </summary>
|
||||
public enum PluginLoadReason
|
||||
namespace Dalamud.Plugin
|
||||
{
|
||||
/// <summary>
|
||||
/// We don't know why this plugin was loaded.
|
||||
/// This enum reflects reasons for loading a plugin.
|
||||
/// </summary>
|
||||
Unknown,
|
||||
public enum PluginLoadReason
|
||||
{
|
||||
/// <summary>
|
||||
/// We don't know why this plugin was loaded.
|
||||
/// </summary>
|
||||
Unknown,
|
||||
|
||||
/// <summary>
|
||||
/// This plugin was loaded because it was installed with the plugin installer.
|
||||
/// </summary>
|
||||
Installer,
|
||||
/// <summary>
|
||||
/// This plugin was loaded because it was installed with the plugin installer.
|
||||
/// </summary>
|
||||
Installer,
|
||||
|
||||
/// <summary>
|
||||
/// This plugin was loaded because it was just updated.
|
||||
/// </summary>
|
||||
Update,
|
||||
/// <summary>
|
||||
/// This plugin was loaded because it was just updated.
|
||||
/// </summary>
|
||||
Update,
|
||||
|
||||
/// <summary>
|
||||
/// This plugin was loaded because it was told to reload.
|
||||
/// </summary>
|
||||
Reload,
|
||||
/// <summary>
|
||||
/// This plugin was loaded because it was told to reload.
|
||||
/// </summary>
|
||||
Reload,
|
||||
|
||||
/// <summary>
|
||||
/// This plugin was loaded because the game was started or Dalamud was reinjected.
|
||||
/// </summary>
|
||||
Boot,
|
||||
/// <summary>
|
||||
/// This plugin was loaded because the game was started or Dalamud was reinjected.
|
||||
/// </summary>
|
||||
Boot,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue