Fixed plugin deletion
This commit is contained in:
@@ -111,7 +111,7 @@ public class PluginLoader : IPluginLoader
|
|||||||
|
|
||||||
var files = installedPlugins.Where(plugin => plugin.IsEnabled).Select(plugin => plugin.FilePath);
|
var files = installedPlugins.Where(plugin => plugin.IsEnabled).Select(plugin => plugin.FilePath);
|
||||||
|
|
||||||
PluginLoaderContext = new PluginLoaderContext("PluginLoader");
|
PluginLoaderContext = new PluginLoaderContext(_Logger, "PluginLoader");
|
||||||
|
|
||||||
foreach (var file in files)
|
foreach (var file in files)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,15 +1,21 @@
|
|||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Runtime.Loader;
|
using System.Runtime.Loader;
|
||||||
|
using DiscordBotCore.Logging;
|
||||||
|
|
||||||
namespace DiscordBotCore.PluginManagement.Loading;
|
namespace DiscordBotCore.PluginManagement.Loading;
|
||||||
|
|
||||||
public class PluginLoaderContext : AssemblyLoadContext
|
public class PluginLoaderContext : AssemblyLoadContext
|
||||||
{
|
{
|
||||||
public PluginLoaderContext(string name) : base(name: name, isCollectible: true) {}
|
private readonly ILogger _logger;
|
||||||
|
|
||||||
|
public PluginLoaderContext(ILogger logger, string name) : base(name: name, isCollectible: true)
|
||||||
|
{
|
||||||
|
_logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
protected override Assembly? Load(AssemblyName assemblyName)
|
protected override Assembly? Load(AssemblyName assemblyName)
|
||||||
{
|
{
|
||||||
|
_logger.Log("Assembly load requested: " + assemblyName.Name, this);
|
||||||
return base.Load(assemblyName);
|
return base.Load(assemblyName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -136,7 +136,8 @@ public class PluginRepository : IPluginRepository
|
|||||||
List<OnlineDependencyInfo> dependencies = await JsonManager.ConvertFromJson<List<OnlineDependencyInfo>>(content);
|
List<OnlineDependencyInfo> dependencies = await JsonManager.ConvertFromJson<List<OnlineDependencyInfo>>(content);
|
||||||
|
|
||||||
return dependencies;
|
return dependencies;
|
||||||
}catch(HttpRequestException exception)
|
}
|
||||||
|
catch(HttpRequestException exception)
|
||||||
{
|
{
|
||||||
_logger.LogException(exception, this);
|
_logger.LogException(exception, this);
|
||||||
return [];
|
return [];
|
||||||
|
|||||||
@@ -10,11 +10,11 @@ public interface IPluginManager
|
|||||||
Task AppendPluginToDatabase(LocalPlugin pluginData);
|
Task AppendPluginToDatabase(LocalPlugin pluginData);
|
||||||
Task<List<LocalPlugin>> GetInstalledPlugins();
|
Task<List<LocalPlugin>> GetInstalledPlugins();
|
||||||
Task<bool> IsPluginInstalled(string pluginName);
|
Task<bool> IsPluginInstalled(string pluginName);
|
||||||
Task<bool> MarkPluginToUninstall(string pluginName);
|
|
||||||
Task UninstallMarkedPlugins();
|
|
||||||
Task<string?> GetDependencyLocation(string dependencyName);
|
Task<string?> GetDependencyLocation(string dependencyName);
|
||||||
Task<string?> GetDependencyLocation(string dependencyName, string pluginName);
|
Task<string?> GetDependencyLocation(string dependencyName, string pluginName);
|
||||||
string GenerateDependencyRelativePath(string pluginName, string dependencyPath);
|
string GenerateDependencyRelativePath(string pluginName, string dependencyPath);
|
||||||
Task InstallPlugin(OnlinePlugin plugin, IProgress<float> progress);
|
Task InstallPlugin(OnlinePlugin plugin, IProgress<float> progress);
|
||||||
Task SetEnabledStatus(string pluginName, bool status);
|
Task SetEnabledStatus(string pluginName, bool status);
|
||||||
|
Task<bool> UninstallPluginByName(string pluginName);
|
||||||
|
Task<LocalPlugin?> GetLocalPluginByName(string pluginName);
|
||||||
}
|
}
|
||||||
@@ -8,17 +8,15 @@ public class LocalPlugin
|
|||||||
public string PluginVersion { get; private set; }
|
public string PluginVersion { get; private set; }
|
||||||
public string FilePath { get; private set; }
|
public string FilePath { get; private set; }
|
||||||
public Dictionary<string, string> ListOfExecutableDependencies {get; private set;}
|
public Dictionary<string, string> ListOfExecutableDependencies {get; private set;}
|
||||||
public bool IsMarkedToUninstall {get; internal set;}
|
|
||||||
public bool IsOfflineAdded { get; internal set; }
|
public bool IsOfflineAdded { get; internal set; }
|
||||||
public bool IsEnabled { get; internal set; }
|
public bool IsEnabled { get; internal set; }
|
||||||
|
|
||||||
[JsonConstructor]
|
[JsonConstructor]
|
||||||
public LocalPlugin(string pluginName, string pluginVersion, string filePath, Dictionary<string, string> listOfExecutableDependencies, bool isMarkedToUninstall, bool isOfflineAdded, bool isEnabled)
|
public LocalPlugin(string pluginName, string pluginVersion, string filePath, Dictionary<string, string> listOfExecutableDependencies, bool isOfflineAdded, bool isEnabled)
|
||||||
{
|
{
|
||||||
PluginName = pluginName;
|
PluginName = pluginName;
|
||||||
PluginVersion = pluginVersion;
|
PluginVersion = pluginVersion;
|
||||||
ListOfExecutableDependencies = listOfExecutableDependencies;
|
ListOfExecutableDependencies = listOfExecutableDependencies;
|
||||||
IsMarkedToUninstall = isMarkedToUninstall;
|
|
||||||
FilePath = filePath;
|
FilePath = filePath;
|
||||||
IsOfflineAdded = isOfflineAdded;
|
IsOfflineAdded = isOfflineAdded;
|
||||||
IsEnabled = isEnabled;
|
IsEnabled = isEnabled;
|
||||||
@@ -30,7 +28,6 @@ public class LocalPlugin
|
|||||||
PluginName = pluginName;
|
PluginName = pluginName;
|
||||||
PluginVersion = pluginVersion;
|
PluginVersion = pluginVersion;
|
||||||
ListOfExecutableDependencies = listOfExecutableDependencies;
|
ListOfExecutableDependencies = listOfExecutableDependencies;
|
||||||
IsMarkedToUninstall = false;
|
|
||||||
FilePath = filePath;
|
FilePath = filePath;
|
||||||
IsOfflineAdded = false;
|
IsOfflineAdded = false;
|
||||||
IsEnabled = true;
|
IsEnabled = true;
|
||||||
|
|||||||
@@ -127,48 +127,6 @@ public sealed class PluginManager : IPluginManager
|
|||||||
return installedPlugins.Any(plugin => plugin.PluginName == pluginName);
|
return installedPlugins.Any(plugin => plugin.PluginName == pluginName);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<bool> MarkPluginToUninstall(string pluginName)
|
|
||||||
{
|
|
||||||
List<LocalPlugin> installedPlugins = await GetInstalledPlugins();
|
|
||||||
List<LocalPlugin> info = installedPlugins.Where(info => info.PluginName == pluginName).ToList();
|
|
||||||
|
|
||||||
if (!info.Any())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
foreach (var item in info)
|
|
||||||
{
|
|
||||||
await RemovePluginFromDatabase(item.PluginName);
|
|
||||||
item.IsMarkedToUninstall = true;
|
|
||||||
await AppendPluginToDatabase(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task UninstallMarkedPlugins()
|
|
||||||
{
|
|
||||||
IEnumerable<LocalPlugin> installedPlugins = (await GetInstalledPlugins()).AsEnumerable();
|
|
||||||
IEnumerable<LocalPlugin> pluginsToRemove = installedPlugins.Where(plugin => plugin.IsMarkedToUninstall).AsEnumerable();
|
|
||||||
|
|
||||||
foreach (var plugin in pluginsToRemove)
|
|
||||||
{
|
|
||||||
await UninstallPlugin(plugin);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task UninstallPlugin(LocalPlugin LocalPlugin)
|
|
||||||
{
|
|
||||||
File.Delete(LocalPlugin.FilePath);
|
|
||||||
|
|
||||||
foreach (var dependency in LocalPlugin.ListOfExecutableDependencies)
|
|
||||||
File.Delete(dependency.Value);
|
|
||||||
|
|
||||||
await RemovePluginFromDatabase(LocalPlugin.PluginName);
|
|
||||||
|
|
||||||
if (Directory.Exists($"{_LibrariesBaseFolder}/{LocalPlugin.PluginName}"))
|
|
||||||
Directory.Delete($"{_LibrariesBaseFolder}/{LocalPlugin.PluginName}", true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<string?> GetDependencyLocation(string dependencyName)
|
public async Task<string?> GetDependencyLocation(string dependencyName)
|
||||||
{
|
{
|
||||||
List<LocalPlugin> installedPlugins = await GetInstalledPlugins();
|
List<LocalPlugin> installedPlugins = await GetInstalledPlugins();
|
||||||
@@ -255,6 +213,45 @@ public sealed class PluginManager : IPluginManager
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<bool> UninstallPluginByName(string pluginName)
|
||||||
|
{
|
||||||
|
var localPlugin = await GetLocalPluginByName(pluginName);
|
||||||
|
if (localPlugin == null)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
File.Delete(localPlugin.FilePath);
|
||||||
|
|
||||||
|
if (Directory.Exists($"./{_LibrariesBaseFolder}/{pluginName}"))
|
||||||
|
{
|
||||||
|
foreach (var file in Directory.EnumerateFiles($"./{_LibrariesBaseFolder}/{pluginName}"))
|
||||||
|
{
|
||||||
|
File.Delete(file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await RemovePluginFromDatabase(pluginName);
|
||||||
|
|
||||||
|
_Logger.Log($"Plugin {pluginName} uninstalled successfully", this, LogType.Info);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<LocalPlugin?> GetLocalPluginByName(string pluginName)
|
||||||
|
{
|
||||||
|
List<LocalPlugin> installedPlugins = await GetInstalledPlugins();
|
||||||
|
var plugin = installedPlugins.Find(p => p.PluginName == pluginName);
|
||||||
|
|
||||||
|
if (plugin == null)
|
||||||
|
{
|
||||||
|
_Logger.Log($"Plugin {pluginName} not found in the database", this, LogType.Warning);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return plugin;
|
||||||
|
}
|
||||||
|
|
||||||
private async Task<bool> CreateEmptyPluginDatabase()
|
private async Task<bool> CreateEmptyPluginDatabase()
|
||||||
{
|
{
|
||||||
string ? pluginDatabaseFile = _Configuration.Get<string>("PluginDatabase");
|
string ? pluginDatabaseFile = _Configuration.Get<string>("PluginDatabase");
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
@using DiscordBotCore.Logging
|
@using DiscordBotCore.Logging
|
||||||
@using DiscordBotCore.PluginManagement
|
@using DiscordBotCore.PluginManagement
|
||||||
|
@using DiscordBotCore.PluginManagement.Loading
|
||||||
@using DiscordBotCore.PluginManagement.Models
|
@using DiscordBotCore.PluginManagement.Models
|
||||||
|
|
||||||
<h3>Installed Plugins</h3>
|
<h3>Installed Plugins</h3>
|
||||||
@@ -60,6 +61,9 @@
|
|||||||
|
|
||||||
[Inject]
|
[Inject]
|
||||||
public ILogger Logger { get; set; }
|
public ILogger Logger { get; set; }
|
||||||
|
|
||||||
|
[Inject]
|
||||||
|
public IPluginLoader PluginLoader { get; set; }
|
||||||
|
|
||||||
private readonly List<InstalledPlugin> _installedPlugins = new List<InstalledPlugin>();
|
private readonly List<InstalledPlugin> _installedPlugins = new List<InstalledPlugin>();
|
||||||
|
|
||||||
@@ -68,9 +72,14 @@
|
|||||||
|
|
||||||
private async Task DeletePluginButtonClick(string pluginName)
|
private async Task DeletePluginButtonClick(string pluginName)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
//TODO: Unload the plugin
|
||||||
|
|
||||||
|
PluginLoader.UnloadAllPlugins();
|
||||||
|
|
||||||
Logger.Log($"Deleting plugin {pluginName}", this);
|
Logger.Log($"Deleting plugin {pluginName}", this);
|
||||||
|
|
||||||
bool result = await PluginManager.MarkPluginToUninstall(pluginName);
|
bool result = await PluginManager.UninstallPluginByName(pluginName);
|
||||||
|
|
||||||
if (!result)
|
if (!result)
|
||||||
{
|
{
|
||||||
@@ -80,6 +89,9 @@
|
|||||||
|
|
||||||
_installedPlugins.RemoveAll(p => p.Name == pluginName);
|
_installedPlugins.RemoveAll(p => p.Name == pluginName);
|
||||||
Logger.Log($"Plugin {pluginName} deleted", this);
|
Logger.Log($"Plugin {pluginName} deleted", this);
|
||||||
|
|
||||||
|
await PluginLoader.LoadPlugins();
|
||||||
|
|
||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user