Added autoinstall for modules
This commit is contained in:
@@ -4,6 +4,10 @@ using System.IO;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
|
||||||
|
using DiscordBot.Utilities;
|
||||||
|
|
||||||
|
using DiscordBotCore.Modules;
|
||||||
|
|
||||||
namespace DiscordBot;
|
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
|
/// Some startup actions that can are executed when the console first starts. This actions are invoked externally at application launch
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private static readonly List<IStartupAction> StartupActions = [
|
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))
|
foreach (var plugin in Directory.GetFiles("./Data/Plugins", "*.dll", SearchOption.AllDirectories))
|
||||||
{
|
{
|
||||||
File.Delete(plugin);
|
File.Delete(plugin);
|
||||||
@@ -34,6 +38,12 @@ public static class Entry
|
|||||||
}
|
}
|
||||||
|
|
||||||
Directory.Delete("temp");
|
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)
|
public static void Main(string[] args)
|
||||||
{
|
{
|
||||||
#if DEBUG
|
|
||||||
if (args.Length > 0)
|
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();
|
Console.Clear();
|
||||||
|
|
||||||
|
|||||||
@@ -91,25 +91,7 @@ public class Program
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Application.CurrentApplication.Logger.OnFormattedLog += (sender, logMessage) =>
|
Application.CurrentApplication.Logger.SetOutFunction(AnsiConsole.MarkupLine);
|
||||||
{
|
|
||||||
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);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
if (!Application.CurrentApplication.ApplicationEnvironmentVariables.ContainsKey("ServerID") ||
|
if (!Application.CurrentApplication.ApplicationEnvironmentVariables.ContainsKey("ServerID") ||
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -15,6 +15,7 @@ using DiscordBotCore.Interfaces.Logger;
|
|||||||
using DiscordBotCore.Modules;
|
using DiscordBotCore.Modules;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Collections.Immutable;
|
using System.Collections.Immutable;
|
||||||
|
using System.Diagnostics;
|
||||||
|
|
||||||
|
|
||||||
namespace DiscordBotCore
|
namespace DiscordBotCore
|
||||||
@@ -46,7 +47,28 @@ namespace DiscordBotCore
|
|||||||
public SettingsDictionary<string, string> ApplicationEnvironmentVariables { get; private set; }
|
public SettingsDictionary<string, string> ApplicationEnvironmentVariables { get; private set; }
|
||||||
public InternalActionManager InternalActionManager { 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 IPluginManager PluginManager { get; private set; }
|
||||||
public Bot.App DiscordBotClient { get; internal set; }
|
public Bot.App DiscordBotClient { get; internal set; }
|
||||||
|
|
||||||
@@ -61,6 +83,7 @@ namespace DiscordBotCore
|
|||||||
Directory.CreateDirectory(_PluginsFolder);
|
Directory.CreateDirectory(_PluginsFolder);
|
||||||
Directory.CreateDirectory(_ArchivesFolder);
|
Directory.CreateDirectory(_ArchivesFolder);
|
||||||
Directory.CreateDirectory(_LogsFolder);
|
Directory.CreateDirectory(_LogsFolder);
|
||||||
|
Directory.CreateDirectory(_ModuleFolder);
|
||||||
|
|
||||||
CurrentApplication.ApplicationEnvironmentVariables = new SettingsDictionary<string, string>(_ConfigFile);
|
CurrentApplication.ApplicationEnvironmentVariables = new SettingsDictionary<string, string>(_ConfigFile);
|
||||||
bool result = await CurrentApplication.ApplicationEnvironmentVariables.LoadFromFile();
|
bool result = await CurrentApplication.ApplicationEnvironmentVariables.LoadFromFile();
|
||||||
|
|||||||
@@ -14,16 +14,13 @@ namespace DiscordBotCore.Interfaces.Logger
|
|||||||
|
|
||||||
string LogMessageFormat { get; set; }
|
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);
|
||||||
void Log(string message, LogType logType);
|
void Log(string message, LogType logType);
|
||||||
void Log(string message, LogType logType, string format);
|
void Log(string message, LogType logType, string format);
|
||||||
void Log(string message, object Sender);
|
void Log(string message, object Sender);
|
||||||
void Log(string message, object Sender, LogType type);
|
void Log(string message, object Sender, LogType type);
|
||||||
void LogException(Exception exception, object Sender, bool logFullStack = false);
|
void LogException(Exception exception, object Sender, bool logFullStack = false);
|
||||||
|
|
||||||
|
void SetOutFunction(Action<string> outFunction);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ using System.Threading.Tasks;
|
|||||||
|
|
||||||
using DiscordBotCore.Interfaces.Modules;
|
using DiscordBotCore.Interfaces.Modules;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using Discord.Commands;
|
|
||||||
|
|
||||||
namespace DiscordBotCore.Loaders
|
namespace DiscordBotCore.Loaders
|
||||||
{
|
{
|
||||||
|
|||||||
30
DiscordBotCore/Modules/ModuleDownloader.cs
Normal file
30
DiscordBotCore/Modules/ModuleDownloader.cs
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,6 +6,7 @@ using System.Threading.Tasks;
|
|||||||
using DiscordBotCore.Interfaces.Logger;
|
using DiscordBotCore.Interfaces.Logger;
|
||||||
using DiscordBotCore.Interfaces.Modules;
|
using DiscordBotCore.Interfaces.Modules;
|
||||||
using DiscordBotCore.Loaders;
|
using DiscordBotCore.Loaders;
|
||||||
|
using DiscordBotCore.Others.Exceptions;
|
||||||
|
|
||||||
namespace DiscordBotCore.Modules
|
namespace DiscordBotCore.Modules
|
||||||
{
|
{
|
||||||
@@ -23,7 +24,10 @@ namespace DiscordBotCore.Modules
|
|||||||
public T GetModule<T>() where T : IBaseModule
|
public T GetModule<T>() where T : IBaseModule
|
||||||
{
|
{
|
||||||
if(!LoadedModules.ContainsKey(typeof(T)))
|
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];
|
IModule<T> module = (IModule<T>)LoadedModules[typeof(T)][0];
|
||||||
return module.Module;
|
return module.Module;
|
||||||
|
|||||||
16
DiscordBotCore/Others/Exceptions/ModuleNotFoundException.cs
Normal file
16
DiscordBotCore/Others/Exceptions/ModuleNotFoundException.cs
Normal 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)}")
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -8,14 +8,13 @@ public sealed class Logger : ILogger
|
|||||||
private readonly FileStream _LogFileStream;
|
private readonly FileStream _LogFileStream;
|
||||||
|
|
||||||
public List<string> LogMessageProperties = typeof(ILogMessage).GetProperties().Select(p => p.Name).ToList();
|
public List<string> LogMessageProperties = typeof(ILogMessage).GetProperties().Select(p => p.Name).ToList();
|
||||||
|
private Action<string>? _OutFunction;
|
||||||
public string LogMessageFormat { get ; set; }
|
public string LogMessageFormat { get ; set; }
|
||||||
|
|
||||||
public event EventHandler<ILogger.FormattedMessage> OnFormattedLog;
|
public Logger(string logFolder, string logMessageFormat, Action<string>? outFunction = null)
|
||||||
public event EventHandler<ILogMessage> OnRawLog;
|
|
||||||
|
|
||||||
public Logger(string logFolder, string logMessageFormat)
|
|
||||||
{
|
{
|
||||||
this.LogMessageFormat = logMessageFormat;
|
this.LogMessageFormat = logMessageFormat;
|
||||||
|
this._OutFunction = outFunction;
|
||||||
var logFile = logFolder + DateTime.Now.ToString("yyyy-MM-dd") + ".log";
|
var logFile = logFolder + DateTime.Now.ToString("yyyy-MM-dd") + ".log";
|
||||||
_LogFileStream = File.Open(logFile, FileMode.Append, FileAccess.Write, FileShare.Read);
|
_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());
|
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;
|
return messageAsString;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -57,22 +73,37 @@ public sealed class Logger : ILogger
|
|||||||
messageAsString = messageAsString.Replace("{" + prop + "}", messageType?.GetProperty(prop)?.GetValue(message)?.ToString());
|
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;
|
return messageAsString;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Log(ILogMessage message, string format)
|
public void Log(ILogMessage message, string format)
|
||||||
{
|
{
|
||||||
OnRawLog?.Invoke(this, message);
|
|
||||||
string messageAsString = GenerateLogMessage(message, format);
|
string messageAsString = GenerateLogMessage(message, format);
|
||||||
OnFormattedLog?.Invoke(this, new ILogger.FormattedMessage() { Message = messageAsString, Type = message.LogMessageType });
|
_OutFunction?.Invoke(messageAsString);
|
||||||
LogToFile(messageAsString);
|
LogToFile(messageAsString);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Log(ILogMessage message)
|
public void Log(ILogMessage message)
|
||||||
{
|
{
|
||||||
OnRawLog?.Invoke(this, message);
|
|
||||||
string messageAsString = GenerateLogMessage(message);
|
string messageAsString = GenerateLogMessage(message);
|
||||||
OnFormattedLog?.Invoke(this, new ILogger.FormattedMessage() { Message = messageAsString, Type = message.LogMessageType }) ;
|
_OutFunction?.Invoke(messageAsString);
|
||||||
LogToFile(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) => Log(new LogMessage(message, Sender));
|
||||||
public void Log(string message, object Sender, LogType type) => Log(new LogMessage(message, Sender, type));
|
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 LogException(Exception exception, object Sender, bool logFullStack = false) => Log(LogMessage.CreateFromException(exception, Sender, logFullStack));
|
||||||
|
|
||||||
|
public void SetOutFunction(Action<string> outFunction)
|
||||||
|
{
|
||||||
|
this._OutFunction = outFunction;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user