From 18d75318d97bd18486f0132365aabc981386645f Mon Sep 17 00:00:00 2001 From: Robert Date: Thu, 14 Mar 2024 20:44:45 +0100 Subject: [PATCH] Workshop - Replace non-workshop plugins when installing them from the workshop --- .../Services/PluginManagementService.cs | 16 ++++++++++++++-- .../PluginEntryInstallationHandler.cs | 16 ++++++++++++---- 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/src/Artemis.Core/Services/PluginManagementService.cs b/src/Artemis.Core/Services/PluginManagementService.cs index dcc903404..11db7dc55 100644 --- a/src/Artemis.Core/Services/PluginManagementService.cs +++ b/src/Artemis.Core/Services/PluginManagementService.cs @@ -451,7 +451,7 @@ public void UnloadPlugins() // It is appropriate to call this now that we have the features of this plugin bool autoEnabled = plugin.AutoEnableIfNew(); - + if (autoEnabled || addedNewFeature) _pluginRepository.SavePlugin(entity); @@ -671,7 +671,19 @@ public void RemovePlugin(Plugin plugin, bool removeSettings) UnloadPlugin(plugin); } - directory.Delete(true); + // Delete plugin.json since that should never be in use and prevents future loads + File.Delete(Path.Combine(directory.FullName, "plugin.json")); + + try + { + // Give a good effort to remove the directory, files may be in use though :\ + directory.Delete(true); + } + catch (Exception e) + { + _logger.Warning(e, "Failed to fully remove plugin directory {Directory}", directory.FullName); + } + if (removeSettings) RemovePluginSettings(plugin); } diff --git a/src/Artemis.WebClient.Workshop/Handlers/InstallationHandlers/Implementations/PluginEntryInstallationHandler.cs b/src/Artemis.WebClient.Workshop/Handlers/InstallationHandlers/Implementations/PluginEntryInstallationHandler.cs index 34f0aac53..592b13037 100644 --- a/src/Artemis.WebClient.Workshop/Handlers/InstallationHandlers/Implementations/PluginEntryInstallationHandler.cs +++ b/src/Artemis.WebClient.Workshop/Handlers/InstallationHandlers/Implementations/PluginEntryInstallationHandler.cs @@ -63,11 +63,17 @@ public async Task InstallAsync(IEntryDetails entry, IRelease using ZipArchive archive = new(stream); archive.ExtractToDirectory(releaseDirectory.FullName); - // If there is already a version of the plugin installed, disable it - if (installedEntry.TryGetMetadata("PluginId", out Guid pluginId)) + PluginInfo pluginInfo = CoreJson.Deserialize(await File.ReadAllTextAsync(Path.Combine(releaseDirectory.FullName, "plugin.json"), cancellationToken))!; + + // If there is already a version of the plugin installed, remove it + Plugin? currentVersion = _pluginManagementService.GetAllPlugins().FirstOrDefault(p => p.Guid == pluginInfo.Guid); + if (currentVersion != null) { - Plugin? currentVersion = _pluginManagementService.GetAllPlugins().FirstOrDefault(p => p.Guid == pluginId); - if (currentVersion != null) + // If the current version isn't from the workshop, remove it first + if (currentVersion.Directory.FullName.StartsWith(Constants.PluginsFolder)) + _pluginManagementService.RemovePlugin(currentVersion, false); + // If the current version is from the workshop only unload it, the old folder will be orphaned and cleaned up later + else _pluginManagementService.UnloadPlugin(currentVersion); } @@ -96,6 +102,8 @@ public async Task InstallAsync(IEntryDetails entry, IRelease return EntryInstallResult.FromFailure(e.Message); } + installedEntry.ApplyRelease(release); + _workshopService.SaveInstalledEntry(installedEntry); return EntryInstallResult.FromSuccess(installedEntry); }