Formatted code and rebuilt PluginLoader

This commit is contained in:
2024-02-27 11:07:27 +02:00
parent 14f280baef
commit ef7a2c0896
40 changed files with 525 additions and 524 deletions

View File

@@ -8,7 +8,7 @@
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\PluginManager\PluginManager.csproj" />
<ProjectReference Include="..\PluginManager\PluginManager.csproj"/>
</ItemGroup>
</Project>

View File

@@ -6,13 +6,15 @@ using PluginManager.Plugin;
if (args.Length == 1)
{
PluginOnlineInfo? result = await JsonManager.ConvertFromJson<PluginOnlineInfo>(args[0]);
var result = await JsonManager.ConvertFromJson<PluginOnlineInfo>(args[0]);
// print all rows
Console.WriteLine($"Name: {result.Name}");
Console.WriteLine($"Version: {result.Version.ToShortString()}");
Console.WriteLine($"Description: {result.Description}");
Console.WriteLine($"Download link: {result.DownLoadLink}");
Console.WriteLine($"Supported OS: {((result.SupportedOS & OSType.WINDOWS) != 0 ? "Windows" : "")} {((result.SupportedOS & OSType.LINUX) != 0 ? "Linux" : "")} {((result.SupportedOS & OSType.MACOSX) != 0 ? "MacOSX" : "")}");
Console.WriteLine(
$"Supported OS: {((result.SupportedOS & OSType.WINDOWS) != 0 ? "Windows" : "")} {((result.SupportedOS & OSType.LINUX) != 0 ? "Linux" : "")} {((result.SupportedOS & OSType.MACOSX) != 0 ? "MacOSX" : "")}"
);
Console.WriteLine($"Has dependencies: {result.HasDependencies}");
Console.WriteLine($"Dependencies: {result.Dependencies.Count}");

View File

@@ -17,7 +17,7 @@ public class Exit: ICommandAction
{
if (args is null || args.Length == 0)
{
Config.Logger.Log("Exiting...", source: typeof(ICommandAction), type: LogType.WARNING);
Config.Logger.Log("Exiting...", typeof(ICommandAction), LogType.WARNING);
await Config.AppSettings.SaveToFile();
Environment.Exit(0);
}
@@ -33,7 +33,7 @@ public class Exit: ICommandAction
case "-f":
case "force":
Config.Logger.Log("Exiting (FORCE)...", source: typeof(ICommandAction), type: LogType.WARNING);
Config.Logger.Log("Exiting (FORCE)...", typeof(ICommandAction), LogType.WARNING);
Environment.Exit(0);
break;

View File

@@ -21,7 +21,14 @@ internal static class PluginMethods
{
var data = await ConsoleUtilities.ExecuteWithProgressBar(manager.GetPluginsList(), "Loading plugins...");
TableData tableData = new(new List<string> { "Name", "Description", "Version", "Has Dependencies" });
TableData tableData = new(new List<string>
{
"Name",
"Description",
"Version",
"Has Dependencies"
}
);
foreach (var plugin in data) tableData.AddRow([plugin.Name, plugin.Description, plugin.Version.ToString(), plugin.HasDependencies ? "Yes" : "No"]);
tableData.HasRoundBorders = false;
@@ -49,9 +56,7 @@ internal static class PluginMethods
await AnsiConsole.Progress()
.Columns(new ProgressColumn[]
{
new TaskDescriptionColumn(),
new ProgressBarColumn(),
new PercentageColumn()
new TaskDescriptionColumn(), new ProgressBarColumn(), new PercentageColumn()
}
)
.StartAsync(async ctx =>
@@ -79,16 +84,14 @@ internal static class PluginMethods
await AnsiConsole.Progress()
.Columns(new ProgressColumn[]
{
new TaskDescriptionColumn(),
new ProgressBarColumn(),
new PercentageColumn()
new TaskDescriptionColumn(), new ProgressBarColumn(), new PercentageColumn()
}
)
.StartAsync(async ctx =>
{
foreach (OnlineDependencyInfo dependency in pluginData.Dependencies)
foreach (var dependency in pluginData.Dependencies)
{
var task = ctx.AddTask($"Downloading {dependency.DownloadLocation}: ");
IProgress<float> progress = new Progress<float>(p =>
@@ -101,7 +104,7 @@ internal static class PluginMethods
downloadTasks.Add(new Tuple<ProgressTask, IProgress<float>, string, string>(task, progress, dependency.DownloadLink, dependency.DownloadLocation));
}
if (!int.TryParse(Config.AppSettings["MaxParallelDownloads"], out int maxParallelDownloads))
if (!int.TryParse(Config.AppSettings["MaxParallelDownloads"], out var maxParallelDownloads))
{
maxParallelDownloads = 5;
Config.AppSettings.Add("MaxParallelDownloads", "5");
@@ -135,74 +138,66 @@ internal static class PluginMethods
var loader = new PluginLoader(Config.DiscordBot.client);
if (args.Length == 2 && args[1] == "-q")
{
loader.LoadPlugins();
await loader.LoadPlugins();
return true;
}
var cc = Console.ForegroundColor;
loader.onCMDLoad += (name, typeName, success, exception) =>
loader.OnCommandLoaded += (data) =>
{
if (name == null || name.Length < 2)
name = typeName;
if (success)
if (data.IsSuccess)
{
Config.Logger.Log("Successfully loaded command : " + name, source: typeof(ICommandAction),
type: LogType.INFO
Config.Logger.Log("Successfully loaded command : " + data.PluginName, typeof(ICommandAction),
LogType.INFO
);
}
else
{
Config.Logger.Log("Failed to load command : " + name + " because " + exception?.Message,
source: typeof(ICommandAction), type: LogType.ERROR
Config.Logger.Log("Failed to load command : " + data.PluginName + " because " + data.ErrorMessage,
typeof(ICommandAction), LogType.ERROR
);
}
Console.ForegroundColor = cc;
};
loader.onEVELoad += (name, typeName, success, exception) =>
loader.OnEventLoaded += (data) =>
{
if (name == null || name.Length < 2)
name = typeName;
if (success)
if (data.IsSuccess)
{
Config.Logger.Log("Successfully loaded event : " + name, source: typeof(ICommandAction),
type: LogType.INFO
Config.Logger.Log("Successfully loaded event : " + data.PluginName, typeof(ICommandAction),
LogType.INFO
);
}
else
{
Config.Logger.Log("Failed to load event : " + name + " because " + exception?.Message,
source: typeof(ICommandAction), type: LogType.ERROR
Config.Logger.Log("Failed to load event : " + data.PluginName + " because " + data.ErrorMessage,
typeof(ICommandAction), LogType.ERROR
);
}
Console.ForegroundColor = cc;
};
loader.onSLSHLoad += (name, typeName, success, exception) =>
loader.OnSlashCommandLoaded += (data) =>
{
if (name == null || name.Length < 2)
name = typeName;
if (success)
if (data.IsSuccess)
{
Config.Logger.Log("Successfully loaded slash command : " + name, source: typeof(ICommandAction),
type: LogType.INFO
Config.Logger.Log("Successfully loaded slash command : " + data.PluginName, typeof(ICommandAction),
LogType.INFO
);
}
else
{
Config.Logger.Log("Failed to load slash command : " + name + " because " + exception?.Message,
source: typeof(ICommandAction), type: LogType.ERROR
Config.Logger.Log("Failed to load slash command : " + data.PluginName + " because " + data.ErrorMessage,
typeof(ICommandAction), LogType.ERROR
);
}
Console.ForegroundColor = cc;
};
loader.LoadPlugins();
await loader.LoadPlugins();
Console.ForegroundColor = cc;
return true;
}

View File

@@ -23,15 +23,32 @@ public class Help: ICommandAction
{
var items = new List<string[]>
{
new[] { "-", "-", "-" },
new[] { "Command", "Usage", "Description" },
new[] { "-", "-", "-" }
new[]
{
"-", "-", "-"
},
new[]
{
"Command", "Usage", "Description"
},
new[]
{
"-", "-", "-"
}
};
foreach (var a in Program.internalActionManager.Actions)
items.Add(new[] { a.Key, a.Value.Usage, a.Value.Description });
items.Add(new[]
{
a.Key, a.Value.Usage, a.Value.Description
}
);
items.Add(new[] { "-", "-", "-" });
items.Add(new[]
{
"-", "-", "-"
}
);
ConsoleUtilities.FormatAndAlignTable(items,
TableFormat.CENTER_EACH_COLUMN_BASED
@@ -48,11 +65,26 @@ public class Help: ICommandAction
var action = Program.internalActionManager.Actions[args[0]];
var actionData = new List<string[]>
{
new[] { "-", "-", "-" },
new[] { "Command", "Usage", "Description" },
new[] { "-", "-", "-" },
new[] { action.ActionName, action.Usage, action.Description },
new[] { "-", "-", "-" }
new[]
{
"-", "-", "-"
},
new[]
{
"Command", "Usage", "Description"
},
new[]
{
"-", "-", "-"
},
new[]
{
action.ActionName, action.Usage, action.Description
},
new[]
{
"-", "-", "-"
}
};
ConsoleUtilities.FormatAndAlignTable(actionData,

View File

@@ -34,7 +34,7 @@ public class Plugin: ICommandAction
return;
}
PluginsManager manager =
var manager =
#if !DEBUG
new PluginsManager("releases");
#else
@@ -54,13 +54,13 @@ public class Plugin: ICommandAction
case "load":
if (pluginsLoaded)
{
Config.Logger.Log("Plugins already loaded", source: typeof(ICommandAction), type: LogType.WARNING);
Config.Logger.Log("Plugins already loaded", typeof(ICommandAction), LogType.WARNING);
break;
}
if (Config.DiscordBot is null)
{
Config.Logger.Log("DiscordBot is null", source: typeof(ICommandAction), type: LogType.WARNING);
Config.Logger.Log("DiscordBot is null", typeof(ICommandAction), LogType.WARNING);
break;
}

View File

@@ -40,15 +40,15 @@ public class Help: DBSlashCommand
if (options.Count > 0)
{
var commandName = options.First().Name;
var slashCommand = slashCommands.FirstOrDefault(x => x.Name == commandName);
var commandName = options.First().Value;
var slashCommand = slashCommands.FirstOrDefault(x => x.Name.TrimEnd() == commandName.ToString());
if (slashCommand is null)
{
await context.RespondAsync("Unknown Command " + commandName);
return;
}
embedBuilder.AddField(slashCommand.Name, slashCommand.canUseDM)
embedBuilder.AddField("DM Usable:", slashCommand.canUseDM, true)
.WithDescription(slashCommand.Description);
}

View File

@@ -1,7 +1,6 @@
using System;
using PluginManager;
using Spectre.Console;
using System.Threading.Tasks;
namespace DiscordBot;
@@ -10,9 +9,9 @@ public static class Installer
{
public static async Task GenerateStartupConfig()
{
string token = await PluginManager.UX.UxHandler.ShowInputBox("SethBot", "Please enter the bot token:");
string botPrefix = await PluginManager.UX.UxHandler.ShowInputBox("SethBot", "Please enter the bot prefix:");
string serverId = await PluginManager.UX.UxHandler.ShowInputBox("SethBot", "Please enter the Server ID:");
var token = await PluginManager.UX.UxHandler.ShowInputBox("SethBot", "Please enter the bot token:");
var botPrefix = await PluginManager.UX.UxHandler.ShowInputBox("SethBot", "Please enter the bot prefix:");
var serverId = await PluginManager.UX.UxHandler.ShowInputBox("SethBot", "Please enter the Server ID:");
if (string.IsNullOrWhiteSpace(serverId)) serverId = "NULL";
@@ -28,6 +27,6 @@ public static class Installer
await Config.AppSettings.SaveToFile();
Config.Logger.Log("Config Saved", source: typeof(Installer));
Config.Logger.Log("Config Saved", typeof(Installer));
}
}

View File

@@ -69,7 +69,7 @@ public class Program
ConsoleUtilities.WriteColorText("&rRemember to close the bot using the ShutDown command (&yexit&r) or some settings won't be saved");
ConsoleUtilities.WriteColorText($"Running on &m{(System.OperatingSystem.IsWindows() ? "Windows" : "Linux")}");
ConsoleUtilities.WriteColorText($"Running on &m{(OperatingSystem.IsWindows() ? "Windows" : "Linux")}");
Console.WriteLine("============================ LOG ============================");
Console.ForegroundColor = ConsoleColor.White;
@@ -82,7 +82,7 @@ public class Program
}
catch (Exception ex)
{
Logger.Log(ex.ToString(), source: typeof(Program), type: LogType.CRITICAL);
Logger.Log(ex.ToString(), typeof(Program), LogType.CRITICAL);
}
}
@@ -102,12 +102,13 @@ public class Program
if (ex.Message == "No process is on the other end of the pipe." || (uint)ex.HResult == 0x800700E9)
{
UxHandler.ShowMessageBox("SethBot", "An error occured while closing the bot last time. Please consider closing the bot using the &rexit&c method !\n" +
"There is a risk of losing all data or corruption of the save file, which in some cases requires to reinstall the bot !", MessageBoxType.Error).Wait();
"There is a risk of losing all data or corruption of the save file, which in some cases requires to reinstall the bot !", MessageBoxType.Error
).Wait();
Logger.Log("An error occured while closing the bot last time. Please consider closing the bot using the &rexit&c method !\n" +
"There is a risk of losing all data or corruption of the save file, which in some cases requires to reinstall the bot !",
source: typeof(Program), type: LogType.ERROR
typeof(Program), LogType.ERROR
);
}
}
@@ -119,7 +120,7 @@ public class Program
Logger.OnLog += (sender, logMessage) =>
{
string messageColor = logMessage.Type switch
var messageColor = logMessage.Type switch
{
LogType.INFO => "[green]",
LogType.WARNING => "[yellow]",

View File

@@ -43,9 +43,7 @@ public static class ConsoleUtilities
.Columns(
new ProgressColumn[]
{
new TaskDescriptionColumn(),
new ProgressBarColumn(),
new PercentageColumn(),
new TaskDescriptionColumn(), new ProgressBarColumn(), new PercentageColumn()
}
)
.StartAsync(
@@ -67,9 +65,7 @@ public static class ConsoleUtilities
await AnsiConsole.Progress()
.Columns(new ProgressColumn[]
{
new TaskDescriptionColumn(),
new ProgressBarColumn(),
new PercentageColumn(),
new TaskDescriptionColumn(), new ProgressBarColumn(), new PercentageColumn()
}
)
.StartAsync(async ctx =>
@@ -85,11 +81,21 @@ public static class ConsoleUtilities
private static readonly Dictionary<char, ConsoleColor> Colors = new()
{
{ 'g', ConsoleColor.Green },
{ 'b', ConsoleColor.Blue },
{ 'r', ConsoleColor.Red },
{ 'm', ConsoleColor.Magenta },
{ 'y', ConsoleColor.Yellow }
{
'g', ConsoleColor.Green
},
{
'b', ConsoleColor.Blue
},
{
'r', ConsoleColor.Red
},
{
'm', ConsoleColor.Magenta
},
{
'y', ConsoleColor.Yellow
}
};
private static readonly char ColorPrefix = '&';
@@ -310,7 +316,10 @@ public static class ConsoleUtilities
public Spinner()
{
Sequence = new[] { "|", "/", "-", "\\" };
Sequence = new[]
{
"|", "/", "-", "\\"
};
position = 0;
}

View File

@@ -106,7 +106,7 @@ public class Boot
if (arg.Message.Contains("401"))
{
Config.AppSettings.Remove("token");
Config.Logger.Log("The token is invalid. Please restart the bot and enter a valid token.", source: typeof(Boot), type: LogType.CRITICAL);
Config.Logger.Log("The token is invalid. Please restart the bot and enter a valid token.", typeof(Boot), LogType.CRITICAL);
await Config.AppSettings.SaveToFile();
await Task.Delay(4000);
Environment.Exit(0);
@@ -115,7 +115,7 @@ public class Boot
private async Task Client_LoggedOut()
{
Config.Logger.Log("Successfully Logged Out", source: typeof(Boot));
Config.Logger.Log("Successfully Logged Out", typeof(Boot));
await Log(new LogMessage(LogSeverity.Info, "Boot", "Successfully logged out from discord !"));
}
@@ -128,7 +128,7 @@ public class Boot
private Task LoggedIn()
{
Config.Logger.Log("Successfully Logged In", source: typeof(Boot));
Config.Logger.Log("Successfully Logged In", typeof(Boot));
return Task.CompletedTask;
}
@@ -138,12 +138,12 @@ public class Boot
{
case LogSeverity.Error:
case LogSeverity.Critical:
Config.Logger.Log(message.Message, source: typeof(Boot), type: LogType.ERROR);
Config.Logger.Log(message.Message, typeof(Boot), LogType.ERROR);
break;
case LogSeverity.Info:
case LogSeverity.Debug:
Config.Logger.Log(message.Message, source: typeof(Boot), type: LogType.INFO);
Config.Logger.Log(message.Message, typeof(Boot), LogType.INFO);
break;

View File

@@ -25,9 +25,9 @@ internal class CommandHandler
/// <param name="botPrefix">The prefix to watch for</param>
public CommandHandler(DiscordSocketClient client, CommandService commandService, string botPrefix)
{
this._client = client;
this._commandService = commandService;
this._botPrefix = botPrefix;
_client = client;
_commandService = commandService;
_botPrefix = botPrefix;
}
/// <summary>
@@ -103,12 +103,10 @@ internal class CommandHandler
.FirstOrDefault(plug => plug.Command ==
message.Content.Substring(mentionPrefix.Length + 1)
.Split(' ')[0] ||
(
plug.Aliases is not null &&
plug.Aliases.Contains(message.CleanContent
.Substring(mentionPrefix.Length + 1)
.Split(' ')[0]
)
plug.Aliases is not null &&
plug.Aliases.Contains(message.CleanContent
.Substring(mentionPrefix.Length + 1)
.Split(' ')[0]
)
);
@@ -120,11 +118,11 @@ internal class CommandHandler
plugin = PluginLoader.Commands!
.FirstOrDefault(p => p.Command ==
message.Content.Split(' ')[0].Substring(_botPrefix.Length) ||
(p.Aliases is not null &&
p.Aliases.Contains(
message.Content.Split(' ')[0]
.Substring(_botPrefix.Length)
))
p.Aliases is not null &&
p.Aliases.Contains(
message.Content.Split(' ')[0]
.Substring(_botPrefix.Length)
)
);
cleanMessage = message.Content.Substring(_botPrefix.Length);
}
@@ -144,9 +142,9 @@ internal class CommandHandler
DbCommandExecutingArguments cmd = new(context, cleanMessage, split[0], argsClean);
Config.Logger.Log(
message: $"User ({context.User.Username}) from Guild \"{context.Guild.Name}\" executed command \"{cmd.cleanContent}\"",
source: typeof(CommandHandler),
type: LogType.INFO
$"User ({context.User.Username}) from Guild \"{context.Guild.Name}\" executed command \"{cmd.cleanContent}\"",
typeof(CommandHandler),
LogType.INFO
);
if (context.Channel is SocketDMChannel)

View File

@@ -29,8 +29,8 @@ public class Config
AppSettings = new SettingsDictionary<string, string>("./Data/Resources/config.json");
AppSettings["LogFolder"] = "./Data/Logs";
AppSettings["PluginFolder"] = "./Data/Plugins";
AppSettings["LogFolder"] = "./Data/Logs";
AppSettings["PluginFolder"] = "./Data/Plugins";
AppSettings["ArchiveFolder"] = "./Data/Archives";
if (OperatingSystem.IsLinux())
@@ -42,7 +42,8 @@ public class Config
"GNOME" => "GNOME",
_ => "CONSOLE"
};
} else AppSettings["UI"] = "CONSOLE";
}
else AppSettings["UI"] = "CONSOLE";
Logger = new Logger(false, true,
AppSettings["LogFolder"] + $"/{DateTime.Today.ToShortDateString().Replace("/", "")}.log"
@@ -54,7 +55,7 @@ public class Config
_isLoaded = true;
Logger.Log(message: "Config initialized", source: typeof(Config));
Logger.Log("Config initialized", typeof(Config));
}

View File

@@ -544,8 +544,10 @@ public class SqlDatabase
/// </summary>
/// <param name="parameterValues">The parameter raw inputs. The Key is name and the Value is the value of the parameter</param>
/// <returns>The SQLiteParameter that has the name, value and DBType set according to your inputs</returns>
private SQLiteParameter? CreateParameter(KeyValuePair<string, object> parameterValues) =>
CreateParameter(parameterValues.Key, parameterValues.Value);
private SQLiteParameter? CreateParameter(KeyValuePair<string, object> parameterValues)
{
return CreateParameter(parameterValues.Key, parameterValues.Value);
}
/// <summary>
/// Execute a query with parameters

View File

@@ -7,7 +7,9 @@ public interface IVersion
public int Patch { get; }
public bool IsNewerThan(IVersion version);
public bool IsOlderThan(IVersion version);
public bool IsEqualTo(IVersion version);
public string ToShortString();

View File

@@ -2,7 +2,7 @@ using System;
namespace PluginManager.Interfaces.Updater;
public abstract class Version : IVersion
public abstract class Version: IVersion
{
public int Major { get; }
public int Minor { get; }
@@ -12,9 +12,9 @@ public abstract class Version : IVersion
protected Version(int major, int minor, int patch)
{
this.Major = major;
this.Minor = minor;
this.Patch = patch;
Major = major;
Minor = minor;
Patch = patch;
}
protected Version(string versionAsString)
@@ -26,20 +26,20 @@ public abstract class Version : IVersion
throw new ArgumentException("Invalid version string");
}
this.Major = int.Parse(versionParts[0]);
this.Minor = int.Parse(versionParts[1]);
this.Patch = int.Parse(versionParts[2]);
Major = int.Parse(versionParts[0]);
Minor = int.Parse(versionParts[1]);
Patch = int.Parse(versionParts[2]);
}
public bool IsNewerThan(IVersion version)
{
if (this.Major > version.Major)
if (Major > version.Major)
return true;
if (this.Major == version.Major && this.Minor > version.Minor)
if (Major == version.Major && Minor > version.Minor)
return true;
if (this.Major == version.Major && this.Minor == version.Minor && this.Patch > version.Patch)
if (Major == version.Major && Minor == version.Minor && Patch > version.Patch)
return true;
return false;
@@ -47,13 +47,13 @@ public abstract class Version : IVersion
public bool IsOlderThan(IVersion version)
{
if (this.Major < version.Major)
if (Major < version.Major)
return true;
if (this.Major == version.Major && this.Minor < version.Minor)
if (Major == version.Major && Minor < version.Minor)
return true;
if (this.Major == version.Major && this.Minor == version.Minor && this.Patch < version.Patch)
if (Major == version.Major && Minor == version.Minor && Patch < version.Patch)
return true;
return false;
@@ -61,7 +61,7 @@ public abstract class Version : IVersion
public bool IsEqualTo(IVersion version)
{
return this.Major == version.Major && this.Minor == version.Minor && this.Patch == version.Patch;
return Major == version.Major && Minor == version.Minor && Patch == version.Patch;
}
public string ToShortString()

View File

@@ -0,0 +1,20 @@
namespace PluginManager.Loaders;
public class FileLoaderResult
{
public string PluginName { get; init; }
public string? ErrorMessage { get; init; }
public FileLoaderResult(string pluginName, string errorMessage)
{
PluginName = pluginName;
ErrorMessage = errorMessage;
}
public FileLoaderResult(string pluginName)
{
PluginName = pluginName;
}
}

View File

@@ -1,52 +1,40 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
using PluginManager.Interfaces;
using PluginManager.Others;
namespace PluginManager.Loaders;
internal class LoaderArgs: EventArgs
{
internal string? PluginName { get; init; }
internal string? TypeName { get; init; }
internal bool IsLoaded { get; init; }
internal Exception? Exception { get; init; }
internal object? Plugin { get; init; }
}
internal class Loader
{
internal Loader(string path, string extension)
private readonly string _SearchPath;
private readonly string _FileExtension;
internal delegate void FileLoadedHandler(FileLoaderResult result);
internal delegate void PluginLoadedHandler(PluginLoadResultData result);
internal event FileLoadedHandler? OnFileLoadedException;
internal event PluginLoadedHandler? OnPluginLoaded;
internal Loader(string searchPath, string fileExtension)
{
this.Path = path;
this.Extension = extension;
_SearchPath = searchPath;
_FileExtension = fileExtension;
}
private string Path { get; }
private string Extension { get; }
internal event FileLoadedEventHandler? FileLoaded;
internal event PluginLoadedEventHandler? PluginLoaded;
internal (List<DBEvent>?, List<DBCommand>?, List<DBSlashCommand>?) Load()
internal async Task Load()
{
List<DBEvent> events = new();
List<DBSlashCommand> slashCommands = new();
List<DBCommand> commands = new();
if (!Directory.Exists(Path))
if (!Directory.Exists(_SearchPath))
{
Directory.CreateDirectory(Path);
return (null, null, null);
Directory.CreateDirectory(_SearchPath);
return;
}
var files = Directory.GetFiles(Path, $"*.{Extension}", SearchOption.AllDirectories);
var files = Directory.GetFiles(_SearchPath, $"*.{_FileExtension}", SearchOption.TopDirectoryOnly);
foreach (var file in files)
{
try
@@ -55,91 +43,40 @@ internal class Loader
}
catch
{
Config.Logger.Log("PluginName: " + new FileInfo(file).Name.Split('.')[0] + " not loaded", source: typeof(Loader), type: LogType.ERROR);
continue;
}
if (FileLoaded != null)
{
var args = new LoaderArgs
{
Exception = null,
TypeName = null,
IsLoaded = false,
PluginName = new FileInfo(file).Name.Split('.')[0],
Plugin = null
};
FileLoaded.Invoke(args);
OnFileLoadedException?.Invoke(new FileLoaderResult(file, "Failed to load file"));
}
}
return (LoadItems<DBEvent>(), LoadItems<DBCommand>(), LoadItems<DBSlashCommand>());
await LoadEverythingOfType<DBEvent>();
await LoadEverythingOfType<DBCommand>();
await LoadEverythingOfType<DBSlashCommand>();
}
internal List<T> LoadItems<T>()
private async Task LoadEverythingOfType<T>()
{
List<T> list = new();
var types = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(s => s.GetTypes())
.Where(p => typeof(T).IsAssignableFrom(p) && !p.IsInterface);
try
foreach (var type in types)
{
var interfaceType = typeof(T);
var types = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(a => a.GetTypes())
.Where(p => interfaceType.IsAssignableFrom(p) && p.IsClass)
.ToArray();
list.Clear();
foreach (var type in types)
try
try
{
var plugin = (T)Activator.CreateInstance(type);
var pluginType = plugin switch
{
var plugin = (T)Activator.CreateInstance(type)!;
list.Add(plugin);
if (PluginLoaded != null)
PluginLoaded.Invoke(new LoaderArgs
{
Exception = null,
IsLoaded = true,
PluginName = type.FullName,
TypeName = typeof(T) == typeof(DBCommand) ? "DBCommand" :
typeof(T) == typeof(DBEvent) ? "DBEvent" :
typeof(T) == typeof(DBSlashCommand) ? "DBSlashCommand" :
null,
Plugin = plugin
}
);
}
catch (Exception ex)
{
if (PluginLoaded != null)
PluginLoaded.Invoke(new LoaderArgs
{
Exception = ex,
IsLoaded = false,
PluginName = type.FullName,
TypeName = nameof(T)
}
);
}
return list;
DBEvent => PluginType.EVENT,
DBCommand => PluginType.COMMAND,
DBSlashCommand => PluginType.SLASH_COMMAND,
_ => PluginType.UNKNOWN
};
OnPluginLoaded?.Invoke(new PluginLoadResultData(type.FullName, pluginType, true, plugin: plugin));
}
catch (Exception ex)
{
OnPluginLoaded?.Invoke(new PluginLoadResultData(type.FullName, PluginType.UNKNOWN, false, ex.Message));
}
}
catch (Exception ex)
{
Config.Logger.Log(ex.Message, source: typeof(Loader), type: LogType.ERROR);
return null;
}
return null;
}
internal delegate void FileLoadedEventHandler(LoaderArgs args);
internal delegate void PluginLoadedEventHandler(LoaderArgs args);
}

View File

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

View File

@@ -0,0 +1,22 @@
using PluginManager.Others;
namespace PluginManager.Loaders;
public class PluginLoadResultData
{
public string PluginName { get; init; }
public PluginType PluginType { get; init; }
public string? ErrorMessage { get; init; }
public bool IsSuccess { get; init; }
public object? Plugin { get; init; }
public PluginLoadResultData(string pluginName, PluginType pluginType, bool isSuccess, string? errorMessage = null, object plugin = null)
{
PluginName = pluginName;
PluginType = pluginType;
IsSuccess = isSuccess;
ErrorMessage = errorMessage;
Plugin = plugin;
}
}

View File

@@ -1,8 +1,5 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Threading.Tasks;
using Discord;
using Discord.WebSocket;
using PluginManager.Interfaces;
using PluginManager.Others;
@@ -11,173 +8,78 @@ namespace PluginManager.Loaders;
public class PluginLoader
{
public delegate void CMDLoaded(string name, string typeName, bool success, Exception? e = null);
internal readonly DiscordSocketClient _Client;
public delegate void EVELoaded(string name, string typeName, bool success, Exception? e = null);
public delegate void CommandLoaded(PluginLoadResultData resultData);
public delegate void SLSHLoaded(string name, string tyypename, bool success, Exception? e = null);
public delegate void EventLoaded(PluginLoadResultData resultData);
private const string pluginFolder = @"./Data/Plugins/";
public delegate void SlashCommandLoaded(PluginLoadResultData resultData);
internal const string pluginExtension = "dll";
private readonly DiscordSocketClient _client;
public CommandLoaded? OnCommandLoaded;
public EventLoaded? OnEventLoaded;
public SlashCommandLoaded? OnSlashCommandLoaded;
/// <summary>
/// Event that is fired when a <see cref="DBCommand" /> is successfully loaded into commands list
/// </summary>
public CMDLoaded? onCMDLoad;
public static List<DBCommand>? Commands;
public static List<DBEvent>? Events;
public static List<DBSlashCommand>? SlashCommands;
/// <summary>
/// Event that is fired when a <see cref="DBEvent" /> is successfully loaded into events list
/// </summary>
public EVELoaded? onEVELoad;
/// <summary>
/// Event that is fired when a <see cref="DBEvent" /> is successfully loaded into events list
/// </summary>
public SLSHLoaded? onSLSHLoad;
/// <summary>
/// The Plugin Loader constructor
/// </summary>
/// <param name="discordSocketClient">The discord bot client where the plugins will pe attached to</param>
public PluginLoader(DiscordSocketClient discordSocketClient)
{
_client = discordSocketClient;
_Client = discordSocketClient;
}
/// <summary>
/// A list of <see cref="DBCommand" /> commands
/// </summary>
public static List<DBCommand>? Commands { get; set; }
/// <summary>
/// A list of <see cref="DBEvent" /> commands
/// </summary>
public static List<DBEvent>? Events { get; set; }
/// <summary>
/// A list of <see cref="DBSlashCommand" /> commands
/// </summary>
public static List<DBSlashCommand>? SlashCommands { get; set; }
public static int PluginsLoaded
public async Task LoadPlugins()
{
get
{
var count = 0;
if (Commands is not null)
count += Commands.Count;
if (Events is not null)
count += Events.Count;
if (SlashCommands is not null)
count += SlashCommands.Count;
return count;
}
}
/// <summary>
/// The main mathod that is called to load all events
/// </summary>
public async void LoadPlugins()
{
//Load all plugins
Commands = new List<DBCommand>();
Events = new List<DBEvent>();
SlashCommands = new List<DBSlashCommand>();
Config.Logger.Log("Starting plugin loader ... Client: " + _client.CurrentUser.Username, source: typeof(PluginLoader), type: LogType.INFO);
Config.Logger.Log("Loading plugins...", typeof(PluginLoader));
var loader = new Loader("./Data/Plugins", "dll");
loader.FileLoaded += args => Config.Logger.Log($"{args.PluginName} file Loaded", source: typeof(PluginLoader), type: LogType.INFO);
loader.PluginLoaded += Loader_PluginLoaded;
var res = loader.Load();
Events = res.Item1;
Commands = res.Item2;
SlashCommands = res.Item3;
var loader = new Loader(Config.AppSettings["PluginFolder"], "dll");
loader.OnFileLoadedException += FileLoadedException;
loader.OnPluginLoaded += OnPluginLoaded;
await loader.Load();
}
private async void Loader_PluginLoaded(LoaderArgs args)
private void FileLoadedException(FileLoaderResult result)
{
switch (args.TypeName)
Config.Logger.Log(result.ErrorMessage, typeof(PluginLoader), LogType.ERROR);
}
private void OnPluginLoaded(PluginLoadResultData result)
{
switch (result.PluginType)
{
case "DBCommand":
onCMDLoad?.Invoke(((DBCommand)args.Plugin!).Command, args.TypeName!, args.IsLoaded, args.Exception);
case PluginType.COMMAND:
Commands.Add((DBCommand)result.Plugin);
OnCommandLoaded?.Invoke(result);
break;
case "DBEvent":
try
case PluginType.EVENT:
if (this.TryStartEvent((DBEvent)result.Plugin))
{
if (args.IsLoaded)
((DBEvent)args.Plugin!).Start(_client);
onEVELoad?.Invoke(((DBEvent)args.Plugin!).Name, args.TypeName!, args.IsLoaded, args.Exception);
}
catch (Exception ex)
{
Config.Logger.Log(ex.Message, source: typeof(PluginLoader), type: LogType.ERROR);
Events.Add((DBEvent)result.Plugin);
OnEventLoaded?.Invoke(result);
}
break;
case "DBSlashCommand":
if (args.IsLoaded)
case PluginType.SLASH_COMMAND:
if (this.TryStartSlashCommand((DBSlashCommand)result.Plugin))
{
var slash = (DBSlashCommand)args.Plugin;
var builder = new SlashCommandBuilder();
builder.WithName(slash.Name);
builder.WithDescription(slash.Description);
builder.WithDMPermission(slash.canUseDM);
builder.Options = slash.Options;
onSLSHLoad?.Invoke(((DBSlashCommand)args.Plugin!).Name, args.TypeName, args.IsLoaded,
args.Exception
);
await _client.CreateGlobalApplicationCommandAsync(builder.Build());
SlashCommands.Add((DBSlashCommand)result.Plugin);
OnSlashCommandLoaded?.Invoke(result);
}
break;
case PluginType.UNKNOWN:
default:
Config.Logger.Log("Unknown plugin type", typeof(PluginLoader), LogType.ERROR);
break;
}
}
public static async Task LoadPluginFromAssembly(Assembly asmb, DiscordSocketClient client)
{
var types = asmb.GetTypes();
foreach (var type in types)
try
{
if (type.IsClass && typeof(DBEvent).IsAssignableFrom(type))
{
var instance = (DBEvent)Activator.CreateInstance(type);
instance.Start(client);
Events.Add(instance);
Config.Logger.Log($"[EVENT] Loaded external {type.FullName}!", source: typeof(PluginLoader));
}
else if (type.IsClass && typeof(DBCommand).IsAssignableFrom(type))
{
var instance = (DBCommand)Activator.CreateInstance(type);
Commands.Add(instance);
Config.Logger.Log($"[CMD] Instance: {type.FullName} loaded !", source: typeof(PluginLoader));
}
else if (type.IsClass && typeof(DBSlashCommand).IsAssignableFrom(type))
{
var instance = (DBSlashCommand)Activator.CreateInstance(type);
var builder = new SlashCommandBuilder();
builder.WithName(instance.Name);
builder.WithDescription(instance.Description);
builder.WithDMPermission(instance.canUseDM);
builder.Options = instance.Options;
await client.CreateGlobalApplicationCommandAsync(builder.Build());
SlashCommands.Add(instance);
Config.Logger.Log($"[SLASH] Instance: {type.FullName} loaded !", source: typeof(PluginLoader));
}
}
catch (Exception ex)
{
//Console.WriteLine(ex.Message);
Config.Logger.Log(ex.Message, source: typeof(PluginLoader), type: LogType.ERROR);
}
}
}

View File

@@ -0,0 +1,54 @@
using System;
using Discord;
using PluginManager.Interfaces;
using PluginManager.Others;
namespace PluginManager.Loaders;
internal static class PluginLoaderExtensions
{
internal static bool TryStartEvent(this PluginLoader pluginLoader, DBEvent? dbEvent)
{
try
{
if (dbEvent is null)
{
throw new ArgumentNullException(nameof(dbEvent));
}
dbEvent.Start(pluginLoader._Client);
return true;
}
catch (Exception e)
{
Config.Logger.Log($"Error starting event {dbEvent.Name}: {e.Message}", typeof(PluginLoader), LogType.ERROR);
return false;
}
}
internal static bool TryStartSlashCommand(this PluginLoader pluginLoader, DBSlashCommand? dbSlashCommand)
{
try
{
if (dbSlashCommand is null)
{
throw new ArgumentNullException(nameof(dbSlashCommand));
}
var builder = new SlashCommandBuilder();
builder.WithName(dbSlashCommand.Name);
builder.WithDescription(dbSlashCommand.Description);
builder.WithDMPermission(dbSlashCommand.canUseDM);
builder.Options = dbSlashCommand.Options;
pluginLoader._Client.CreateGlobalApplicationCommandAsync(builder.Build());
return true;
}
catch (Exception e)
{
Config.Logger.Log($"Error starting slash command {dbSlashCommand.Name}: {e.Message}", typeof(PluginLoader), LogType.ERROR);
return false;
}
}
}

View File

@@ -2,7 +2,7 @@ using PluginManager.Interfaces.Updater;
namespace PluginManager.Online.Helpers;
public class ApplicationVersion : Version
public class ApplicationVersion: Version
{
public ApplicationVersion(int major, int minor, int patch): base(major, minor, patch)

View File

@@ -3,7 +3,7 @@ using PluginManager.Interfaces.Updater;
namespace PluginManager.Online.Helpers;
public class PluginVersion : Version
public class PluginVersion: Version
{
[JsonConstructor]
public PluginVersion(int major, int minor, int patch): base(major, minor, patch)

View File

@@ -9,7 +9,7 @@ namespace PluginManager.Online;
public class PluginsManager
{
private static readonly string _DefaultBranch = "releases";
private static readonly string _DefaultBranch = "releases";
private static readonly string _DefaultBaseUrl = "https://raw.githubusercontent.com/andreitdr/SethPlugins";
private static readonly string _DefaultPluginsLink = "PluginsList.json";
@@ -23,28 +23,29 @@ public class PluginsManager
public PluginsManager(Uri baseUrl, string branch)
{
this.BaseUrl = baseUrl.ToString();
this.Branch = branch;
BaseUrl = baseUrl.ToString();
Branch = branch;
}
public PluginsManager(string branch)
{
this.BaseUrl = _DefaultBaseUrl;
this.Branch = branch;
BaseUrl = _DefaultBaseUrl;
Branch = branch;
}
public PluginsManager()
{
this.BaseUrl = _DefaultBaseUrl;
this.Branch = _DefaultBranch;
BaseUrl = _DefaultBaseUrl;
Branch = _DefaultBranch;
}
public async Task<List<PluginOnlineInfo?>> GetPluginsList()
{
string jsonText = await ServerCom.GetAllTextFromUrl(PluginsLink);
List<PluginOnlineInfo?> result = await JsonManager.ConvertFromJson<List<PluginOnlineInfo?>>(jsonText);
var jsonText = await ServerCom.GetAllTextFromUrl(PluginsLink);
List<PluginOnlineInfo?> result = await JsonManager.ConvertFromJson<List<PluginOnlineInfo?>>(jsonText);
OSType currentOS = OperatingSystem.IsWindows() ? OSType.WINDOWS : OperatingSystem.IsLinux() ? OSType.LINUX : OSType.MACOSX;
var currentOS = OperatingSystem.IsWindows() ? OSType.WINDOWS :
OperatingSystem.IsLinux() ? OSType.LINUX : OSType.MACOSX;
return result.FindAll(pl => (pl.SupportedOS & currentOS) != 0);
}
@@ -52,7 +53,7 @@ public class PluginsManager
public async Task<PluginOnlineInfo?> GetPluginDataByName(string pluginName)
{
List<PluginOnlineInfo?> plugins = await GetPluginsList();
PluginOnlineInfo? result = plugins.Find(p => p.Name == pluginName);
var result = plugins.Find(p => p.Name == pluginName);
return result;
}

View File

@@ -89,7 +89,7 @@ public static class ArchiveManager
}
catch (Exception ex)
{
Config.Logger.Log(message: ex.Message, source: typeof(ArchiveManager), type: LogType.ERROR); // Write the error to a file
Config.Logger.Log(ex.Message, typeof(ArchiveManager), LogType.ERROR); // Write the error to a file
await Task.Delay(100);
return await ReadFromPakAsync(fileName, archFile);
}
@@ -126,7 +126,7 @@ public static class ArchiveManager
}
catch (Exception ex)
{
Config.Logger.Log(ex.Message, source: typeof(ArchiveManager), type: LogType.ERROR);
Config.Logger.Log(ex.Message, typeof(ArchiveManager), LogType.ERROR);
}
currentZipFile++;
@@ -158,7 +158,7 @@ public static class ArchiveManager
}
catch (Exception ex)
{
Config.Logger.Log(ex.Message, source: typeof(ArchiveManager), type: LogType.ERROR);
Config.Logger.Log(ex.Message, typeof(ArchiveManager), LogType.ERROR);
}
await Task.Delay(10);

View File

@@ -17,26 +17,26 @@ public class DbCommandExecutingArguments
public DbCommandExecutingArguments(SocketUserMessage? message, DiscordSocketClient client)
{
this.context = new SocketCommandContext(client, message);
int pos = 0;
context = new SocketCommandContext(client, message);
var pos = 0;
if (message.HasMentionPrefix(client.CurrentUser, ref pos))
{
var mentionPrefix = "<@" + client.CurrentUser.Id + ">";
this.cleanContent = message.Content.Substring(mentionPrefix.Length + 1);
cleanContent = message.Content.Substring(mentionPrefix.Length + 1);
}
else
{
this.cleanContent = message.Content.Substring(Config.DiscordBot.botPrefix.Length);
cleanContent = message.Content.Substring(Config.DiscordBot.botPrefix.Length);
}
var split = this.cleanContent.Split(' ');
var split = cleanContent.Split(' ');
string[]? argsClean = null;
if (split.Length > 1)
argsClean = string.Join(' ', split, 1, split.Length - 1).Split(' ');
this.commandUsed = split[0];
this.arguments = argsClean;
commandUsed = split[0];
arguments = argsClean;
}
public SocketCommandContext context { get; init; }

View File

@@ -32,10 +32,18 @@ public enum InternalActionRunType
}
[Flags]
public enum OSType : byte
public enum OSType: byte
{
NONE = 0,
NONE = 0,
WINDOWS = 1 << 0,
LINUX = 2 << 1,
MACOSX = 3 << 2,
LINUX = 2 << 1,
MACOSX = 3 << 2
}
public enum PluginType
{
UNKNOWN,
COMMAND,
EVENT,
SLASH_COMMAND
}

View File

@@ -18,7 +18,11 @@ public class JsonManager
public static async Task SaveToJsonFile<T>(string file, T Data)
{
var str = new MemoryStream();
await JsonSerializer.SerializeAsync(str, Data, typeof(T), new JsonSerializerOptions { WriteIndented = true });
await JsonSerializer.SerializeAsync(str, Data, typeof(T), new JsonSerializerOptions
{
WriteIndented = true
}
);
await File.WriteAllBytesAsync(file, str.ToArray());
await str.FlushAsync();
str.Close();

View File

@@ -43,9 +43,15 @@ public class Log: ILog
ThrowTime = DateTime.Now;
}
public static implicit operator Log(string message) => new(message);
public static implicit operator Log(string message)
{
return new Log(message);
}
public static implicit operator string(Log log) => $"[{log.ThrowTime}] {log.Message}";
public static implicit operator string(Log log)
{
return $"[{log.ThrowTime}] {log.Message}";
}
public string AsLongString()
{

View File

@@ -33,7 +33,7 @@ public class SettingsDictionary<TKey, TValue>: IDictionary<TKey, TValue>
{
if (File.Exists(_file))
{
string FileContent = File.ReadAllText(_file);
var FileContent = File.ReadAllText(_file);
if (string.IsNullOrEmpty(FileContent))
File.WriteAllText(_file, "{}");
@@ -66,62 +66,62 @@ public class SettingsDictionary<TKey, TValue>: IDictionary<TKey, TValue>
public void Add(KeyValuePair<TKey, TValue> item)
{
this._dictionary!.Add(item);
_dictionary!.Add(item);
}
public void Clear()
{
this._dictionary!.Clear();
_dictionary!.Clear();
}
public bool Contains(KeyValuePair<TKey, TValue> item)
{
return this._dictionary!.Contains(item);
return _dictionary!.Contains(item);
}
public void CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex)
{
this._dictionary!.CopyTo(array, arrayIndex);
_dictionary!.CopyTo(array, arrayIndex);
}
public bool Remove(KeyValuePair<TKey, TValue> item)
{
return this._dictionary!.Remove(item);
return _dictionary!.Remove(item);
}
public int Count => _dictionary!.Count;
public bool IsReadOnly => _dictionary!.IsReadOnly;
public void Add(TKey key, TValue value)
{
this._dictionary!.Add(key, value);
_dictionary!.Add(key, value);
}
public bool ContainsKey(TKey key)
{
return this._dictionary!.ContainsKey(key);
return _dictionary!.ContainsKey(key);
}
public bool Remove(TKey key)
{
return this._dictionary!.Remove(key);
return _dictionary!.Remove(key);
}
public bool TryGetValue(TKey key, out TValue value)
{
return this._dictionary!.TryGetValue(key, out value);
return _dictionary!.TryGetValue(key, out value);
}
public TValue this[TKey key]
{
get
{
if (this._dictionary!.ContainsKey(key))
if (this._dictionary[key] is string s && !string.IsNullOrEmpty(s) && !string.IsNullOrWhiteSpace(s))
return this._dictionary[key];
if (_dictionary!.ContainsKey(key))
if (_dictionary[key] is string s && !string.IsNullOrEmpty(s) && !string.IsNullOrWhiteSpace(s))
return _dictionary[key];
return default!;
}
set => this._dictionary![key] = value;
set => _dictionary![key] = value;
}
public ICollection<TKey> Keys => _dictionary!.Keys;

View File

@@ -7,7 +7,7 @@ public class OnlineDependencyInfo
public OnlineDependencyInfo(string downloadLink, string downloadLocation)
{
DownloadLink = downloadLink;
DownloadLink = downloadLink;
DownloadLocation = downloadLocation;
}
}

View File

@@ -11,7 +11,7 @@ public class PluginInfo
public PluginInfo(string pluginName, IVersion pluginVersion)
{
PluginName = pluginName;
PluginName = pluginName;
PluginVersion = pluginVersion;
FileData = new FileInfo($"{Config.AppSettings["PluginFolder"]}/{pluginName}.dll");

View File

@@ -19,23 +19,23 @@ public class PluginOnlineInfo
[JsonConstructor]
public PluginOnlineInfo(string name, PluginVersion version, string description, string downLoadLink, OSType supportedOS, List<OnlineDependencyInfo> dependencies)
{
Name = name;
Version = version;
Description = description;
DownLoadLink = downLoadLink;
SupportedOS = supportedOS;
Dependencies = dependencies;
Name = name;
Version = version;
Description = description;
DownLoadLink = downLoadLink;
SupportedOS = supportedOS;
Dependencies = dependencies;
HasDependencies = dependencies.Count > 0;
}
public PluginOnlineInfo(string name, PluginVersion version, string description, string downLoadLink, OSType supportedOS)
{
Name = name;
Version = version;
Description = description;
DownLoadLink = downLoadLink;
SupportedOS = supportedOS;
Dependencies = new List<OnlineDependencyInfo>();
Name = name;
Version = version;
Description = description;
DownLoadLink = downLoadLink;
SupportedOS = supportedOS;
Dependencies = new List<OnlineDependencyInfo>();
HasDependencies = false;
}

View File

@@ -12,17 +12,17 @@
<None Remove="BlankWindow1.xaml"/>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Avalonia" Version="11.0.6" />
<PackageReference Include="Avalonia" Version="11.0.6"/>
<PackageReference Include="Discord.Net" Version="3.11.0"/>
<PackageReference Include="Spectre.Console" Version="0.47.0" />
<PackageReference Include="Spectre.Console" Version="0.47.0"/>
<PackageReference Include="System.Data.SQLite.Core" Version="1.0.118"/>
</ItemGroup>
<ItemGroup>
<UpToDateCheckInput Remove="UI\Controls\MessageBox.axaml" />
<UpToDateCheckInput Remove="UI\Controls\MessageBox.axaml"/>
</ItemGroup>
<ItemGroup>
<Reference Include="Spectre.Console">
<HintPath>..\..\..\.nuget\packages\spectre.console\0.47.0\lib\net7.0\Spectre.Console.dll</HintPath>
</Reference>
<Reference Include="Spectre.Console">
<HintPath>..\..\..\.nuget\packages\spectre.console\0.47.0\lib\net7.0\Spectre.Console.dll</HintPath>
</Reference>
</ItemGroup>
</Project>

View File

@@ -13,16 +13,18 @@ public enum MessageBoxButtons
{
YesNo,
YesNoCancel,
ContinueCancel,
ContinueCancel
}
internal interface IOutputModel
{
internal Task ShowMessageBox(string title, string message, MessageBoxType type);
internal Task<string> ShowInputBox(string title, string message);
internal Task ShowMessageBox(string message);
internal Task<int> ShowMessageBox(string title, string message, MessageBoxButtons buttons, bool isWarning);
internal Task ShowNotification(string title, string message, int timeout_seconds = 5);

View File

@@ -3,7 +3,7 @@ using System.Threading.Tasks;
namespace PluginManager.UX.Linux;
internal class KDE : IOutputModel
internal class KDE: IOutputModel
{
internal string KdeDialogApplication { get; } = "kdialog";
@@ -12,12 +12,12 @@ internal class KDE : IOutputModel
var process = new Process();
process.StartInfo.FileName = KdeDialogApplication;
string typeStr = type switch
var typeStr = type switch
{
MessageBoxType.Info => "msgbox",
MessageBoxType.Info => "msgbox",
MessageBoxType.Warning => "sorry",
MessageBoxType.Error => "error",
_ => "info"
MessageBoxType.Error => "error",
_ => "info"
};
process.StartInfo.Arguments = $"--title \"{title}\" --{typeStr} \"{message}\"";
@@ -28,10 +28,10 @@ internal class KDE : IOutputModel
public async Task<string> ShowInputBox(string title, string message)
{
var process = new Process();
process.StartInfo.FileName = KdeDialogApplication;
process.StartInfo.Arguments = $"--title \"{title}\" --inputbox \"{message}\"";
process.StartInfo.FileName = KdeDialogApplication;
process.StartInfo.Arguments = $"--title \"{title}\" --inputbox \"{message}\"";
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.RedirectStandardInput = true;
process.StartInfo.RedirectStandardInput = true;
process.Start();
await process.WaitForExitAsync();
@@ -41,7 +41,7 @@ internal class KDE : IOutputModel
public async Task ShowMessageBox(string message)
{
var process = new Process();
process.StartInfo.FileName = KdeDialogApplication;
process.StartInfo.FileName = KdeDialogApplication;
process.StartInfo.Arguments = $"--msgbox \"{message}\"";
process.Start();
await process.WaitForExitAsync();
@@ -52,14 +52,14 @@ internal class KDE : IOutputModel
var process = new Process();
process.StartInfo.FileName = KdeDialogApplication;
string buttonsStr = buttons switch
var buttonsStr = buttons switch
{
MessageBoxButtons.YesNo => "yesno",
MessageBoxButtons.YesNoCancel => "yesnocancel",
MessageBoxButtons.YesNo => "yesno",
MessageBoxButtons.YesNoCancel => "yesnocancel",
MessageBoxButtons.ContinueCancel => "continuecancel",
_ => "yesno"
_ => "yesno"
};
string typeStr = isWarning ? "warning" : "";
var typeStr = isWarning ? "warning" : "";
process.StartInfo.Arguments = $"--title \"{title}\" --{typeStr}{buttonsStr} \"{message}\"";
process.Start();
await process.WaitForExitAsync();
@@ -69,7 +69,7 @@ internal class KDE : IOutputModel
public async Task ShowNotification(string title, string message, int timeout_seconds = 5)
{
var process = new Process();
process.StartInfo.FileName = KdeDialogApplication;
process.StartInfo.FileName = KdeDialogApplication;
process.StartInfo.Arguments = $"--title \"{title}\" --passivepopup \"{message}\" {timeout_seconds}";
process.Start();
await process.WaitForExitAsync();

View File

@@ -1,11 +1,9 @@
using System.Threading.Tasks;
using Spectre.Console;
namespace PluginManager.UX.Other;
internal class Console : IOutputModel
internal class Console: IOutputModel
{
public Task ShowMessageBox(string title, string message, MessageBoxType type)
@@ -21,7 +19,7 @@ internal class Console : IOutputModel
{
AnsiConsole.MarkupLine(title);
string input = AnsiConsole.Ask<string>(message);
var input = AnsiConsole.Ask<string>(message);
return Task.FromResult(input);
}
@@ -32,7 +30,7 @@ internal class Console : IOutputModel
return Task.CompletedTask;
}
public Task<int> ShowMessageBox(string title, string message,MessageBoxButtons buttons, bool isWarning)
public Task<int> ShowMessageBox(string title, string message, MessageBoxButtons buttons, bool isWarning)
{
AnsiConsole.MarkupLine(title);
AnsiConsole.MarkupLine(message);