From f601cd4d825996e6bc1a55cb25397e99cc63343d Mon Sep 17 00:00:00 2001 From: goat <16760685+goaaats@users.noreply.github.com> Date: Thu, 15 Jul 2021 01:56:55 +0200 Subject: [PATCH 01/10] fix: keep ApiLevel - 1 plugins in folder --- Dalamud/Plugin/Internal/PluginManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dalamud/Plugin/Internal/PluginManager.cs b/Dalamud/Plugin/Internal/PluginManager.cs index 1eec895e5..9cf488dc6 100644 --- a/Dalamud/Plugin/Internal/PluginManager.cs +++ b/Dalamud/Plugin/Internal/PluginManager.cs @@ -558,7 +558,7 @@ namespace Dalamud.Plugin.Internal continue; } - if (manifest.DalamudApiLevel < DalamudApiLevel && !this.dalamud.Configuration.LoadAllApiLevels) + if (manifest.DalamudApiLevel < DalamudApiLevel - 1 && !this.dalamud.Configuration.LoadAllApiLevels) { Log.Information($"Lower API: cleaning up {versionDir.FullName}"); versionDir.Delete(true); From dd41c7714870ade4134c9c47dc4f8c701b9b08cf Mon Sep 17 00:00:00 2001 From: goat <16760685+goaaats@users.noreply.github.com> Date: Thu, 15 Jul 2021 03:07:18 +0200 Subject: [PATCH 02/10] fix warning in Troubleshooting.cs --- Dalamud/Troubleshooting.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dalamud/Troubleshooting.cs b/Dalamud/Troubleshooting.cs index 70b80cb5e..69b0df23e 100644 --- a/Dalamud/Troubleshooting.cs +++ b/Dalamud/Troubleshooting.cs @@ -52,7 +52,7 @@ namespace Dalamud public PluginManifest[] LoadedPlugins { get; set; } public string DalamudVersion { get; set; } - + public string DalamudGitHash { get; set; } public string GameVersion { get; set; } From 83edcc583f6d831a7a2e7cfd31af92d66f2a39c7 Mon Sep 17 00:00:00 2001 From: goat <16760685+goaaats@users.noreply.github.com> Date: Thu, 15 Jul 2021 03:08:02 +0200 Subject: [PATCH 03/10] feat: still show outdated plugins with a warning --- .../Internal/Windows/PluginInstallerWindow.cs | 20 +++++++++++++++++++ Dalamud/Plugin/Internal/PluginManager.cs | 4 ++++ 2 files changed, 24 insertions(+) diff --git a/Dalamud/Interface/Internal/Windows/PluginInstallerWindow.cs b/Dalamud/Interface/Internal/Windows/PluginInstallerWindow.cs index faf8e022f..6780ade6b 100644 --- a/Dalamud/Interface/Internal/Windows/PluginInstallerWindow.cs +++ b/Dalamud/Interface/Internal/Windows/PluginInstallerWindow.cs @@ -614,6 +614,12 @@ namespace Dalamud.Interface.Internal.Windows } } + // Outdated API level + if (plugin.Manifest.DalamudApiLevel < PluginManager.DalamudApiLevel) + { + label += Locs.PluginTitleMod_OutdatedError; + } + if (ImGui.CollapsingHeader($"{label}###Header{index}{plugin.Manifest.InternalName}")) { var manifest = plugin.Manifest; @@ -644,6 +650,13 @@ namespace Dalamud.Interface.Internal.Windows ImGui.TextWrapped(manifest.Description); } + if (plugin.Manifest.DalamudApiLevel < PluginManager.DalamudApiLevel) + { + ImGui.PushStyleColor(ImGuiCol.Text, ImGuiColors.DalamudRed); + ImGui.TextWrapped(Locs.PluginBody_Outdated); + ImGui.PopStyleColor(); + } + // Available commands (if loaded) if (plugin.IsLoaded) { @@ -681,6 +694,9 @@ namespace Dalamud.Interface.Internal.Windows // Disable everything if the updater is running or another plugin is operating var disabled = this.updateStatus == OperationStatus.InProgress || this.installStatus == OperationStatus.InProgress; + // Disable everything if the plugin is outdated + disabled = disabled || plugin.Manifest.DalamudApiLevel < PluginManager.DalamudApiLevel; + if (plugin.State == PluginState.InProgress) { ImGuiComponents.DisabledButton(Locs.PluginButton_Working); @@ -1062,6 +1078,8 @@ namespace Dalamud.Interface.Internal.Windows public static string PluginTitleMod_UnloadError => Loc.Localize("InstallerUnloadError", " (unload error)"); + public static string PluginTitleMod_OutdatedError => Loc.Localize("InstallerOutdatedError", " (outdated)"); + #endregion #region Plugin context menu @@ -1082,6 +1100,8 @@ namespace Dalamud.Interface.Internal.Windows public static string PluginBody_DeleteDevPlugin => Loc.Localize("InstallerDeleteDevPlugin ", " To delete this plugin, please remove it from the devPlugins folder."); + public static string PluginBody_Outdated => Loc.Localize("InstallerOutdatedPluginBody ", "This plugin is outdated and incompatible at the moment. Please wait for it to be updated by its author."); + #endregion #region Plugin buttons diff --git a/Dalamud/Plugin/Internal/PluginManager.cs b/Dalamud/Plugin/Internal/PluginManager.cs index 9cf488dc6..7a32e9eab 100644 --- a/Dalamud/Plugin/Internal/PluginManager.cs +++ b/Dalamud/Plugin/Internal/PluginManager.cs @@ -469,6 +469,10 @@ namespace Dalamud.Plugin.Internal { Log.Information(ex, $"Dev plugin failed to load, adding anyways: {dllFile.Name}"); } + else if (plugin.Manifest.DalamudApiLevel < DalamudApiLevel) + { + Log.Information(ex, $"Plugin was outdated, adding anyways: {dllFile.Name}"); + } else { PluginLocations.Remove(plugin.AssemblyName.FullName); From 12adc4099f7bb37e05365425871e305a64ef7291 Mon Sep 17 00:00:00 2001 From: goat <16760685+goaaats@users.noreply.github.com> Date: Thu, 15 Jul 2021 03:42:10 +0200 Subject: [PATCH 04/10] feat: move plugin update into separate function, add update button to applicable available plugin --- .../Internal/Windows/PluginInstallerWindow.cs | 21 ++- Dalamud/Plugin/Internal/PluginManager.cs | 137 +++++++++--------- 2 files changed, 92 insertions(+), 66 deletions(-) diff --git a/Dalamud/Interface/Internal/Windows/PluginInstallerWindow.cs b/Dalamud/Interface/Internal/Windows/PluginInstallerWindow.cs index 6780ade6b..dc9d80535 100644 --- a/Dalamud/Interface/Internal/Windows/PluginInstallerWindow.cs +++ b/Dalamud/Interface/Internal/Windows/PluginInstallerWindow.cs @@ -591,8 +591,9 @@ namespace Dalamud.Interface.Internal.Windows label += Locs.PluginTitleMod_UnloadError; } + var availablePluginUpdate = this.pluginListUpdatable.FirstOrDefault(up => up.InstalledPlugin == plugin); // Update available - if (this.pluginListUpdatable.FirstOrDefault(up => up.InstalledPlugin == plugin) != default) + if (availablePluginUpdate != default) { label += Locs.PluginTitleMod_HasUpdate; } @@ -676,6 +677,9 @@ namespace Dalamud.Interface.Internal.Windows this.DrawDevPluginButtons(plugin); this.DrawVisitRepoUrlButton(plugin.Manifest.RepoUrl); + if (availablePluginUpdate != default) + this.DrawUpdateSinglePluginButton(plugin, availablePluginUpdate); + ImGui.SameLine(); ImGui.TextColored(ImGuiColors.DalamudGrey3, $" v{plugin.Manifest.AssemblyVersion}"); @@ -776,6 +780,19 @@ namespace Dalamud.Interface.Internal.Windows } } + private void DrawUpdateSinglePluginButton(LocalPlugin plugin, AvailablePluginUpdate update) + { + ImGui.SameLine(); + + if (ImGuiComponents.IconButton(FontAwesomeIcon.Download)) + { + this.dalamud.PluginManager.UpdateSinglePlugin(update, false); + } + + if (ImGui.IsItemHovered()) + ImGui.SetTooltip(Locs.PluginButtonToolTip_UpdateSingle(update.UpdateManifest.AssemblyVersion.ToString())); + } + private void DrawOpenPluginSettingsButton(LocalPlugin plugin) { if (plugin.DalamudInterface?.UiBuilder?.HasConfigUi ?? false) @@ -1130,6 +1147,8 @@ namespace Dalamud.Interface.Internal.Windows public static string PluginButtonToolTip_VisitPluginUrl => Loc.Localize("InstallerVisitPluginUrl", "Visit plugin URL"); + public static string PluginButtonToolTip_UpdateSingle(string version) => Loc.Localize("InstallerUpdateSingle", "Update to {0}").Format(version); + #endregion #region Footer diff --git a/Dalamud/Plugin/Internal/PluginManager.cs b/Dalamud/Plugin/Internal/PluginManager.cs index 7a32e9eab..64dca30b8 100644 --- a/Dalamud/Plugin/Internal/PluginManager.cs +++ b/Dalamud/Plugin/Internal/PluginManager.cs @@ -17,6 +17,7 @@ using Dalamud.Game.Text; using Dalamud.Plugin.Internal.Exceptions; using Dalamud.Plugin.Internal.Types; using HarmonyLib; +using JetBrains.Annotations; using Newtonsoft.Json; namespace Dalamud.Plugin.Internal @@ -599,84 +600,90 @@ namespace Dalamud.Plugin.Internal { Log.Information("Starting plugin update"); - var listChanged = false; - var updatedList = new List(); // Prevent collection was modified errors for (var i = 0; i < this.updatablePlugins.Count; i++) { - var metadata = this.updatablePlugins[i]; - - var plugin = metadata.InstalledPlugin; - - // Can't update that! - if (plugin is LocalDevPlugin) - continue; - - var updateStatus = new PluginUpdateStatus() - { - InternalName = plugin.Manifest.InternalName, - Name = plugin.Manifest.Name, - Version = metadata.UseTesting - ? metadata.UpdateManifest.TestingAssemblyVersion - : metadata.UpdateManifest.AssemblyVersion, - }; - - if (dryRun) - { - updateStatus.WasUpdated = true; - updatedList.Add(updateStatus); - } - else - { - // Unload if loaded - if (plugin.State == PluginState.Loaded || plugin.State == PluginState.LoadError) - { - try - { - plugin.Unload(); - } - catch (Exception ex) - { - Log.Error(ex, "Error during unload (update)"); - continue; - } - } - - try - { - plugin.Disable(); - this.installedPlugins.Remove(plugin); - listChanged = true; - } - catch (Exception ex) - { - Log.Error(ex, "Error during disable (update)"); - continue; - } - - try - { - this.InstallPlugin(metadata.UpdateManifest, metadata.UseTesting, PluginLoadReason.Update); - listChanged = true; - } - catch (Exception ex) - { - Log.Error(ex, "Error during install (update)"); - continue; - } - } + updatedList.Add(this.UpdateSinglePlugin(this.updatablePlugins[i], dryRun)); } - if (listChanged) - this.NotifyInstalledPluginsChanged(); + this.NotifyInstalledPluginsChanged(); Log.Information("Plugin update OK."); return updatedList; } + /// + /// Update a single plugin, provided a valid . + /// + /// The available plugin update. + /// Whether or not to actually perform the update, or just indicate success. + /// The status of the update. + [CanBeNull] + public PluginUpdateStatus UpdateSinglePlugin(AvailablePluginUpdate metadata, bool dryRun) + { + var plugin = metadata.InstalledPlugin; + + // Can't update that! + if (plugin is LocalDevPlugin) + return null; + + var updateStatus = new PluginUpdateStatus + { + InternalName = plugin.Manifest.InternalName, + Name = plugin.Manifest.Name, + Version = metadata.UseTesting ? metadata.UpdateManifest.TestingAssemblyVersion : metadata.UpdateManifest.AssemblyVersion + }; + + if (dryRun) + { + updateStatus.WasUpdated = true; + } + else + { + updateStatus.WasUpdated = true; + + // Unload if loaded + if (plugin.State == PluginState.Loaded || plugin.State == PluginState.LoadError) + { + try + { + plugin.Unload(); + } + catch (Exception ex) + { + Log.Error(ex, "Error during unload (update)"); + updateStatus.WasUpdated = false; + } + } + + try + { + plugin.Disable(); + this.installedPlugins.Remove(plugin); + } + catch (Exception ex) + { + Log.Error(ex, "Error during disable (update)"); + updateStatus.WasUpdated = false; + } + + try + { + this.InstallPlugin(metadata.UpdateManifest, metadata.UseTesting, PluginLoadReason.Update); + } + catch (Exception ex) + { + Log.Error(ex, "Error during install (update)"); + updateStatus.WasUpdated = false; + } + } + + return updateStatus; + } + /// /// Print to chat any plugin updates and whether they were successful. /// From ec8897dcb166e118b087b1be64a43f360709243c Mon Sep 17 00:00:00 2001 From: goat <16760685+goaaats@users.noreply.github.com> Date: Thu, 15 Jul 2021 03:43:58 +0200 Subject: [PATCH 05/10] fix: do not disable controls if outdated and LoadAllApiLevels --- Dalamud/Interface/Internal/Windows/PluginInstallerWindow.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dalamud/Interface/Internal/Windows/PluginInstallerWindow.cs b/Dalamud/Interface/Internal/Windows/PluginInstallerWindow.cs index dc9d80535..ee497f4c8 100644 --- a/Dalamud/Interface/Internal/Windows/PluginInstallerWindow.cs +++ b/Dalamud/Interface/Internal/Windows/PluginInstallerWindow.cs @@ -699,7 +699,7 @@ namespace Dalamud.Interface.Internal.Windows var disabled = this.updateStatus == OperationStatus.InProgress || this.installStatus == OperationStatus.InProgress; // Disable everything if the plugin is outdated - disabled = disabled || plugin.Manifest.DalamudApiLevel < PluginManager.DalamudApiLevel; + disabled = disabled || (plugin.Manifest.DalamudApiLevel < PluginManager.DalamudApiLevel && !this.dalamud.Configuration.LoadAllApiLevels); if (plugin.State == PluginState.InProgress) { From 6ec657266b8e7a61b45cf2140cdf73c4732a7c97 Mon Sep 17 00:00:00 2001 From: goat <16760685+goaaats@users.noreply.github.com> Date: Thu, 15 Jul 2021 03:47:28 +0200 Subject: [PATCH 06/10] fix: NotifyAvailablePluginsChanged when plugin is removed --- Dalamud/Plugin/Internal/PluginManager.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/Dalamud/Plugin/Internal/PluginManager.cs b/Dalamud/Plugin/Internal/PluginManager.cs index 64dca30b8..8ce079814 100644 --- a/Dalamud/Plugin/Internal/PluginManager.cs +++ b/Dalamud/Plugin/Internal/PluginManager.cs @@ -497,6 +497,7 @@ namespace Dalamud.Plugin.Internal this.installedPlugins.Remove(plugin); PluginLocations.Remove(plugin.AssemblyName.FullName); + this.NotifyAvailablePluginsChanged(); this.NotifyInstalledPluginsChanged(); } From 386251f232c55b47ee1be1867e0efc1149ff8177 Mon Sep 17 00:00:00 2001 From: goat <16760685+goaaats@users.noreply.github.com> Date: Thu, 15 Jul 2021 03:50:13 +0200 Subject: [PATCH 07/10] fix: remove duplicate exception log --- Dalamud/Plugin/Internal/PluginManager.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Dalamud/Plugin/Internal/PluginManager.cs b/Dalamud/Plugin/Internal/PluginManager.cs index 8ce079814..4a70a0a25 100644 --- a/Dalamud/Plugin/Internal/PluginManager.cs +++ b/Dalamud/Plugin/Internal/PluginManager.cs @@ -199,9 +199,9 @@ namespace Dalamud.Plugin.Internal { // Not a plugin } - catch (Exception ex) + catch (Exception) { - Log.Error(ex, "During boot plugin load, an unexpected error occurred"); + Log.Error("During boot plugin load, an unexpected error occurred"); } } } From 112833be8b2245b608dffbf88c2ffeef50abad97 Mon Sep 17 00:00:00 2001 From: goat <16760685+goaaats@users.noreply.github.com> Date: Thu, 15 Jul 2021 03:53:17 +0200 Subject: [PATCH 08/10] fix(PluginInstallerWindow): duplicate ImGui id with 3rd plugins install button --- Dalamud/Interface/Internal/Windows/PluginInstallerWindow.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Dalamud/Interface/Internal/Windows/PluginInstallerWindow.cs b/Dalamud/Interface/Internal/Windows/PluginInstallerWindow.cs index ee497f4c8..ecc2e8dee 100644 --- a/Dalamud/Interface/Internal/Windows/PluginInstallerWindow.cs +++ b/Dalamud/Interface/Internal/Windows/PluginInstallerWindow.cs @@ -523,7 +523,8 @@ namespace Dalamud.Interface.Internal.Windows } else { - if (ImGui.Button(Locs.PluginButton_InstallVersion(versionString))) + var buttonText = Locs.PluginButton_InstallVersion(versionString); + if (ImGui.Button($"{buttonText}##{buttonText}{index}")) { this.installStatus = OperationStatus.InProgress; From 0cb0bff7144628fdc2490ba8e9bd23e03a3b2213 Mon Sep 17 00:00:00 2001 From: goat <16760685+goaaats@users.noreply.github.com> Date: Thu, 15 Jul 2021 04:01:26 +0200 Subject: [PATCH 09/10] fix(PluginInstallerWindow): use task for single update, correct error handling --- .../Internal/Windows/PluginInstallerWindow.cs | 35 +++++++++++++++---- Dalamud/Plugin/Internal/PluginManager.cs | 2 +- 2 files changed, 30 insertions(+), 7 deletions(-) diff --git a/Dalamud/Interface/Internal/Windows/PluginInstallerWindow.cs b/Dalamud/Interface/Internal/Windows/PluginInstallerWindow.cs index ecc2e8dee..7908c7004 100644 --- a/Dalamud/Interface/Internal/Windows/PluginInstallerWindow.cs +++ b/Dalamud/Interface/Internal/Windows/PluginInstallerWindow.cs @@ -787,7 +787,22 @@ namespace Dalamud.Interface.Internal.Windows if (ImGuiComponents.IconButton(FontAwesomeIcon.Download)) { - this.dalamud.PluginManager.UpdateSinglePlugin(update, false); + this.installStatus = OperationStatus.InProgress; + + Task.Run(() => this.dalamud.PluginManager.UpdateSinglePlugin(update, false)) + .ContinueWith(task => + { + // There is no need to set as Complete for an individual plugin installation + this.installStatus = OperationStatus.Idle; + + var errorMessage = Locs.ErrorModal_SingleUpdateFail(update.UpdateManifest.Name); + this.DisplayErrorContinuation(task, errorMessage); + + if (!task.Result.WasUpdated) + { + ShowErrorModal(errorMessage); + } + }); } if (ImGui.IsItemHovered()) @@ -986,7 +1001,7 @@ namespace Dalamud.Interface.Internal.Windows { if (task.IsFaulted) { - this.errorModalMessage = state as string; + var errorModalMessage = state as string; foreach (var ex in task.Exception.InnerExceptions) { @@ -995,7 +1010,7 @@ namespace Dalamud.Interface.Internal.Windows Log.Error(ex, "Plugin installer threw an error"); #if DEBUG if (!string.IsNullOrEmpty(ex.Message)) - this.errorModalMessage += $"\n\n{ex.Message}"; + errorModalMessage += $"\n\n{ex.Message}"; #endif } else @@ -1003,13 +1018,12 @@ namespace Dalamud.Interface.Internal.Windows Log.Error(ex, "Plugin installer threw an unexpected error"); #if DEBUG if (!string.IsNullOrEmpty(ex.Message)) - this.errorModalMessage += $"\n\n{ex.Message}"; + errorModalMessage += $"\n\n{ex.Message}"; #endif } } - this.errorModalDrawing = true; - this.errorModalOnNextFrame = true; + this.ShowErrorModal(errorModalMessage); return false; } @@ -1017,6 +1031,13 @@ namespace Dalamud.Interface.Internal.Windows return true; } + private void ShowErrorModal(string message) + { + this.errorModalMessage = message; + this.errorModalDrawing = true; + this.errorModalOnNextFrame = true; + } + [SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1201:Elements should appear in the correct order", Justification = "Disregard here")] private static class Locs { @@ -1176,6 +1197,8 @@ namespace Dalamud.Interface.Internal.Windows public static string ErrorModal_InstallFail(string name) => Loc.Localize("InstallerInstallFail", "Failed to install plugin {0}.").Format(name); + public static string ErrorModal_SingleUpdateFail(string name) => Loc.Localize("InstallerSingleUpdateFail", "Failed to update plugin {0}.").Format(name); + public static string ErrorModal_EnableFail(string name) => Loc.Localize("InstallerEnableFail", "Failed to enable plugin {0}.").Format(name); public static string ErrorModal_DisableFail(string name) => Loc.Localize("InstallerDisableFail", "Failed to disable plugin {0}.").Format(name); diff --git a/Dalamud/Plugin/Internal/PluginManager.cs b/Dalamud/Plugin/Internal/PluginManager.cs index 4a70a0a25..c20deb177 100644 --- a/Dalamud/Plugin/Internal/PluginManager.cs +++ b/Dalamud/Plugin/Internal/PluginManager.cs @@ -635,7 +635,7 @@ namespace Dalamud.Plugin.Internal { InternalName = plugin.Manifest.InternalName, Name = plugin.Manifest.Name, - Version = metadata.UseTesting ? metadata.UpdateManifest.TestingAssemblyVersion : metadata.UpdateManifest.AssemblyVersion + Version = metadata.UseTesting ? metadata.UpdateManifest.TestingAssemblyVersion : metadata.UpdateManifest.AssemblyVersion, }; if (dryRun) From ba27dbe783bd4324773205efe301660fb7b90e3b Mon Sep 17 00:00:00 2001 From: goat <16760685+goaaats@users.noreply.github.com> Date: Thu, 15 Jul 2021 04:18:17 +0200 Subject: [PATCH 10/10] fix(PluginManager): return if any step of plugin update failed --- Dalamud/Plugin/Internal/PluginManager.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Dalamud/Plugin/Internal/PluginManager.cs b/Dalamud/Plugin/Internal/PluginManager.cs index c20deb177..83fd13c46 100644 --- a/Dalamud/Plugin/Internal/PluginManager.cs +++ b/Dalamud/Plugin/Internal/PluginManager.cs @@ -657,6 +657,7 @@ namespace Dalamud.Plugin.Internal { Log.Error(ex, "Error during unload (update)"); updateStatus.WasUpdated = false; + return updateStatus; } } @@ -669,6 +670,7 @@ namespace Dalamud.Plugin.Internal { Log.Error(ex, "Error during disable (update)"); updateStatus.WasUpdated = false; + return updateStatus; } try @@ -679,6 +681,7 @@ namespace Dalamud.Plugin.Internal { Log.Error(ex, "Error during install (update)"); updateStatus.WasUpdated = false; + return updateStatus; } }