From a2179787b9bab0d660c8430230a02e58b40f581f Mon Sep 17 00:00:00 2001 From: Andrei Tudor Date: Tue, 27 Feb 2024 19:42:59 +0200 Subject: [PATCH] Plugin Updater --- DiscordBot/Bot/Actions/Extra/PluginMethods.cs | 9 +-- DiscordBot/Bot/Actions/Plugin.cs | 12 +--- PluginManager/Config.cs | 17 +++++- PluginManager/Loaders/Loader.cs | 2 +- PluginManager/Loaders/PluginLoader.cs | 4 +- PluginManager/Online/PluginsManager.cs | 39 +++++++++++++ PluginManager/Plugin/PluginInfo.cs | 9 +-- PluginManager/PluginManager.csproj | 3 + .../Updater/Plugins/PluginUpdater.cs | 56 +++++++++++++++++++ 9 files changed, 127 insertions(+), 24 deletions(-) create mode 100644 PluginManager/Updater/Plugins/PluginUpdater.cs diff --git a/DiscordBot/Bot/Actions/Extra/PluginMethods.cs b/DiscordBot/Bot/Actions/Extra/PluginMethods.cs index 67d16b3..fbf6ad2 100644 --- a/DiscordBot/Bot/Actions/Extra/PluginMethods.cs +++ b/DiscordBot/Bot/Actions/Extra/PluginMethods.cs @@ -1,8 +1,5 @@ using System; using System.Collections.Generic; -using System.IO; -using System.Runtime.CompilerServices; -using System.Threading; using System.Threading.Tasks; using DiscordBot.Utilities; using PluginManager; @@ -10,7 +7,6 @@ using PluginManager.Interfaces; using PluginManager.Loaders; using PluginManager.Online; using PluginManager.Others; -using PluginManager.Plugin; using Spectre.Console; namespace DiscordBot.Bot.Actions.Extra; @@ -75,6 +71,7 @@ internal static class PluginMethods if (!pluginData.HasDependencies) { + await manager.AppendPluginToDatabase(pluginName, pluginData.Version); Console.WriteLine("Finished installing " + pluginName + " successfully"); await RefreshPlugins(false); return; @@ -129,7 +126,7 @@ internal static class PluginMethods } ); - + await manager.AppendPluginToDatabase(pluginName, pluginData.Version); await RefreshPlugins(false); } @@ -197,7 +194,7 @@ internal static class PluginMethods Console.ForegroundColor = cc; }; - await loader.LoadPlugins(); + await loader. LoadPlugins(); Console.ForegroundColor = cc; return true; } diff --git a/DiscordBot/Bot/Actions/Plugin.cs b/DiscordBot/Bot/Actions/Plugin.cs index fc3a304..59ffc8b 100644 --- a/DiscordBot/Bot/Actions/Plugin.cs +++ b/DiscordBot/Bot/Actions/Plugin.cs @@ -34,14 +34,6 @@ public class Plugin: ICommandAction return; } - var manager = -#if !DEBUG - new PluginsManager("releases"); -#else - // new PluginsManager("tests"); - new PluginsManager("releases"); -#endif - switch (args[0]) { case "refresh": @@ -49,7 +41,7 @@ public class Plugin: ICommandAction break; case "list": - await PluginMethods.List(manager); + await PluginMethods.List(Config.PluginsManager); break; case "load": if (pluginsLoaded) @@ -81,7 +73,7 @@ public class Plugin: ICommandAction } } - await PluginMethods.DownloadPlugin(manager, pluginName); + await PluginMethods.DownloadPlugin(Config.PluginsManager, pluginName); break; } } diff --git a/PluginManager/Config.cs b/PluginManager/Config.cs index 8ebafa3..722f83e 100644 --- a/PluginManager/Config.cs +++ b/PluginManager/Config.cs @@ -1,9 +1,12 @@ using System; +using System.Collections.Generic; using System.IO; using System.Threading.Tasks; using PluginManager.Bot; +using PluginManager.Online; using PluginManager.Others; using PluginManager.Others.Logger; +using PluginManager.Plugin; using OperatingSystem = System.OperatingSystem; namespace PluginManager; @@ -14,6 +17,8 @@ public class Config public static Logger Logger; public static SettingsDictionary AppSettings; + public static PluginsManager PluginsManager; + internal static Boot? DiscordBotClient; public static Boot? DiscordBot => DiscordBotClient; @@ -32,6 +37,14 @@ public class Config AppSettings["LogFolder"] = "./Data/Logs"; AppSettings["PluginFolder"] = "./Data/Plugins"; AppSettings["ArchiveFolder"] = "./Data/Archives"; + + AppSettings["PluginDatabase"] = "./Data/Resources/plugins.json"; + + if (!File.Exists(AppSettings["PluginDatabase"])) + { + List plugins = new(); + await JsonManager.SaveToJsonFile(AppSettings["PluginDatabase"], plugins); + } if (OperatingSystem.IsLinux()) { @@ -54,10 +67,12 @@ public class Config UX.UxHandler.Init(); _isLoaded = true; + PluginsManager = new PluginsManager("releases"); + + await PluginsManager.CheckForUpdates(); Logger.Log("Config initialized", typeof(Config)); - } } diff --git a/PluginManager/Loaders/Loader.cs b/PluginManager/Loaders/Loader.cs index ef9bc80..c6ee02d 100644 --- a/PluginManager/Loaders/Loader.cs +++ b/PluginManager/Loaders/Loader.cs @@ -43,7 +43,7 @@ internal class Loader } catch { - OnFileLoadedException?.Invoke(new FileLoaderResult(file, "Failed to load file")); + OnFileLoadedException?.Invoke(new FileLoaderResult(file, $"Failed to load file {file}")); } } diff --git a/PluginManager/Loaders/PluginLoader.cs b/PluginManager/Loaders/PluginLoader.cs index f82e375..2e0a0e1 100644 --- a/PluginManager/Loaders/PluginLoader.cs +++ b/PluginManager/Loaders/PluginLoader.cs @@ -3,6 +3,7 @@ using System.Threading.Tasks; using Discord.WebSocket; using PluginManager.Interfaces; using PluginManager.Others; +using PluginManager.Updater.Plugins; namespace PluginManager.Loaders; @@ -31,13 +32,12 @@ public class PluginLoader public async Task LoadPlugins() { - Commands = new List(); Events = new List(); SlashCommands = new List(); Config.Logger.Log("Loading plugins...", typeof(PluginLoader)); - + var loader = new Loader(Config.AppSettings["PluginFolder"], "dll"); loader.OnFileLoadedException += FileLoadedException; diff --git a/PluginManager/Online/PluginsManager.cs b/PluginManager/Online/PluginsManager.cs index b99f787..e531e77 100644 --- a/PluginManager/Online/PluginsManager.cs +++ b/PluginManager/Online/PluginsManager.cs @@ -1,9 +1,11 @@ using System; using System.Collections.Generic; +using System.IO; using System.Threading.Tasks; using PluginManager.Online.Helpers; using PluginManager.Others; using PluginManager.Plugin; +using PluginManager.Updater.Plugins; namespace PluginManager.Online; @@ -57,6 +59,43 @@ public class PluginsManager return result; } + + public async Task RemovePluginFromDatabase(string pluginName) + { + List installedPlugins = await JsonManager.ConvertFromJson>(await File.ReadAllTextAsync(Config.AppSettings["PluginDatabase"])); + + installedPlugins.RemoveAll(p => p.PluginName == pluginName); + await JsonManager.SaveToJsonFile( Config.AppSettings["PluginDatabase"],installedPlugins); + } + public async Task AppendPluginToDatabase(string pluginName, PluginVersion version) + { + List installedPlugins = await JsonManager.ConvertFromJson>(await File.ReadAllTextAsync(Config.AppSettings["PluginDatabase"])); + + installedPlugins.Add(new PluginInfo(pluginName, version)); + await JsonManager.SaveToJsonFile( Config.AppSettings["PluginDatabase"],installedPlugins); + } + + public async Task> GetInstalledPlugins() + { + return await JsonManager.ConvertFromJson>(await File.ReadAllTextAsync(Config.AppSettings["PluginDatabase"])); + } + + public async Task CheckForUpdates() + { + var pluginUpdater = new PluginUpdater(this); + + List installedPlugins = await GetInstalledPlugins(); + + foreach (var plugin in installedPlugins) + { + if (await pluginUpdater.HasUpdate(plugin.PluginName)) + { + Console.WriteLine($"Updating {plugin.PluginName}..."); + await pluginUpdater.UpdatePlugin(plugin.PluginName); + } + } + } + } diff --git a/PluginManager/Plugin/PluginInfo.cs b/PluginManager/Plugin/PluginInfo.cs index b2221dc..4280e3a 100644 --- a/PluginManager/Plugin/PluginInfo.cs +++ b/PluginManager/Plugin/PluginInfo.cs @@ -1,20 +1,21 @@ using System.IO; using PluginManager.Interfaces.Updater; +using PluginManager.Online.Helpers; namespace PluginManager.Plugin; public class PluginInfo { public string PluginName { get; private set; } - public IVersion PluginVersion { get; private set; } - public FileInfo FileData { get; private set; } + public PluginVersion PluginVersion { get; private set; } + public string FilePath { get; private set; } - public PluginInfo(string pluginName, IVersion pluginVersion) + public PluginInfo(string pluginName, PluginVersion pluginVersion) { PluginName = pluginName; PluginVersion = pluginVersion; - FileData = new FileInfo($"{Config.AppSettings["PluginFolder"]}/{pluginName}.dll"); + FilePath = $"{Config.AppSettings["PluginFolder"]}/{pluginName}.dll"; } public static PluginInfo FromOnlineInfo(PluginOnlineInfo onlineInfo) diff --git a/PluginManager/PluginManager.csproj b/PluginManager/PluginManager.csproj index 10780fb..12af348 100644 --- a/PluginManager/PluginManager.csproj +++ b/PluginManager/PluginManager.csproj @@ -25,4 +25,7 @@ ..\..\..\.nuget\packages\spectre.console\0.47.0\lib\net7.0\Spectre.Console.dll + + + \ No newline at end of file diff --git a/PluginManager/Updater/Plugins/PluginUpdater.cs b/PluginManager/Updater/Plugins/PluginUpdater.cs new file mode 100644 index 0000000..5b23c02 --- /dev/null +++ b/PluginManager/Updater/Plugins/PluginUpdater.cs @@ -0,0 +1,56 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Threading.Tasks; +using PluginManager.Online; +using PluginManager.Plugin; + +namespace PluginManager.Updater.Plugins; + +public class PluginUpdater +{ + private readonly PluginsManager _PluginManager; + + public PluginUpdater(PluginsManager pluginManager) + { + _PluginManager = pluginManager; + } + + public async Task GetPluginInfo(string pluginName) + { + var result = await _PluginManager.GetPluginDataByName(pluginName); + return result; + } + + public async Task GetLocalPluginInfo(string pluginName) + { + string pluginsDatabase = File.ReadAllText(Config.AppSettings["PluginDatabase"]); + List installedPlugins = await JsonManager.ConvertFromJson>(pluginsDatabase); + + var result = installedPlugins.Find(p => p.PluginName == pluginName); + + return result; + } + + public async Task UpdatePlugin(string pluginName, IProgress? progressMeter = null) + { + PluginOnlineInfo pluginInfo = await GetPluginInfo(pluginName); + await ServerCom.DownloadFileAsync(pluginInfo.DownLoadLink, $"{Config.AppSettings["PluginFolder"]}/{pluginName}.dll", progressMeter); + + foreach(OnlineDependencyInfo dependency in pluginInfo.Dependencies) + await ServerCom.DownloadFileAsync(dependency.DownloadLocation, dependency.DownloadLocation, progressMeter); + + await _PluginManager.RemovePluginFromDatabase(pluginName); + await _PluginManager.AppendPluginToDatabase(pluginName, pluginInfo.Version); + } + + public async Task HasUpdate(string pluginName) + { + var localPluginInfo = await GetLocalPluginInfo(pluginName); + var pluginInfo = await GetPluginInfo(pluginName); + + return pluginInfo.Version.IsNewerThan(localPluginInfo.PluginVersion); + + } + +}