Added autoinstall for modules

This commit is contained in:
2024-07-14 21:24:49 +03:00
parent 3f8590b8f3
commit 13900bb3f3
10 changed files with 153 additions and 40 deletions

View File

@@ -4,6 +4,10 @@ using System.IO;
using System.Linq;
using System.Reflection;
using DiscordBot.Utilities;
using DiscordBotCore.Modules;
namespace DiscordBot;
@@ -13,7 +17,7 @@ public static class Entry
/// Some startup actions that can are executed when the console first starts. This actions are invoked externally at application launch
/// </summary>
private static readonly List<IStartupAction> StartupActions = [
new StartupAction("/purge_plugins", (args) => {
new StartupAction("/purge_plugins", () => {
foreach (var plugin in Directory.GetFiles("./Data/Plugins", "*.dll", SearchOption.AllDirectories))
{
File.Delete(plugin);
@@ -34,6 +38,12 @@ public static class Entry
}
Directory.Delete("temp");
}),
new StartupAction("--module-install", (args) => {
ModuleDownloader moduleDownloader = new ModuleDownloader(args[0]);
ConsoleUtilities.ExecuteTaskWithBuiltInProgress(moduleDownloader.DownloadModule, "Downloading logger module").Wait();
})
];
@@ -51,13 +61,11 @@ public static class Entry
";
public static void Main(string[] args)
{
#if DEBUG
if (args.Length > 0)
{
StartupActions.FirstOrDefault(action => action.Command == args[0], null)?.RunAction(args[..1]);
}
#endif
StartupActions.FirstOrDefault(action => action.Command == args[0], null)?.RunAction(args[1..]);
}
Console.Clear();

View File

@@ -91,25 +91,7 @@ public class Program
return;
}
Application.CurrentApplication.Logger.OnFormattedLog += (sender, logMessage) =>
{
var messageColor = logMessage.Type switch
{
LogType.INFO => "[green]",
LogType.WARNING => "[yellow]",
LogType.ERROR => "[red]",
LogType.CRITICAL => "[red]",
_ => "[white]"
};
if (logMessage.Message.Contains('[') || logMessage.Message.Contains(']'))
{
logMessage.Message = logMessage.Message.Replace("[", "<").Replace("]", ">");
}
string messageToPrint = $"{messageColor}{logMessage.Message}[/]";
AnsiConsole.MarkupLine(messageToPrint);
};
Application.CurrentApplication.Logger.SetOutFunction(AnsiConsole.MarkupLine);
if (!Application.CurrentApplication.ApplicationEnvironmentVariables.ContainsKey("ServerID") ||

View File

@@ -46,4 +46,22 @@ internal static class ConsoleUtilities
}
public static async Task ExecuteTaskWithBuiltInProgress(Func<IProgress<float>, Task> method, string taskMessage)
{
await AnsiConsole.Progress()
.AutoClear(false) // Do not remove the task list when done
.HideCompleted(false) // Hide tasks as they are completed
.Columns(new TaskDescriptionColumn(), new ProgressBarColumn(), new PercentageColumn())
.StartAsync(
async ctx =>
{
var task = ctx.AddTask(taskMessage);
IProgress<float> progress = new Progress<float>(x => task.Value = x);
await method(progress);
task.Value = 100;
}
);
}
}

View File

@@ -15,6 +15,7 @@ using DiscordBotCore.Interfaces.Logger;
using DiscordBotCore.Modules;
using System.Linq;
using System.Collections.Immutable;
using System.Diagnostics;
namespace DiscordBotCore
@@ -46,7 +47,28 @@ namespace DiscordBotCore
public SettingsDictionary<string, string> ApplicationEnvironmentVariables { get; private set; }
public InternalActionManager InternalActionManager { get; private set; }
public ILogger Logger => _ModuleManager.GetModule<ILogger>();
public ILogger Logger
{
get
{
try { return _ModuleManager.GetModule<ILogger>(); }
catch (ModuleNotFoundException<ILogger> ex)
{
Console.WriteLine("No logger found");
Console.WriteLine("Not having a valid logger is NOT an option. The default module will be downloaded from the official repo.");
Console.WriteLine("Install the default one ? [y/n]");
ConsoleKey response = Console.ReadKey().Key;
if (response is ConsoleKey.Y)
{
Process.Start("DiscordBot", "--module-install LoggerModule");
}
Environment.Exit(0);
return null!;
}
}
}
public IPluginManager PluginManager { get; private set; }
public Bot.App DiscordBotClient { get; internal set; }
@@ -61,6 +83,7 @@ namespace DiscordBotCore
Directory.CreateDirectory(_PluginsFolder);
Directory.CreateDirectory(_ArchivesFolder);
Directory.CreateDirectory(_LogsFolder);
Directory.CreateDirectory(_ModuleFolder);
CurrentApplication.ApplicationEnvironmentVariables = new SettingsDictionary<string, string>(_ConfigFile);
bool result = await CurrentApplication.ApplicationEnvironmentVariables.LoadFromFile();

View File

@@ -14,16 +14,13 @@ namespace DiscordBotCore.Interfaces.Logger
string LogMessageFormat { get; set; }
event EventHandler<FormattedMessage> OnFormattedLog;
event EventHandler<ILogMessage> OnRawLog;
void Log(ILogMessage message);
void Log(ILogMessage message, string format);
void Log(string message);
void Log(string message, LogType logType);
void Log(string message, LogType logType, string format);
void Log(string message, object Sender);
void Log(string message, object Sender, LogType type);
void LogException(Exception exception, object Sender, bool logFullStack = false);
void SetOutFunction(Action<string> outFunction);
}
}

