diff --git a/Dalamud/Interface/Internal/Windows/PluginInstaller/PluginInstallerWindow.cs b/Dalamud/Interface/Internal/Windows/PluginInstaller/PluginInstallerWindow.cs
index 3b3804baa..d28401e73 100644
--- a/Dalamud/Interface/Internal/Windows/PluginInstaller/PluginInstallerWindow.cs
+++ b/Dalamud/Interface/Internal/Windows/PluginInstaller/PluginInstallerWindow.cs
@@ -327,6 +327,46 @@ internal class PluginInstallerWindow : Window, IDisposable
});
}
+ ///
+ /// A continuation task that displays any errors received into the error modal.
+ ///
+ /// The previous task.
+ /// An error message to be displayed.
+ /// A value indicating whether to continue with the next task.
+ public bool DisplayErrorContinuation(Task task, object state)
+ {
+ if (task.IsFaulted)
+ {
+ var errorModalMessage = state as string;
+
+ foreach (var ex in task.Exception.InnerExceptions)
+ {
+ if (ex is PluginException)
+ {
+ Log.Error(ex, "Plugin installer threw an error");
+#if DEBUG
+ if (!string.IsNullOrEmpty(ex.Message))
+ errorModalMessage += $"\n\n{ex.Message}";
+#endif
+ }
+ else
+ {
+ Log.Error(ex, "Plugin installer threw an unexpected error");
+#if DEBUG
+ if (!string.IsNullOrEmpty(ex.Message))
+ errorModalMessage += $"\n\n{ex.Message}";
+#endif
+ }
+ }
+
+ this.ShowErrorModal(errorModalMessage);
+
+ return false;
+ }
+
+ return true;
+ }
+
private void DrawProgressOverlay()
{
var pluginManager = Service.Get();
@@ -2155,7 +2195,7 @@ internal class PluginInstallerWindow : Window, IDisposable
this.DrawSendFeedbackButton(plugin.Manifest, plugin.IsTesting);
}
- if (availablePluginUpdate != default && ! plugin.IsDev)
+ if (availablePluginUpdate != default && !plugin.IsDev)
this.DrawUpdateSinglePluginButton(availablePluginUpdate);
ImGui.SameLine();
@@ -2914,46 +2954,6 @@ internal class PluginInstallerWindow : Window, IDisposable
private bool WasPluginSeen(string internalName) =>
Service.Get().SeenPluginInternalName.Contains(internalName);
- ///
- /// A continuation task that displays any errors received into the error modal.
- ///
- /// The previous task.
- /// An error message to be displayed.
- /// A value indicating whether to continue with the next task.
- public bool DisplayErrorContinuation(Task task, object state)
- {
- if (task.IsFaulted)
- {
- var errorModalMessage = state as string;
-
- foreach (var ex in task.Exception.InnerExceptions)
- {
- if (ex is PluginException)
- {
- Log.Error(ex, "Plugin installer threw an error");
-#if DEBUG
- if (!string.IsNullOrEmpty(ex.Message))
- errorModalMessage += $"\n\n{ex.Message}";
-#endif
- }
- else
- {
- Log.Error(ex, "Plugin installer threw an unexpected error");
-#if DEBUG
- if (!string.IsNullOrEmpty(ex.Message))
- errorModalMessage += $"\n\n{ex.Message}";
-#endif
- }
- }
-
- this.ShowErrorModal(errorModalMessage);
-
- return false;
- }
-
- return true;
- }
-
private Task ShowErrorModal(string message)
{
this.errorModalMessage = message;
diff --git a/Dalamud/Interface/Internal/Windows/PluginInstaller/ProfileManagerWidget.cs b/Dalamud/Interface/Internal/Windows/PluginInstaller/ProfileManagerWidget.cs
index 1448074f3..60f605f8e 100644
--- a/Dalamud/Interface/Internal/Windows/PluginInstaller/ProfileManagerWidget.cs
+++ b/Dalamud/Interface/Internal/Windows/PluginInstaller/ProfileManagerWidget.cs
@@ -16,6 +16,9 @@ using Serilog;
namespace Dalamud.Interface.Internal.Windows.PluginInstaller;
+///
+/// ImGui widget used to manage profiles.
+///
internal class ProfileManagerWidget
{
private readonly PluginInstallerWindow installer;
@@ -25,11 +28,24 @@ internal class ProfileManagerWidget
private string pickerSearch = string.Empty;
private string profileNameEdit = string.Empty;
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The plugin installer.
public ProfileManagerWidget(PluginInstallerWindow installer)
{
this.installer = installer;
}
+ private enum Mode
+ {
+ Overview,
+ EditSingleProfile,
+ }
+
+ ///
+ /// Draw this widget's contents.
+ ///
public void Draw()
{
switch (this.mode)
@@ -44,6 +60,9 @@ internal class ProfileManagerWidget
}
}
+ ///
+ /// Reset the widget.
+ ///
public void Reset()
{
this.mode = Mode.Overview;
@@ -428,12 +447,6 @@ internal class ProfileManagerWidget
}
}
- private enum Mode
- {
- Overview,
- EditSingleProfile,
- }
-
private static class Locs
{
public static string TooltipEnableDisable =>
diff --git a/Dalamud/Plugin/Internal/PluginManager.cs b/Dalamud/Plugin/Internal/PluginManager.cs
index a0283ca67..162b6c90b 100644
--- a/Dalamud/Plugin/Internal/PluginManager.cs
+++ b/Dalamud/Plugin/Internal/PluginManager.cs
@@ -816,137 +816,6 @@ internal partial class PluginManager : IDisposable, IServiceType
return plugin;
}
- ///
- /// Load a plugin.
- ///
- /// The associated with the main assembly of this plugin.
- /// The already loaded definition, if available.
- /// The reason this plugin was loaded.
- /// If this plugin should support development features.
- /// If this plugin is being loaded at boot.
- /// Don't load the plugin, just don't do it.
- /// The loaded plugin.
- private async Task LoadPluginAsync(FileInfo dllFile, LocalPluginManifest? manifest, PluginLoadReason reason, bool isDev = false, bool isBoot = false, bool doNotLoad = false)
- {
- var name = manifest?.Name ?? dllFile.Name;
- var loadPlugin = !doNotLoad;
-
- LocalPlugin plugin;
-
- if (manifest != null && manifest.InternalName == null)
- {
- Log.Error("{FileName}: Your manifest has no internal name set! Can't load this.", dllFile.FullName);
- throw new Exception("No internal name");
- }
-
- if (isDev)
- {
- Log.Information($"Loading dev plugin {name}");
- var devPlugin = new LocalDevPlugin(dllFile, manifest);
- loadPlugin &= !isBoot || devPlugin.StartOnBoot;
-
- var probablyInternalNameForThisPurpose = manifest?.InternalName ?? dllFile.Name;
- var wantsInDefaultProfile =
- this.profileManager.DefaultProfile.WantsPlugin(probablyInternalNameForThisPurpose);
- if (wantsInDefaultProfile == false && devPlugin.StartOnBoot)
- {
- this.profileManager.DefaultProfile.AddOrUpdate(probablyInternalNameForThisPurpose, true, false);
- }
- else if (wantsInDefaultProfile == true && !devPlugin.StartOnBoot)
- {
- this.profileManager.DefaultProfile.AddOrUpdate(probablyInternalNameForThisPurpose, false, false);
- }
-
- plugin = devPlugin;
- }
- else
- {
- Log.Information($"Loading plugin {name}");
- plugin = new LocalPlugin(dllFile, manifest);
- }
-
-#pragma warning disable CS0618
- var defaultState = manifest?.Disabled != true && loadPlugin;
-#pragma warning restore CS0618
-
- // Need to do this here, so plugins that don't load are still added to the default profile
- var wantToLoad = this.profileManager.GetWantState(plugin.Manifest.InternalName, defaultState);
-
- if (loadPlugin)
- {
- try
- {
- if (wantToLoad && !plugin.IsOrphaned)
- {
- await plugin.LoadAsync(reason);
- }
- else
- {
- Log.Verbose($"{name} not loaded, wantToLoad:{wantToLoad} orphaned:{plugin.IsOrphaned}");
- }
- }
- catch (InvalidPluginException)
- {
- PluginLocations.Remove(plugin.AssemblyName?.FullName ?? string.Empty, out _);
- throw;
- }
- catch (BannedPluginException)
- {
- // Out of date plugins get added so they can be updated.
- Log.Information($"Plugin was banned, adding anyways: {dllFile.Name}");
- }
- catch (Exception ex)
- {
- if (plugin.IsDev)
- {
- // Dev plugins always get added to the list so they can be fiddled with in the UI
- Log.Information(ex, $"Dev plugin failed to load, adding anyways: {dllFile.Name}");
-
- // NOTE(goat): This can't work - plugins don't "unload" if they fail to load.
- // plugin.Disable(); // Disable here, otherwise you can't enable+load later
- }
- else if (plugin.IsOutdated)
- {
- // Out of date plugins get added, so they can be updated.
- Log.Information(ex, $"Plugin was outdated, adding anyways: {dllFile.Name}");
- }
- else if (plugin.IsOrphaned)
- {
- // Orphaned plugins get added, so that users aren't confused.
- Log.Information(ex, $"Plugin was orphaned, adding anyways: {dllFile.Name}");
- }
- else if (isBoot)
- {
- // During boot load, plugins always get added to the list so they can be fiddled with in the UI
- Log.Information(ex, $"Regular plugin failed to load, adding anyways: {dllFile.Name}");
-
- // NOTE(goat): This can't work - plugins don't "unload" if they fail to load.
- // plugin.Disable(); // Disable here, otherwise you can't enable+load later
- }
- else if (!plugin.CheckPolicy())
- {
- // During boot load, plugins always get added to the list so they can be fiddled with in the UI
- Log.Information(ex, $"Plugin not loaded due to policy, adding anyways: {dllFile.Name}");
-
- // NOTE(goat): This can't work - plugins don't "unload" if they fail to load.
- // plugin.Disable(); // Disable here, otherwise you can't enable+load later
- }
- else
- {
- PluginLocations.Remove(plugin.AssemblyName?.FullName ?? string.Empty, out _);
- throw;
- }
- }
- }
-
- lock (this.pluginListLock)
- {
- this.InstalledPlugins = this.InstalledPlugins.Add(plugin);
- }
-
- return plugin;
- }
-
///
/// Remove a plugin.
///
@@ -1330,6 +1199,137 @@ internal partial class PluginManager : IDisposable, IServiceType
/// The calling plugin, or null.
public LocalPlugin? FindCallingPlugin() => this.FindCallingPlugin(new StackTrace());
+ ///
+ /// Load a plugin.
+ ///
+ /// The associated with the main assembly of this plugin.
+ /// The already loaded definition, if available.
+ /// The reason this plugin was loaded.
+ /// If this plugin should support development features.
+ /// If this plugin is being loaded at boot.
+ /// Don't load the plugin, just don't do it.
+ /// The loaded plugin.
+ private async Task LoadPluginAsync(FileInfo dllFile, LocalPluginManifest? manifest, PluginLoadReason reason, bool isDev = false, bool isBoot = false, bool doNotLoad = false)
+ {
+ var name = manifest?.Name ?? dllFile.Name;
+ var loadPlugin = !doNotLoad;
+
+ LocalPlugin plugin;
+
+ if (manifest != null && manifest.InternalName == null)
+ {
+ Log.Error("{FileName}: Your manifest has no internal name set! Can't load this.", dllFile.FullName);
+ throw new Exception("No internal name");
+ }
+
+ if (isDev)
+ {
+ Log.Information($"Loading dev plugin {name}");
+ var devPlugin = new LocalDevPlugin(dllFile, manifest);
+ loadPlugin &= !isBoot || devPlugin.StartOnBoot;
+
+ var probablyInternalNameForThisPurpose = manifest?.InternalName ?? dllFile.Name;
+ var wantsInDefaultProfile =
+ this.profileManager.DefaultProfile.WantsPlugin(probablyInternalNameForThisPurpose);
+ if (wantsInDefaultProfile == false && devPlugin.StartOnBoot)
+ {
+ this.profileManager.DefaultProfile.AddOrUpdate(probablyInternalNameForThisPurpose, true, false);
+ }
+ else if (wantsInDefaultProfile == true && !devPlugin.StartOnBoot)
+ {
+ this.profileManager.DefaultProfile.AddOrUpdate(probablyInternalNameForThisPurpose, false, false);
+ }
+
+ plugin = devPlugin;
+ }
+ else
+ {
+ Log.Information($"Loading plugin {name}");
+ plugin = new LocalPlugin(dllFile, manifest);
+ }
+
+#pragma warning disable CS0618
+ var defaultState = manifest?.Disabled != true && loadPlugin;
+#pragma warning restore CS0618
+
+ // Need to do this here, so plugins that don't load are still added to the default profile
+ var wantToLoad = this.profileManager.GetWantState(plugin.Manifest.InternalName, defaultState);
+
+ if (loadPlugin)
+ {
+ try
+ {
+ if (wantToLoad && !plugin.IsOrphaned)
+ {
+ await plugin.LoadAsync(reason);
+ }
+ else
+ {
+ Log.Verbose($"{name} not loaded, wantToLoad:{wantToLoad} orphaned:{plugin.IsOrphaned}");
+ }
+ }
+ catch (InvalidPluginException)
+ {
+ PluginLocations.Remove(plugin.AssemblyName?.FullName ?? string.Empty, out _);
+ throw;
+ }
+ catch (BannedPluginException)
+ {
+ // Out of date plugins get added so they can be updated.
+ Log.Information($"Plugin was banned, adding anyways: {dllFile.Name}");
+ }
+ catch (Exception ex)
+ {
+ if (plugin.IsDev)
+ {
+ // Dev plugins always get added to the list so they can be fiddled with in the UI
+ Log.Information(ex, $"Dev plugin failed to load, adding anyways: {dllFile.Name}");
+
+ // NOTE(goat): This can't work - plugins don't "unload" if they fail to load.
+ // plugin.Disable(); // Disable here, otherwise you can't enable+load later
+ }
+ else if (plugin.IsOutdated)
+ {
+ // Out of date plugins get added, so they can be updated.
+ Log.Information(ex, $"Plugin was outdated, adding anyways: {dllFile.Name}");
+ }
+ else if (plugin.IsOrphaned)
+ {
+ // Orphaned plugins get added, so that users aren't confused.
+ Log.Information(ex, $"Plugin was orphaned, adding anyways: {dllFile.Name}");
+ }
+ else if (isBoot)
+ {
+ // During boot load, plugins always get added to the list so they can be fiddled with in the UI
+ Log.Information(ex, $"Regular plugin failed to load, adding anyways: {dllFile.Name}");
+
+ // NOTE(goat): This can't work - plugins don't "unload" if they fail to load.
+ // plugin.Disable(); // Disable here, otherwise you can't enable+load later
+ }
+ else if (!plugin.CheckPolicy())
+ {
+ // During boot load, plugins always get added to the list so they can be fiddled with in the UI
+ Log.Information(ex, $"Plugin not loaded due to policy, adding anyways: {dllFile.Name}");
+
+ // NOTE(goat): This can't work - plugins don't "unload" if they fail to load.
+ // plugin.Disable(); // Disable here, otherwise you can't enable+load later
+ }
+ else
+ {
+ PluginLocations.Remove(plugin.AssemblyName?.FullName ?? string.Empty, out _);
+ throw;
+ }
+ }
+ }
+
+ lock (this.pluginListLock)
+ {
+ this.InstalledPlugins = this.InstalledPlugins.Add(plugin);
+ }
+
+ return plugin;
+ }
+
private void DetectAvailablePluginUpdates()
{
var updatablePlugins = new List();
diff --git a/Dalamud/Plugin/Internal/Profiles/ProfileCommandHandler.cs b/Dalamud/Plugin/Internal/Profiles/ProfileCommandHandler.cs
index 994069335..aa72200a1 100644
--- a/Dalamud/Plugin/Internal/Profiles/ProfileCommandHandler.cs
+++ b/Dalamud/Plugin/Internal/Profiles/ProfileCommandHandler.cs
@@ -61,6 +61,13 @@ internal class ProfileCommandHandler : IServiceType, IDisposable
this.framework.Update += this.FrameworkOnUpdate;
}
+ private enum ProfileOp
+ {
+ Enable,
+ Disable,
+ Toggle,
+ }
+
///
public void Dispose()
{
@@ -166,11 +173,4 @@ internal class ProfileCommandHandler : IServiceType, IDisposable
return name;
}
-
- private enum ProfileOp
- {
- Enable,
- Disable,
- Toggle,
- }
}
diff --git a/Dalamud/Plugin/Internal/Profiles/ProfileManager.cs b/Dalamud/Plugin/Internal/Profiles/ProfileManager.cs
index b7073ac99..f7eac6d21 100644
--- a/Dalamud/Plugin/Internal/Profiles/ProfileManager.cs
+++ b/Dalamud/Plugin/Internal/Profiles/ProfileManager.cs
@@ -165,7 +165,7 @@ internal class ProfileManager : IServiceType
///
/// Go through all profiles and plugins, and enable/disable plugins they want active.
- /// This will block until all plugins have been loaded/reloaded!
+ /// This will block until all plugins have been loaded/reloaded.
///
public void ApplyAllWantStates()
{
diff --git a/Dalamud/Plugin/Internal/Profiles/ProfileModel.cs b/Dalamud/Plugin/Internal/Profiles/ProfileModel.cs
index 06075a07e..c73e80450 100644
--- a/Dalamud/Plugin/Internal/Profiles/ProfileModel.cs
+++ b/Dalamud/Plugin/Internal/Profiles/ProfileModel.cs
@@ -5,14 +5,29 @@ using Newtonsoft.Json;
namespace Dalamud.Plugin.Internal.Profiles;
+///
+/// Class representing a profile.
+///
public abstract class ProfileModel
{
+ ///
+ /// Gets or sets the ID of the profile.
+ ///
[JsonProperty("id")]
public Guid Guid { get; set; } = Guid.Empty;
+ ///
+ /// Gets or sets the name of the profile.
+ ///
[JsonProperty("n")]
public string Name { get; set; } = "New Profile";
+ ///
+ /// Deserialize a profile into a model.
+ ///
+ /// The string to decompress.
+ /// The parsed model.
+ /// Thrown when the parsed string is not a valid profile.
public static ProfileModel? Deserialize(string model)
{
var json = Util.DecompressString(Convert.FromBase64String(model.Substring(3)));
@@ -23,6 +38,11 @@ public abstract class ProfileModel
throw new ArgumentException("Was not a compressed style model.");
}
+ ///
+ /// Serialize this model into a string usable for sharing.
+ ///
+ /// The serialized representation of the model.
+ /// Thrown when an unsupported model is serialized.
public string Serialize()
{
string prefix;
diff --git a/Dalamud/Plugin/Internal/Profiles/ProfileModelV1.cs b/Dalamud/Plugin/Internal/Profiles/ProfileModelV1.cs
index cae585c30..2a851d234 100644
--- a/Dalamud/Plugin/Internal/Profiles/ProfileModelV1.cs
+++ b/Dalamud/Plugin/Internal/Profiles/ProfileModelV1.cs
@@ -1,27 +1,55 @@
using System.Collections.Generic;
+
using Newtonsoft.Json;
namespace Dalamud.Plugin.Internal.Profiles;
+///
+/// Version 1 of the profile model.
+///
public class ProfileModelV1 : ProfileModel
{
+ ///
+ /// Gets the prefix of this version.
+ ///
public static string SerializedPrefix => "DP1";
+ ///
+ /// Gets or sets a value indicating whether or not this profile should always be enabled at boot.
+ ///
[JsonProperty("b")]
public bool AlwaysEnableOnBoot { get; set; } = false;
+ ///
+ /// Gets or sets a value indicating whether or not this profile is currently enabled.
+ ///
[JsonProperty("e")]
public bool IsEnabled { get; set; } = false;
+ ///
+ /// Gets or sets a value indicating this profile's color.
+ ///
[JsonProperty("c")]
public uint Color { get; set; }
+ ///
+ /// Gets or sets the list of plugins in this profile.
+ ///
public List Plugins { get; set; } = new();
+ ///
+ /// Class representing a single plugin in a profile.
+ ///
public class ProfileModelV1Plugin
{
- public string InternalName { get; set; }
+ ///
+ /// Gets or sets the internal name of the plugin.
+ ///
+ public string? InternalName { get; set; }
+ ///
+ /// Gets or sets a value indicating whether or not this entry is enabled.
+ ///
public bool IsEnabled { get; set; }
}
}
diff --git a/Dalamud/Plugin/Internal/Profiles/ProfilePluginEntry.cs b/Dalamud/Plugin/Internal/Profiles/ProfilePluginEntry.cs
index 21856e572..0a6f5140b 100644
--- a/Dalamud/Plugin/Internal/Profiles/ProfilePluginEntry.cs
+++ b/Dalamud/Plugin/Internal/Profiles/ProfilePluginEntry.cs
@@ -1,14 +1,28 @@
namespace Dalamud.Plugin.Internal.Profiles;
+///
+/// Class representing a single plugin in a profile.
+///
internal class ProfilePluginEntry
{
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The internal name of the plugin.
+ /// A value indicating whether or not this entry is enabled.
public ProfilePluginEntry(string internalName, bool state)
{
this.InternalName = internalName;
this.IsEnabled = state;
}
+ ///
+ /// Gets the internal name of the plugin.
+ ///
public string InternalName { get; }
+ ///
+ /// Gets a value indicating whether or not this entry is enabled.
+ ///
public bool IsEnabled { get; }
}
diff --git a/Dalamud/Plugin/Internal/Types/LocalPlugin.cs b/Dalamud/Plugin/Internal/Types/LocalPlugin.cs
index 7811939b4..062fc94f1 100644
--- a/Dalamud/Plugin/Internal/Types/LocalPlugin.cs
+++ b/Dalamud/Plugin/Internal/Types/LocalPlugin.cs
@@ -136,7 +136,9 @@ internal class LocalPlugin : IDisposable
this.disabledFile = LocalPluginManifest.GetDisabledFile(this.DllFile);
if (this.disabledFile.Exists)
{
+#pragma warning disable CS0618
this.Manifest.Disabled = true;
+#pragma warning restore CS0618
this.disabledFile.Delete();
}
@@ -627,9 +629,9 @@ internal class LocalPlugin : IDisposable
var manifest = LocalPluginManifest.GetManifestFile(this.DllFile);
if (manifest.Exists)
{
- //var isDisabled = this.IsDisabled; // saving the internal state because it could have been deleted
+ // var isDisabled = this.IsDisabled; // saving the internal state because it could have been deleted
this.Manifest = LocalPluginManifest.Load(manifest);
- //this.Manifest.Disabled = isDisabled;
+ // this.Manifest.Disabled = isDisabled;
this.SaveManifest();
}