plugin list command now shows if the plugin is already installed.

This commit is contained in:
2024-03-26 23:54:44 +02:00
parent b6675af9cb
commit 5d4fa6fba7
14 changed files with 99 additions and 115 deletions

View File

@@ -1,4 +1,4 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
@@ -23,10 +23,17 @@ internal static class PluginMethods
"Name", "Name",
"Description", "Description",
"Version", "Version",
"Has Dependencies" "Is Installed"
} }
); );
foreach (var plugin in data) tableData.AddRow([plugin.Name, plugin.Description, plugin.Version.ToString(), plugin.HasDependencies ? "Yes" : "No"]);
var installedPlugins = await manager.GetInstalledPlugins();
foreach (var plugin in data)
{
bool isInstalled = installedPlugins.Any(p => p.PluginName == plugin.Name);
tableData.AddRow([plugin.Name, plugin.Description, plugin.Version.ToString(), isInstalled ? "Yes" : "No"]);
}
tableData.HasRoundBorders = false; tableData.HasRoundBorders = false;
tableData.PrintAsTable(); tableData.PrintAsTable();
@@ -133,7 +140,7 @@ internal static class PluginMethods
internal static async Task<bool> LoadPlugins(string[] args) internal static async Task<bool> LoadPlugins(string[] args)
{ {
var loader = new PluginLoader(Config.DiscordBot.client); var loader = new PluginLoader(Config.DiscordBot.Client);
if (args.Length == 2 && args[1] == "-q") if (args.Length == 2 && args[1] == "-q")
{ {
await loader.LoadPlugins(); await loader.LoadPlugins();

View File

@@ -1,4 +1,4 @@
using System.Threading.Tasks; using System.Threading.Tasks;
using PluginManager; using PluginManager;
using PluginManager.Interfaces; using PluginManager.Interfaces;
@@ -26,7 +26,7 @@ namespace DiscordBotUI.Bot
public async Task LoadPlugins() public async Task LoadPlugins()
{ {
var loader = new PluginLoader(Config.DiscordBot.client); var loader = new PluginLoader(Config.DiscordBot.Client);
loader.OnCommandLoaded += (data) => loader.OnCommandLoaded += (data) =>
{ {

View File

@@ -13,27 +13,27 @@ public class Boot
/// <summary> /// <summary>
/// The bot prefix /// The bot prefix
/// </summary> /// </summary>
public readonly string botPrefix; public readonly string BotPrefix;
/// <summary> /// <summary>
/// The bot token /// The bot token
/// </summary> /// </summary>
public readonly string botToken; public readonly string BotToken;
/// <summary> /// <summary>
/// The bot client /// The bot client
/// </summary> /// </summary>
public DiscordSocketClient client; public DiscordSocketClient Client;
/// <summary> /// <summary>
/// The bot command handler /// The bot command handler
/// </summary> /// </summary>
private CommandHandler commandServiceHandler; private CommandHandler _commandServiceHandler;
/// <summary> /// <summary>
/// The command service /// The command service
/// </summary> /// </summary>
private CommandService service; private CommandService _service;
/// <summary> /// <summary>
/// The main Boot constructor /// The main Boot constructor
@@ -42,8 +42,8 @@ public class Boot
/// <param name="botPrefix">The bot prefix</param> /// <param name="botPrefix">The bot prefix</param>
public Boot(string botToken, string botPrefix) public Boot(string botToken, string botPrefix)
{ {
this.botPrefix = botPrefix; this.BotPrefix = botPrefix;
this.botToken = botToken; this.BotToken = botToken;
} }
@@ -51,7 +51,7 @@ public class Boot
/// Checks if the bot is ready /// Checks if the bot is ready
/// </summary> /// </summary>
/// <value> true if the bot is ready, otherwise false </value> /// <value> true if the bot is ready, otherwise false </value>
public bool isReady { get; private set; } public bool IsReady { get; private set; }
/// <summary> /// <summary>
/// The start method for the bot. This method is used to load the bot /// The start method for the bot. This method is used to load the bot
@@ -73,33 +73,33 @@ public class Boot
GatewayIntents = GatewayIntents.All GatewayIntents = GatewayIntents.All
}; };
client = new DiscordSocketClient(config); Client = new DiscordSocketClient(config);
service = new CommandService(); _service = new CommandService();
CommonTasks(); CommonTasks();
await client.LoginAsync(TokenType.Bot, botToken); await Client.LoginAsync(TokenType.Bot, BotToken);
await client.StartAsync(); await Client.StartAsync();
commandServiceHandler = new CommandHandler(client, service, botPrefix); _commandServiceHandler = new CommandHandler(Client, _service, BotPrefix);
await commandServiceHandler.InstallCommandsAsync(); await _commandServiceHandler.InstallCommandsAsync();
Config.DiscordBotClient = this; Config.DiscordBotClient = this;
while (!isReady) ; while (!IsReady) ;
} }
private void CommonTasks() private void CommonTasks()
{ {
if (client == null) return; if (Client == null) return;
client.LoggedOut += Client_LoggedOut; Client.LoggedOut += Client_LoggedOut;
client.Log += Log; Client.Log += Log;
client.LoggedIn += LoggedIn; Client.LoggedIn += LoggedIn;
client.Ready += Ready; Client.Ready += Ready;
client.Disconnected += Client_Disconnected; Client.Disconnected += Client_Disconnected;
} }
private async Task Client_Disconnected(Exception arg) private async Task Client_Disconnected(Exception arg)
@@ -122,7 +122,7 @@ public class Boot
private Task Ready() private Task Ready()
{ {
isReady = true; IsReady = true;
// UxHandler.ShowNotification("SethBot", "Seth Discord Bot is now up and running !").Wait(); // UxHandler.ShowNotification("SethBot", "Seth Discord Bot is now up and running !").Wait();
return Task.CompletedTask; return Task.CompletedTask;
} }

View File

@@ -130,7 +130,7 @@ internal class CommandHandler
if (plugin is null) if (plugin is null)
return; return;
if (plugin.requireAdmin && !context.Message.Author.isAdmin()) if (plugin.requireAdmin && !context.Message.Author.IsAdmin())
return; return;
var split = cleanMessage.Split(' '); var split = cleanMessage.Split(' ');

View File

@@ -12,6 +12,16 @@ namespace PluginManager;
public class Config public class Config
{ {
private static readonly string _DefaultBranchForPlugins = "releases";
private static readonly string _ConfigFile = "./Data/Resources/config.json";
private static readonly string _PluginsDatabaseFile = "./Data/Resources/plugins.json";
private static readonly string _ResourcesFolder = "./Data/Resources";
private static readonly string _PluginsFolder = "./Data/Plugins";
private static readonly string _ArchivesFolder = "./Data/Archives";
private static readonly string _LogsFolder = "./Data/Logs";
private static bool _isLoaded; private static bool _isLoaded;
public static Logger Logger; public static Logger Logger;
public static SettingsDictionary<string, string> AppSettings; public static SettingsDictionary<string, string> AppSettings;
@@ -26,38 +36,33 @@ public class Config
{ {
if (_isLoaded) return; if (_isLoaded) return;
Directory.CreateDirectory("./Data/Resources"); Directory.CreateDirectory(_ResourcesFolder);
Directory.CreateDirectory("./Data/Plugins"); Directory.CreateDirectory(_PluginsFolder);
Directory.CreateDirectory("./Data/Archives"); Directory.CreateDirectory(_ArchivesFolder);
Directory.CreateDirectory("./Data/Logs"); Directory.CreateDirectory(_LogsFolder);
AppSettings = new SettingsDictionary<string, string>("./Data/Resources/config.json"); AppSettings = new SettingsDictionary<string, string>(_ConfigFile);
bool response = await AppSettings.LoadFromFile(); bool response = await AppSettings.LoadFromFile();
if (!response) if (!response)
throw new Exception("Invalid config file"); throw new Exception("Invalid config file");
AppSettings["LogFolder"] = "./Data/Logs"; AppSettings["LogFolder"] = _LogsFolder;
AppSettings["PluginFolder"] = "./Data/Plugins"; AppSettings["PluginFolder"] = _PluginsFolder;
AppSettings["ArchiveFolder"] = "./Data/Archives"; AppSettings["ArchiveFolder"] = _ArchivesFolder;
AppSettings["PluginDatabase"] = "./Data/Resources/plugins.json";
ArchiveManager.Initialize(); AppSettings["PluginDatabase"] = _PluginsDatabaseFile;
if (!File.Exists(_PluginsDatabaseFile))
if (!File.Exists(AppSettings["PluginDatabase"]))
{ {
List<PluginInfo> plugins = new(); List<PluginInfo> plugins = new();
await JsonManager.SaveToJsonFile(AppSettings["PluginDatabase"], plugins); await JsonManager.SaveToJsonFile(_PluginsDatabaseFile, plugins);
} }
Logger = new Logger(false, true, AppSettings["LogFolder"] + $"/{DateTime.Today.ToShortDateString().Replace("/", "")}.log"); Logger = new Logger(false, true, _LogsFolder + $"/{DateTime.Today.ToShortDateString().Replace("/", "")}.log");
PluginsManager = new PluginsManager("releases"); PluginsManager = new PluginsManager(_DefaultBranchForPlugins);
await PluginsManager.UninstallMarkedPlugins(); await PluginsManager.UninstallMarkedPlugins();

View File

@@ -13,22 +13,22 @@ public class ActionsLoader
{ {
public delegate void ActionLoaded(string name, string typeName, bool success, Exception? e = null); public delegate void ActionLoaded(string name, string typeName, bool success, Exception? e = null);
private readonly string actionExtension = "dll"; private readonly string _actionExtension = "dll";
private readonly string actionFolder = @"./Data/Plugins/"; private readonly string _actionFolder = @"./Data/Plugins/";
public ActionsLoader(string path, string extension) public ActionsLoader(string path, string extension)
{ {
actionFolder = path; _actionFolder = path;
actionExtension = extension; _actionExtension = extension;
} }
public event ActionLoaded? ActionLoadedEvent; public event ActionLoaded? ActionLoadedEvent;
public async Task<List<ICommandAction>?> Load() public async Task<List<ICommandAction>?> Load()
{ {
Directory.CreateDirectory(actionFolder); Directory.CreateDirectory(_actionFolder);
var files = Directory.GetFiles(actionFolder, $"*.{actionExtension}", SearchOption.AllDirectories); var files = Directory.GetFiles(_actionFolder, $"*.{_actionExtension}", SearchOption.AllDirectories);
var actions = new List<ICommandAction>(); var actions = new List<ICommandAction>();

View File

@@ -1,6 +0,0 @@
namespace PluginManager.Loaders;
public class PluginHandler
{
}

View File

@@ -1,10 +1,8 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using PluginManager.Online.Helpers;
using PluginManager.Others; using PluginManager.Others;
using PluginManager.Plugin; using PluginManager.Plugin;
using PluginManager.Updater.Plugins; using PluginManager.Updater.Plugins;
@@ -83,6 +81,13 @@ public class PluginsManager
return await JsonManager.ConvertFromJson<List<PluginInfo>>(await File.ReadAllTextAsync(Config.AppSettings["PluginDatabase"])); return await JsonManager.ConvertFromJson<List<PluginInfo>>(await File.ReadAllTextAsync(Config.AppSettings["PluginDatabase"]));
} }
public async Task<bool> IsPluginInstalled(string pluginName)
{
List<PluginInfo> installedPlugins = await JsonManager.ConvertFromJson<List<PluginInfo>>(await File.ReadAllTextAsync(Config.AppSettings["PluginDatabase"]));
return installedPlugins.Any(plugin => plugin.PluginName == pluginName);
}
public async Task CheckForUpdates() public async Task CheckForUpdates()
{ {
var pluginUpdater = new PluginUpdater(this); var pluginUpdater = new PluginUpdater(this);

View File

@@ -9,19 +9,19 @@ namespace PluginManager.Others.Actions;
public class InternalActionManager public class InternalActionManager
{ {
public Dictionary<string, ICommandAction> Actions = new(); public Dictionary<string, ICommandAction> Actions = new();
public ActionsLoader loader; private readonly ActionsLoader _loader;
public InternalActionManager(string path, string extension) public InternalActionManager(string path, string extension)
{ {
loader = new ActionsLoader(path, extension); _loader = new ActionsLoader(path, extension);
} }
public async Task Initialize() public async Task Initialize()
{ {
var m_actions = await loader.Load(); var loadedActions = await _loader.Load();
if (m_actions == null) if (loadedActions == null)
return; return;
foreach (var action in m_actions) foreach (var action in loadedActions)
Actions.TryAdd(action.ActionName, action); Actions.TryAdd(action.ActionName, action);
} }

View File

@@ -8,27 +8,9 @@ namespace PluginManager.Others;
public static class ArchiveManager public static class ArchiveManager
{ {
private static string? _ArchiveFolder;
private static bool IsInitialized { get; set; }
public static void Initialize() public static void CreateFromFile(string file, string folder)
{ {
if (IsInitialized)
throw new Exception("ArchiveManager is already initialized");
if (!Config.AppSettings.ContainsKey("ArchiveFolder"))
Config.AppSettings["ArchiveFolder"] = "./Data/Archives/";
_ArchiveFolder = Config.AppSettings["ArchiveFolder"];
IsInitialized = true;
}
public static async Task CreateFromFile(string file, string folder)
{
if(!IsInitialized) throw new Exception("ArchiveManager is not initialized");
if (!Directory.Exists(folder)) if (!Directory.Exists(folder))
Directory.CreateDirectory(folder); Directory.CreateDirectory(folder);
@@ -50,9 +32,8 @@ public static class ArchiveManager
/// <returns>An array of bytes that represents the Stream value from the file that was read inside the archive</returns> /// <returns>An array of bytes that represents the Stream value from the file that was read inside the archive</returns>
public static async Task<byte[]?> ReadStreamFromPakAsync(string fileName, string archName) public static async Task<byte[]?> ReadStreamFromPakAsync(string fileName, string archName)
{ {
if (!IsInitialized) throw new Exception("ArchiveManager is not initialized");
archName = _ArchiveFolder + archName; archName = Config.AppSettings["ArchiveFolder"] + archName;
if (!File.Exists(archName)) if (!File.Exists(archName))
throw new Exception("Failed to load file !"); throw new Exception("Failed to load file !");
@@ -80,8 +61,7 @@ public static class ArchiveManager
/// <returns>A string that represents the content of the file or null if the file does not exists or it has no content</returns> /// <returns>A string that represents the content of the file or null if the file does not exists or it has no content</returns>
public static async Task<string?> ReadFromPakAsync(string fileName, string archFile) public static async Task<string?> ReadFromPakAsync(string fileName, string archFile)
{ {
if (!IsInitialized) throw new Exception("ArchiveManager is not initialized"); archFile = Config.AppSettings["ArchiveFolder"] + archFile;
archFile = _ArchiveFolder + archFile;
if (!File.Exists(archFile)) if (!File.Exists(archFile))
throw new Exception("Failed to load file !"); throw new Exception("Failed to load file !");
@@ -125,7 +105,6 @@ public static class ArchiveManager
string zip, string folder, IProgress<float> progress, string zip, string folder, IProgress<float> progress,
UnzipProgressType type) UnzipProgressType type)
{ {
if (!IsInitialized) throw new Exception("ArchiveManager is not initialized");
Directory.CreateDirectory(folder); Directory.CreateDirectory(folder);
using var archive = ZipFile.OpenRead(zip); using var archive = ZipFile.OpenRead(zip);
var totalZipFiles = archive.Entries.Count(); var totalZipFiles = archive.Entries.Count();

View File

@@ -6,6 +6,13 @@ namespace PluginManager.Others;
public class DbCommandExecutingArguments public class DbCommandExecutingArguments
{ {
public SocketCommandContext context { get; init; }
public string cleanContent { get; init; }
public string commandUsed { get; init; }
public string[]? arguments { get; init; }
public ISocketMessageChannel Channel => context.Channel;
public DbCommandExecutingArguments( public DbCommandExecutingArguments(
SocketCommandContext context, string cleanContent, string commandUsed, string[]? arguments) SocketCommandContext context, string cleanContent, string commandUsed, string[]? arguments)
{ {
@@ -26,7 +33,7 @@ public class DbCommandExecutingArguments
} }
else else
{ {
cleanContent = message.Content.Substring(Config.DiscordBot.botPrefix.Length); cleanContent = message.Content.Substring(Config.DiscordBot.BotPrefix.Length);
} }
var split = cleanContent.Split(' '); var split = cleanContent.Split(' ');
@@ -38,10 +45,4 @@ public class DbCommandExecutingArguments
commandUsed = split[0]; commandUsed = split[0];
arguments = argsClean; arguments = argsClean;
} }
public SocketCommandContext context { get; init; }
public string cleanContent { get; init; }
public string commandUsed { get; init; }
public string[]? arguments { get; init; }
public ISocketMessageChannel Channel => context.Channel;
} }

View File

@@ -19,12 +19,6 @@ public enum UnzipProgressType
PERCENTAGE_FROM_TOTAL_SIZE PERCENTAGE_FROM_TOTAL_SIZE
} }
public enum SaveType
{
TXT,
JSON
}
public enum InternalActionRunType public enum InternalActionRunType
{ {
ON_STARTUP, ON_STARTUP,

View File

@@ -26,7 +26,7 @@ public static class DiscordPermissions
/// <param name="user">The user</param> /// <param name="user">The user</param>
/// <param name="role">The role</param> /// <param name="role">The role</param>
/// <returns></returns> /// <returns></returns>
public static bool hasRole(this SocketGuildUser user, IRole role) public static bool HasRole(this SocketGuildUser user, IRole role)
{ {
return user.Roles.Contains(role); return user.Roles.Contains(role);
} }
@@ -37,7 +37,7 @@ public static class DiscordPermissions
/// <param name="user">The user</param> /// <param name="user">The user</param>
/// <param name="permission">The permission</param> /// <param name="permission">The permission</param>
/// <returns></returns> /// <returns></returns>
public static bool hasPermission(this SocketGuildUser user, GuildPermission permission) public static bool HasPermission(this SocketGuildUser user, GuildPermission permission)
{ {
return user.Roles.Where(role => role.hasPermission(permission)).Any() || user.Guild.Owner == user; return user.Roles.Where(role => role.hasPermission(permission)).Any() || user.Guild.Owner == user;
} }
@@ -47,9 +47,9 @@ public static class DiscordPermissions
/// </summary> /// </summary>
/// <param name="user">The user</param> /// <param name="user">The user</param>
/// <returns></returns> /// <returns></returns>
public static bool isAdmin(this SocketGuildUser user) public static bool IsAdmin(this SocketGuildUser user)
{ {
return user.hasPermission(GuildPermission.Administrator); return user.HasPermission(GuildPermission.Administrator);
} }
/// <summary> /// <summary>
@@ -57,8 +57,8 @@ public static class DiscordPermissions
/// </summary> /// </summary>
/// <param name="user">The user</param> /// <param name="user">The user</param>
/// <returns></returns> /// <returns></returns>
public static bool isAdmin(this SocketUser user) public static bool IsAdmin(this SocketUser user)
{ {
return isAdmin((SocketGuildUser)user); return IsAdmin((SocketGuildUser)user);
} }
} }

View File

@@ -1,7 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using PluginManager.Online; using PluginManager.Online;
using PluginManager.Plugin; using PluginManager.Plugin;
@@ -10,16 +9,16 @@ namespace PluginManager.Updater.Plugins;
public class PluginUpdater public class PluginUpdater
{ {
private readonly PluginsManager _PluginManager; private readonly PluginsManager _PluginsManager;
public PluginUpdater(PluginsManager pluginManager) public PluginUpdater(PluginsManager pluginManager)
{ {
_PluginManager = pluginManager; _PluginsManager = pluginManager;
} }
public async Task<PluginOnlineInfo> GetPluginInfo(string pluginName) public async Task<PluginOnlineInfo> GetPluginInfo(string pluginName)
{ {
var result = await _PluginManager.GetPluginDataByName(pluginName); var result = await _PluginsManager.GetPluginDataByName(pluginName);
return result; return result;
} }
@@ -41,8 +40,8 @@ public class PluginUpdater
foreach(OnlineDependencyInfo dependency in pluginInfo.Dependencies) foreach(OnlineDependencyInfo dependency in pluginInfo.Dependencies)
await ServerCom.DownloadFileAsync(dependency.DownloadLocation, dependency.DownloadLocation, progressMeter); await ServerCom.DownloadFileAsync(dependency.DownloadLocation, dependency.DownloadLocation, progressMeter);
await _PluginManager.RemovePluginFromDatabase(pluginName); await _PluginsManager.RemovePluginFromDatabase(pluginName);
await _PluginManager.AppendPluginToDatabase(PluginInfo.FromOnlineInfo(pluginInfo)); await _PluginsManager.AppendPluginToDatabase(PluginInfo.FromOnlineInfo(pluginInfo));
} }
public async Task<bool> HasUpdate(string pluginName) public async Task<bool> HasUpdate(string pluginName)