View File

@@ -6,7 +6,6 @@ using System.Threading.Tasks;
using DiscordBotCore.Interfaces.Modules;
using System.Reflection;
using Discord.Commands;
namespace DiscordBotCore.Loaders
{

View File

@@ -0,0 +1,30 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using DiscordBotCore.Online;
namespace DiscordBotCore.Modules
{
public class ModuleDownloader
{
private string _moduleName;
private readonly string _baseUrl = "https://raw.githubusercontent.com/andreitdr/SethPlugins/tests/Modules/";
private readonly string _moduleFolder = "./Data/Modules";
public ModuleDownloader(string moduleName)
{
_moduleName = moduleName;
}
public async Task DownloadModule(IProgress<float> progressToWrite)
{
Directory.CreateDirectory(_moduleFolder);
string url = _baseUrl + _moduleName + ".dll";
await ServerCom.DownloadFileAsync(url, _moduleFolder + "/" + _moduleName + ".dll", progressToWrite);
}
}
}

View File

@@ -6,6 +6,7 @@ using System.Threading.Tasks;
using DiscordBotCore.Interfaces.Logger;
using DiscordBotCore.Interfaces.Modules;
using DiscordBotCore.Loaders;
using DiscordBotCore.Others.Exceptions;
namespace DiscordBotCore.Modules
{
@@ -23,7 +24,10 @@ namespace DiscordBotCore.Modules
public T GetModule<T>() where T : IBaseModule
{
if(!LoadedModules.ContainsKey(typeof(T)))
throw new Exception($"No module loaded with this signature: {nameof(T)}");
throw new ModuleNotFoundException<T>();
if (!LoadedModules[typeof(T)].Any())
throw new ModuleNotFoundException<T>();
IModule<T> module = (IModule<T>)LoadedModules[typeof(T)][0];
return module.Module;

View File

@@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DiscordBotCore.Others.Exceptions
{
internal class ModuleNotFoundException<T> : Exception
{
private Type _type = typeof(T);
public ModuleNotFoundException() : base($"No module loaded with this signature: {typeof(T)}")
{
}
}
}

View File

@@ -8,14 +8,13 @@ public sealed class Logger : ILogger
private readonly FileStream _LogFileStream;
public List<string> LogMessageProperties = typeof(ILogMessage).GetProperties().Select(p => p.Name).ToList();
private Action<string>? _OutFunction;
public string LogMessageFormat { get ; set; }
public event EventHandler<ILogger.FormattedMessage> OnFormattedLog;
public event EventHandler<ILogMessage> OnRawLog;
public Logger(string logFolder, string logMessageFormat)
public Logger(string logFolder, string logMessageFormat, Action<string>? outFunction = null)
{
this.LogMessageFormat = logMessageFormat;
this._OutFunction = outFunction;
var logFile = logFolder + DateTime.Now.ToString("yyyy-MM-dd") + ".log";
_LogFileStream = File.Open(logFile, FileMode.Append, FileAccess.Write, FileShare.Read);
}
@@ -34,6 +33,23 @@ public sealed class Logger : ILogger
messageAsString = messageAsString.Replace("{" + prop + "}", messageType?.GetProperty(prop)?.GetValue(message)?.ToString());
}
switch (message.LogMessageType)
{
case LogType.INFO:
messageAsString = $"[green]{messageAsString} [/]";
break;
case LogType.WARNING:
messageAsString = $"[yellow]{messageAsString} [/]";
break;
case LogType.ERROR:
messageAsString = $"[red]{messageAsString} [/]";
break;
case LogType.CRITICAL:
messageAsString = $"[red] [bold]{messageAsString} [/][/]";
break;
}
return messageAsString;
}
@@ -57,22 +73,37 @@ public sealed class Logger : ILogger
messageAsString = messageAsString.Replace("{" + prop + "}", messageType?.GetProperty(prop)?.GetValue(message)?.ToString());
}
switch (message.LogMessageType)
{
case LogType.INFO:
messageAsString = $"[green]{messageAsString} [/]";
break;
case LogType.WARNING:
messageAsString = $"[yellow]{messageAsString} [/]";
break;
case LogType.ERROR:
messageAsString = $"[red]{messageAsString} [/]";
break;
case LogType.CRITICAL:
messageAsString = $"[red][bold]{messageAsString} [/][/]";
break;
}
return messageAsString;
}
public void Log(ILogMessage message, string format)
{
OnRawLog?.Invoke(this, message);
string messageAsString = GenerateLogMessage(message, format);
OnFormattedLog?.Invoke(this, new ILogger.FormattedMessage() { Message = messageAsString, Type = message.LogMessageType });
_OutFunction?.Invoke(messageAsString);
LogToFile(messageAsString);
}
public void Log(ILogMessage message)
{
OnRawLog?.Invoke(this, message);
string messageAsString = GenerateLogMessage(message);
OnFormattedLog?.Invoke(this, new ILogger.FormattedMessage() { Message = messageAsString, Type = message.LogMessageType }) ;
_OutFunction?.Invoke(messageAsString);
LogToFile(messageAsString);
}
@@ -83,4 +114,9 @@ public sealed class Logger : ILogger
public void Log(string message, object Sender) => Log(new LogMessage(message, Sender));
public void Log(string message, object Sender, LogType type) => Log(new LogMessage(message, Sender, type));
public void LogException(Exception exception, object Sender, bool logFullStack = false) => Log(LogMessage.CreateFromException(exception, Sender, logFullStack));
public void SetOutFunction(Action<string> outFunction)
{
this._OutFunction = outFunction;
}
}