From 098607cca8e66b4155a6b7b5de58d439e65caa39 Mon Sep 17 00:00:00 2001 From: Infi Date: Wed, 13 Jul 2022 21:27:10 +0200 Subject: [PATCH 1/5] Give users the choice to not switch (#916) Co-authored-by: goat --- Dalamud/Interface/Internal/Windows/BranchSwitcherWindow.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Dalamud/Interface/Internal/Windows/BranchSwitcherWindow.cs b/Dalamud/Interface/Internal/Windows/BranchSwitcherWindow.cs index bdff07e3e..7f5f83bc0 100644 --- a/Dalamud/Interface/Internal/Windows/BranchSwitcherWindow.cs +++ b/Dalamud/Interface/Internal/Windows/BranchSwitcherWindow.cs @@ -31,8 +31,8 @@ public class BranchSwitcherWindow : Window public BranchSwitcherWindow() : base("Branch Switcher", ImGuiWindowFlags.AlwaysAutoResize) { - this.ShowCloseButton = false; - this.RespectCloseHotkey = false; + this.ShowCloseButton = true; + this.RespectCloseHotkey = true; } /// @@ -95,6 +95,7 @@ public class BranchSwitcherWindow : Window if (ImGui.Button("Pick")) { Pick(); + this.IsOpen = false; } ImGui.SameLine(); From 2c011b6bcd2eea6dd182f7c371bc520e2cbac1dc Mon Sep 17 00:00:00 2001 From: goat <16760685+goaaats@users.noreply.github.com> Date: Wed, 13 Jul 2022 21:29:01 +0200 Subject: [PATCH 2/5] feat: let users delete policy-blocked and orphaned plugins --- .../PluginInstaller/PluginInstallerWindow.cs | 53 ++++++++++++------- Dalamud/Plugin/Internal/PluginManager.cs | 4 +- Dalamud/Plugin/Internal/Types/LocalPlugin.cs | 7 +++ 3 files changed, 44 insertions(+), 20 deletions(-) diff --git a/Dalamud/Interface/Internal/Windows/PluginInstaller/PluginInstallerWindow.cs b/Dalamud/Interface/Internal/Windows/PluginInstaller/PluginInstallerWindow.cs index 4b0a30a10..16a682106 100644 --- a/Dalamud/Interface/Internal/Windows/PluginInstaller/PluginInstallerWindow.cs +++ b/Dalamud/Interface/Internal/Windows/PluginInstaller/PluginInstallerWindow.cs @@ -1724,7 +1724,6 @@ namespace Dalamud.Interface.Internal.Windows.PluginInstaller } else if (plugin.State == PluginState.Loaded || plugin.State == PluginState.LoadError || plugin.State == PluginState.DependencyResolutionFailed) { - // TODO: We should draw the trash can button for policy-blocked plugins in safe mode, so plugins can be deleted if (pluginManager.SafeMode) { ImGuiComponents.DisabledButton(Locs.PluginButton_SafeMode); @@ -1932,8 +1931,10 @@ namespace Dalamud.Interface.Internal.Windows.PluginInstaller private void DrawDeletePluginButton(LocalPlugin plugin) { - var unloaded = plugin.State == PluginState.Unloaded; - var showButton = unloaded && (plugin.IsDev || plugin.IsOutdated || plugin.IsBanned || plugin.IsOrphaned); + var unloaded = plugin.State == PluginState.Unloaded || plugin.State == PluginState.LoadError; + + // When policy check fails, the plugin is never loaded + var showButton = unloaded && (plugin.IsDev || plugin.IsOutdated || plugin.IsBanned || plugin.IsOrphaned || !plugin.CheckPolicy()); if (!showButton) return; @@ -1941,26 +1942,40 @@ namespace Dalamud.Interface.Internal.Windows.PluginInstaller var pluginManager = Service.Get(); ImGui.SameLine(); - if (ImGuiComponents.IconButton(FontAwesomeIcon.TrashAlt)) + if (plugin.HasEverStartedLoad) { - try - { - plugin.DllFile.Delete(); - pluginManager.RemovePlugin(plugin); - } - catch (Exception ex) - { - Log.Error(ex, $"Plugin installer threw an error during removal of {plugin.Name}"); + ImGui.PushFont(InterfaceManager.IconFont); + ImGuiComponents.DisabledButton(FontAwesomeIcon.TrashAlt.ToIconString()); + ImGui.PopFont(); - this.errorModalMessage = Locs.ErrorModal_DeleteFail(plugin.Name); - this.errorModalDrawing = true; - this.errorModalOnNextFrame = true; + if (ImGui.IsItemHovered()) + { + ImGui.SetTooltip(Locs.PluginButtonToolTip_DeletePluginRestricted); } } - - if (ImGui.IsItemHovered()) + else { - ImGui.SetTooltip(Locs.PluginButtonToolTip_DeletePlugin); + if (ImGuiComponents.IconButton(FontAwesomeIcon.TrashAlt)) + { + try + { + plugin.DllFile.Delete(); + pluginManager.RemovePlugin(plugin); + } + catch (Exception ex) + { + Log.Error(ex, $"Plugin installer threw an error during removal of {plugin.Name}"); + + this.errorModalMessage = Locs.ErrorModal_DeleteFail(plugin.Name); + this.errorModalDrawing = true; + this.errorModalOnNextFrame = true; + } + } + + if (ImGui.IsItemHovered()) + { + ImGui.SetTooltip(Locs.PluginButtonToolTip_DeletePlugin); + } } } @@ -2369,6 +2384,8 @@ namespace Dalamud.Interface.Internal.Windows.PluginInstaller public static string PluginButtonToolTip_DeletePlugin => Loc.Localize("InstallerDeletePlugin ", "Delete plugin"); + public static string PluginButtonToolTip_DeletePluginRestricted => Loc.Localize("InstallerDeletePluginRestricted", "Cannot delete - please try restarting the game."); + 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); diff --git a/Dalamud/Plugin/Internal/PluginManager.cs b/Dalamud/Plugin/Internal/PluginManager.cs index 29138b3ed..02c27f04b 100644 --- a/Dalamud/Plugin/Internal/PluginManager.cs +++ b/Dalamud/Plugin/Internal/PluginManager.cs @@ -771,8 +771,8 @@ internal partial class PluginManager : IDisposable, IServiceType /// Plugin to remove. public void RemovePlugin(LocalPlugin plugin) { - if (plugin.State != PluginState.Unloaded) - throw new InvalidPluginOperationException($"Unable to remove {plugin.Name}, not unloaded"); + if (plugin.State != PluginState.Unloaded && plugin.HasEverStartedLoad) + throw new InvalidPluginOperationException($"Unable to remove {plugin.Name}, not unloaded and had loaded before"); lock (this.pluginListLock) { diff --git a/Dalamud/Plugin/Internal/Types/LocalPlugin.cs b/Dalamud/Plugin/Internal/Types/LocalPlugin.cs index 32343feff..bb5b3d42d 100644 --- a/Dalamud/Plugin/Internal/Types/LocalPlugin.cs +++ b/Dalamud/Plugin/Internal/Types/LocalPlugin.cs @@ -189,6 +189,11 @@ internal class LocalPlugin : IDisposable /// public string BanReason { get; } + /// + /// Gets a value indicating whether the plugin has ever started to load. + /// + public bool HasEverStartedLoad { get; private set; } + /// /// Gets a value indicating whether the plugin is loaded and running. /// @@ -335,6 +340,8 @@ internal class LocalPlugin : IDisposable "Please refer to https://github.com/goatcorp/Dalamud/discussions/603 for more information."); } + this.HasEverStartedLoad = true; + this.loader ??= PluginLoader.CreateFromAssemblyFile(this.DllFile.FullName, SetupLoaderConfig); if (reloading || this.IsDev) From 138bf2552d5eb94209141b929ad87b2164c552ff Mon Sep 17 00:00:00 2001 From: goat <16760685+goaaats@users.noreply.github.com> Date: Wed, 13 Jul 2022 21:40:23 +0200 Subject: [PATCH 3/5] build: 6.4.0.35 --- Dalamud/Dalamud.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dalamud/Dalamud.csproj b/Dalamud/Dalamud.csproj index b61365905..013180b32 100644 --- a/Dalamud/Dalamud.csproj +++ b/Dalamud/Dalamud.csproj @@ -8,7 +8,7 @@ - 6.4.0.34 + 6.4.0.35 XIV Launcher addon framework $(DalamudVersion) $(DalamudVersion) From 3c0cfc693f764641f7b01e2d4582bb4a6c5a8b27 Mon Sep 17 00:00:00 2001 From: goat <16760685+goaaats@users.noreply.github.com> Date: Thu, 14 Jul 2022 18:56:19 +0200 Subject: [PATCH 4/5] chore: assert that bannedplugin serializes correctly --- Dalamud/Interface/Internal/DalamudInterface.cs | 2 +- Dalamud/Plugin/Internal/PluginManager.cs | 14 +++++++++++--- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/Dalamud/Interface/Internal/DalamudInterface.cs b/Dalamud/Interface/Internal/DalamudInterface.cs index b19176d12..28031c2a4 100644 --- a/Dalamud/Interface/Internal/DalamudInterface.cs +++ b/Dalamud/Interface/Internal/DalamudInterface.cs @@ -210,7 +210,7 @@ namespace Dalamud.Interface.Internal /// Opens the . /// /// The data kind to switch to after opening. - public void OpenDataWindow(string dataKind = null) + public void OpenDataWindow(string? dataKind = null) { this.dataWindow.IsOpen = true; if (dataKind != null && this.dataWindow.IsOpen) diff --git a/Dalamud/Plugin/Internal/PluginManager.cs b/Dalamud/Plugin/Internal/PluginManager.cs index 02c27f04b..c8a18cc3f 100644 --- a/Dalamud/Plugin/Internal/PluginManager.cs +++ b/Dalamud/Plugin/Internal/PluginManager.cs @@ -48,7 +48,7 @@ internal partial class PluginManager : IDisposable, IServiceType private readonly object pluginListLock = new(); private readonly DirectoryInfo pluginDirectory; private readonly DirectoryInfo devPluginDirectory; - private readonly BannedPlugin[] bannedPlugins; + private readonly BannedPlugin[]? bannedPlugins; [ServiceManager.ServiceDependency] private readonly DalamudConfiguration configuration = Service.Get(); @@ -78,7 +78,11 @@ internal partial class PluginManager : IDisposable, IServiceType this.PluginConfigs = new PluginConfigurations(Path.Combine(Path.GetDirectoryName(this.startInfo.ConfigurationPath) ?? string.Empty, "pluginConfigs")); var bannedPluginsJson = File.ReadAllText(Path.Combine(this.startInfo.AssetDirectory!, "UIRes", "bannedplugin.json")); - this.bannedPlugins = JsonConvert.DeserializeObject(bannedPluginsJson) ?? Array.Empty(); + this.bannedPlugins = JsonConvert.DeserializeObject(bannedPluginsJson); + if (this.bannedPlugins == null) + { + throw new InvalidDataException("Couldn't deserialize banned plugins manifest."); + } this.ApplyPatches(); } @@ -846,7 +850,7 @@ internal partial class PluginManager : IDisposable, IServiceType continue; } - if (manifest.DalamudApiLevel < DalamudApiLevel - 1 && !configuration.LoadAllApiLevels) + if (manifest.DalamudApiLevel < DalamudApiLevel - 1 && !this.configuration.LoadAllApiLevels) { Log.Information($"Lower API: cleaning up {versionDir.FullName}"); versionDir.Delete(true); @@ -1060,6 +1064,8 @@ internal partial class PluginManager : IDisposable, IServiceType /// A value indicating whether the plugin/manifest has been banned. public bool IsManifestBanned(PluginManifest manifest) { + Debug.Assert(this.bannedPlugins != null, "this.bannedPlugins != null"); + return !this.configuration.LoadBannedPlugins && this.bannedPlugins.Any(ban => (ban.Name == manifest.InternalName || ban.Name == Hash.GetStringSha256Hash(manifest.InternalName)) && ban.AssemblyVersion >= manifest.AssemblyVersion); } @@ -1071,6 +1077,8 @@ internal partial class PluginManager : IDisposable, IServiceType /// The reason of the ban, if any. public string GetBanReason(PluginManifest manifest) { + Debug.Assert(this.bannedPlugins != null, "this.bannedPlugins != null"); + return this.bannedPlugins.LastOrDefault(ban => ban.Name == manifest.InternalName).Reason; } From bc348cf1814d51e1b4ff3766ca558d39d04ed2a0 Mon Sep 17 00:00:00 2001 From: goat <16760685+goaaats@users.noreply.github.com> Date: Thu, 14 Jul 2022 18:56:51 +0200 Subject: [PATCH 5/5] build: 6.4.0.36 --- Dalamud/Dalamud.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dalamud/Dalamud.csproj b/Dalamud/Dalamud.csproj index 013180b32..1be87123b 100644 --- a/Dalamud/Dalamud.csproj +++ b/Dalamud/Dalamud.csproj @@ -8,7 +8,7 @@ - 6.4.0.35 + 6.4.0.36 XIV Launcher addon framework $(DalamudVersion) $(DalamudVersion)