mirror of
https://github.com/goatcorp/Dalamud.git
synced 2025-12-13 12:14:16 +01:00
Rework plugin deletion + misc (#927)
* fix: stuck overlay on errors * feat: delete old plugin versions * feat: ignore error tag when outdated, banned, or orphaned * feat: rework plugin deletion
This commit is contained in:
parent
62831f8d1e
commit
1574ef7c33
4 changed files with 97 additions and 19 deletions
|
|
@ -1689,7 +1689,8 @@ namespace Dalamud.Interface.Internal.Windows.PluginInstaller
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load error
|
// Load error
|
||||||
if (plugin.State is PluginState.LoadError or PluginState.DependencyResolutionFailed && plugin.CheckPolicy())
|
if (plugin.State is PluginState.LoadError or PluginState.DependencyResolutionFailed && plugin.CheckPolicy()
|
||||||
|
&& !plugin.IsOutdated && !plugin.IsBanned && !plugin.IsOrphaned)
|
||||||
{
|
{
|
||||||
label += Locs.PluginTitleMod_LoadError;
|
label += Locs.PluginTitleMod_LoadError;
|
||||||
trouble = true;
|
trouble = true;
|
||||||
|
|
@ -1749,6 +1750,12 @@ namespace Dalamud.Interface.Internal.Windows.PluginInstaller
|
||||||
trouble = true;
|
trouble = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Scheduled for deletion
|
||||||
|
if (plugin.Manifest.ScheduledForDeletion)
|
||||||
|
{
|
||||||
|
label += Locs.PluginTitleMod_ScheduledForDeletion;
|
||||||
|
}
|
||||||
|
|
||||||
ImGui.PushID($"installed{index}{plugin.Manifest.InternalName}");
|
ImGui.PushID($"installed{index}{plugin.Manifest.InternalName}");
|
||||||
var hasChangelog = !plugin.Manifest.Changelog.IsNullOrEmpty();
|
var hasChangelog = !plugin.Manifest.Changelog.IsNullOrEmpty();
|
||||||
|
|
||||||
|
|
@ -1959,7 +1966,10 @@ namespace Dalamud.Interface.Internal.Windows.PluginInstaller
|
||||||
|
|
||||||
unloadTask.Wait();
|
unloadTask.Wait();
|
||||||
if (!unloadTask.Result)
|
if (!unloadTask.Result)
|
||||||
|
{
|
||||||
|
this.enableDisableStatus = OperationStatus.Complete;
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var disableTask = Task.Run(() => plugin.Disable())
|
var disableTask = Task.Run(() => plugin.Disable())
|
||||||
.ContinueWith(this.DisplayErrorContinuation, Locs.ErrorModal_DisableFail(plugin.Name));
|
.ContinueWith(this.DisplayErrorContinuation, Locs.ErrorModal_DisableFail(plugin.Name));
|
||||||
|
|
@ -1985,7 +1995,10 @@ namespace Dalamud.Interface.Internal.Windows.PluginInstaller
|
||||||
|
|
||||||
enableTask.Wait();
|
enableTask.Wait();
|
||||||
if (!enableTask.Result)
|
if (!enableTask.Result)
|
||||||
|
{
|
||||||
|
this.enableDisableStatus = OperationStatus.Complete;
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var loadTask = Task.Run(() => plugin.LoadAsync(PluginLoadReason.Installer))
|
var loadTask = Task.Run(() => plugin.LoadAsync(PluginLoadReason.Installer))
|
||||||
.ContinueWith(this.DisplayErrorContinuation, Locs.ErrorModal_LoadFail(plugin.Name));
|
.ContinueWith(this.DisplayErrorContinuation, Locs.ErrorModal_LoadFail(plugin.Name));
|
||||||
|
|
@ -2152,8 +2165,10 @@ namespace Dalamud.Interface.Internal.Windows.PluginInstaller
|
||||||
|
|
||||||
var pluginManager = Service<PluginManager>.Get();
|
var pluginManager = Service<PluginManager>.Get();
|
||||||
|
|
||||||
|
var devNotDeletable = plugin.IsDev && plugin.State != PluginState.Unloaded && plugin.State != PluginState.DependencyResolutionFailed;
|
||||||
|
|
||||||
ImGui.SameLine();
|
ImGui.SameLine();
|
||||||
if (plugin.State != PluginState.Unloaded && plugin.State != PluginState.LoadError)
|
if (plugin.State == PluginState.Loaded || devNotDeletable)
|
||||||
{
|
{
|
||||||
ImGui.PushFont(InterfaceManager.IconFont);
|
ImGui.PushFont(InterfaceManager.IconFont);
|
||||||
ImGuiComponents.DisabledButton(FontAwesomeIcon.TrashAlt.ToIconString());
|
ImGuiComponents.DisabledButton(FontAwesomeIcon.TrashAlt.ToIconString());
|
||||||
|
|
@ -2161,18 +2176,9 @@ namespace Dalamud.Interface.Internal.Windows.PluginInstaller
|
||||||
|
|
||||||
if (ImGui.IsItemHovered())
|
if (ImGui.IsItemHovered())
|
||||||
{
|
{
|
||||||
ImGui.SetTooltip(Locs.PluginButtonToolTip_DeletePluginLoaded);
|
ImGui.SetTooltip(plugin.State == PluginState.Loaded
|
||||||
}
|
? Locs.PluginButtonToolTip_DeletePluginLoaded
|
||||||
}
|
: Locs.PluginButtonToolTip_DeletePluginRestricted);
|
||||||
else if (plugin.HasEverStartedLoad && !plugin.IsDev)
|
|
||||||
{
|
|
||||||
ImGui.PushFont(InterfaceManager.IconFont);
|
|
||||||
ImGuiComponents.DisabledButton(FontAwesomeIcon.TrashAlt.ToIconString());
|
|
||||||
ImGui.PopFont();
|
|
||||||
|
|
||||||
if (ImGui.IsItemHovered())
|
|
||||||
{
|
|
||||||
ImGui.SetTooltip(Locs.PluginButtonToolTip_DeletePluginRestricted);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
@ -2181,8 +2187,19 @@ namespace Dalamud.Interface.Internal.Windows.PluginInstaller
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
plugin.DllFile.Delete();
|
if (plugin.IsDev)
|
||||||
pluginManager.RemovePlugin(plugin);
|
{
|
||||||
|
plugin.DllFile.Delete();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
plugin.ScheduleDeletion(!plugin.Manifest.ScheduledForDeletion);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (plugin.State is PluginState.Unloaded or PluginState.DependencyResolutionFailed)
|
||||||
|
{
|
||||||
|
pluginManager.RemovePlugin(plugin);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
|
@ -2194,7 +2211,21 @@ namespace Dalamud.Interface.Internal.Windows.PluginInstaller
|
||||||
|
|
||||||
if (ImGui.IsItemHovered())
|
if (ImGui.IsItemHovered())
|
||||||
{
|
{
|
||||||
ImGui.SetTooltip(Locs.PluginButtonToolTip_DeletePlugin);
|
string tooltipMessage;
|
||||||
|
if (plugin.Manifest.ScheduledForDeletion)
|
||||||
|
{
|
||||||
|
tooltipMessage = Locs.PluginButtonToolTip_DeletePluginScheduledCancel;
|
||||||
|
}
|
||||||
|
else if (plugin.State is PluginState.Unloaded or PluginState.DependencyResolutionFailed)
|
||||||
|
{
|
||||||
|
tooltipMessage = Locs.PluginButtonToolTip_DeletePlugin;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tooltipMessage = Locs.PluginButtonToolTip_DeletePluginScheduled;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui.SetTooltip(tooltipMessage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2530,9 +2561,11 @@ namespace Dalamud.Interface.Internal.Windows.PluginInstaller
|
||||||
public static string PluginTitleMod_OutdatedError => Loc.Localize("InstallerOutdatedError", " (outdated)");
|
public static string PluginTitleMod_OutdatedError => Loc.Localize("InstallerOutdatedError", " (outdated)");
|
||||||
|
|
||||||
public static string PluginTitleMod_BannedError => Loc.Localize("InstallerBannedError", " (automatically disabled)");
|
public static string PluginTitleMod_BannedError => Loc.Localize("InstallerBannedError", " (automatically disabled)");
|
||||||
|
|
||||||
public static string PluginTitleMod_OrphanedError => Loc.Localize("InstallerOrphanedError", " (unknown repository)");
|
public static string PluginTitleMod_OrphanedError => Loc.Localize("InstallerOrphanedError", " (unknown repository)");
|
||||||
|
|
||||||
|
public static string PluginTitleMod_ScheduledForDeletion => Loc.Localize("InstallerScheduledForDeletion", " (scheduled for deletion)");
|
||||||
|
|
||||||
public static string PluginTitleMod_New => Loc.Localize("InstallerNewPlugin ", " New!");
|
public static string PluginTitleMod_New => Loc.Localize("InstallerNewPlugin ", " New!");
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
@ -2608,6 +2641,10 @@ namespace Dalamud.Interface.Internal.Windows.PluginInstaller
|
||||||
|
|
||||||
public static string PluginButtonToolTip_DeletePluginRestricted => Loc.Localize("InstallerDeletePluginRestricted", "Cannot delete right now - please restart the game.");
|
public static string PluginButtonToolTip_DeletePluginRestricted => Loc.Localize("InstallerDeletePluginRestricted", "Cannot delete right now - please restart the game.");
|
||||||
|
|
||||||
|
public static string PluginButtonToolTip_DeletePluginScheduled => Loc.Localize("InstallerDeletePluginScheduled", "Delete plugin on next restart");
|
||||||
|
|
||||||
|
public static string PluginButtonToolTip_DeletePluginScheduledCancel => Loc.Localize("InstallerDeletePluginScheduledCancel", "Cancel scheduled deletion");
|
||||||
|
|
||||||
public static string PluginButtonToolTip_DeletePluginLoaded => Loc.Localize("InstallerDeletePluginLoaded", "Disable this plugin before deleting it.");
|
public static string PluginButtonToolTip_DeletePluginLoaded => Loc.Localize("InstallerDeletePluginLoaded", "Disable this plugin before deleting it.");
|
||||||
|
|
||||||
public static string PluginButtonToolTip_VisitPluginUrl => Loc.Localize("InstallerVisitPluginUrl", "Visit plugin URL");
|
public static string PluginButtonToolTip_VisitPluginUrl => Loc.Localize("InstallerVisitPluginUrl", "Visit plugin URL");
|
||||||
|
|
|
||||||
|
|
@ -848,10 +848,17 @@ internal partial class PluginManager : IDisposable, IServiceType
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
foreach (var versionDir in versionDirs)
|
for (var i = 0; i < versionDirs.Length; i++)
|
||||||
{
|
{
|
||||||
|
var versionDir = versionDirs[i];
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
if (i != 0)
|
||||||
|
{
|
||||||
|
Log.Information($"Old version: cleaning up {versionDir.FullName}");
|
||||||
|
versionDir.Delete(true);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
var dllFile = new FileInfo(Path.Combine(versionDir.FullName, $"{pluginDir.Name}.dll"));
|
var dllFile = new FileInfo(Path.Combine(versionDir.FullName, $"{pluginDir.Name}.dll"));
|
||||||
if (!dllFile.Exists)
|
if (!dllFile.Exists)
|
||||||
{
|
{
|
||||||
|
|
@ -865,6 +872,21 @@ internal partial class PluginManager : IDisposable, IServiceType
|
||||||
{
|
{
|
||||||
Log.Information($"Missing manifest: cleaning up {versionDir.FullName}");
|
Log.Information($"Missing manifest: cleaning up {versionDir.FullName}");
|
||||||
versionDir.Delete(true);
|
versionDir.Delete(true);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (manifestFile.Length == 0)
|
||||||
|
{
|
||||||
|
Log.Information($"Manifest empty: cleaning up {versionDir.FullName}");
|
||||||
|
versionDir.Delete(true);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var manifest = LocalPluginManifest.Load(manifestFile);
|
||||||
|
if (manifest.ScheduledForDeletion)
|
||||||
|
{
|
||||||
|
Log.Information($"Scheduled deletion: cleaning up {versionDir.FullName}");
|
||||||
|
versionDir.Delete(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
|
|
@ -902,6 +924,9 @@ internal partial class PluginManager : IDisposable, IServiceType
|
||||||
if (plugin.InstalledPlugin.Manifest.Disabled && ignoreDisabled)
|
if (plugin.InstalledPlugin.Manifest.Disabled && ignoreDisabled)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if (plugin.InstalledPlugin.Manifest.ScheduledForDeletion)
|
||||||
|
continue;
|
||||||
|
|
||||||
var result = await this.UpdateSinglePluginAsync(plugin, false, dryRun);
|
var result = await this.UpdateSinglePluginAsync(plugin, false, dryRun);
|
||||||
if (result != null)
|
if (result != null)
|
||||||
updatedList.Add(result);
|
updatedList.Add(result);
|
||||||
|
|
|
||||||
|
|
@ -560,6 +560,7 @@ internal class LocalPlugin : IDisposable
|
||||||
throw new InvalidPluginOperationException($"Unable to enable {this.Name}, not disabled");
|
throw new InvalidPluginOperationException($"Unable to enable {this.Name}, not disabled");
|
||||||
|
|
||||||
this.Manifest.Disabled = false;
|
this.Manifest.Disabled = false;
|
||||||
|
this.Manifest.ScheduledForDeletion = false;
|
||||||
this.SaveManifest();
|
this.SaveManifest();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -614,6 +615,16 @@ internal class LocalPlugin : IDisposable
|
||||||
this.SaveManifest();
|
this.SaveManifest();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Schedule the deletion of this plugin on next cleanup.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="status">Schedule or cancel the deletion.</param>
|
||||||
|
public void ScheduleDeletion(bool status = true)
|
||||||
|
{
|
||||||
|
this.Manifest.ScheduledForDeletion = status;
|
||||||
|
this.SaveManifest();
|
||||||
|
}
|
||||||
|
|
||||||
private static void SetupLoaderConfig(LoaderConfig config)
|
private static void SetupLoaderConfig(LoaderConfig config)
|
||||||
{
|
{
|
||||||
config.IsUnloadable = true;
|
config.IsUnloadable = true;
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,11 @@ internal record LocalPluginManifest : PluginManifest
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool Testing { get; set; }
|
public bool Testing { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets a value indicating whether the plugin should be deleted during the next cleanup.
|
||||||
|
/// </summary>
|
||||||
|
public bool ScheduledForDeletion { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the 3rd party repo URL that this plugin was installed from. Used to display where the plugin was
|
/// 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
|
/// sourced from on the installed plugin view. This should not be included in the plugin master. This value is null
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue