Improved logging.
This commit is contained in:
@@ -17,9 +17,8 @@ public class Exit : ICommandAction
|
|||||||
{
|
{
|
||||||
if (args is null || args.Length == 0)
|
if (args is null || args.Length == 0)
|
||||||
{
|
{
|
||||||
Config.Logger.Log("Exiting...", "Exit", isInternal: false);
|
Config.Logger.Log("Exiting...", source: typeof(ICommandAction), type: LogType.WARNING);
|
||||||
await Config.AppSettings.SaveToFile();
|
await Config.AppSettings.SaveToFile();
|
||||||
await Config.Logger.SaveToFile();
|
|
||||||
Environment.Exit(0);
|
Environment.Exit(0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -34,7 +33,7 @@ public class Exit : ICommandAction
|
|||||||
|
|
||||||
case "-f":
|
case "-f":
|
||||||
case "force":
|
case "force":
|
||||||
Config.Logger.Log("Exiting (FORCE)...", "Exit", LogLevel.WARNING, false);
|
Config.Logger.Log("Exiting (FORCE)...", source: typeof(ICommandAction), type: LogType.WARNING);
|
||||||
Environment.Exit(0);
|
Environment.Exit(0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|||||||
204
DiscordBot/Bot/Actions/Extra/PluginMethods.cs
Normal file
204
DiscordBot/Bot/Actions/Extra/PluginMethods.cs
Normal file
@@ -0,0 +1,204 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using DiscordBot.Utilities;
|
||||||
|
using PluginManager;
|
||||||
|
using PluginManager.Interfaces;
|
||||||
|
using PluginManager.Loaders;
|
||||||
|
using PluginManager.Online;
|
||||||
|
using PluginManager.Others;
|
||||||
|
using Spectre.Console;
|
||||||
|
|
||||||
|
namespace DiscordBot.Bot.Actions.Extra;
|
||||||
|
|
||||||
|
internal static class PluginMethods
|
||||||
|
{
|
||||||
|
private static readonly PluginsManager PluginsManager = new();
|
||||||
|
|
||||||
|
internal static async Task List()
|
||||||
|
{
|
||||||
|
var data = await ConsoleUtilities.ExecuteWithProgressBar(PluginsManager.GetAvailablePlugins(), "Loading plugins...");
|
||||||
|
|
||||||
|
TableData tableData = new(new List<string> { "Name", "Description", "Type", "Version" });
|
||||||
|
foreach (var plugin in data) tableData.AddRow(plugin);
|
||||||
|
|
||||||
|
tableData.HasRoundBorders = false;
|
||||||
|
tableData.PrintAsTable();
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static async Task RefreshPlugins(bool quiet)
|
||||||
|
{
|
||||||
|
await Program.internalActionManager.Execute("plugin", "load", quiet ? "-q" : string.Empty);
|
||||||
|
await Program.internalActionManager.Refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static async Task DownloadPlugin(PluginsManager manager, string pluginName)
|
||||||
|
{
|
||||||
|
var pluginData = await manager.GetPluginLinkByName(pluginName);
|
||||||
|
if (pluginData.Length == 0)
|
||||||
|
{
|
||||||
|
Console.WriteLine($"Plugin {pluginName} not found. Please check the spelling and try again.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var pluginType = pluginData[0];
|
||||||
|
var pluginLink = pluginData[1];
|
||||||
|
var pluginRequirements = pluginData[2];
|
||||||
|
|
||||||
|
|
||||||
|
await AnsiConsole.Progress()
|
||||||
|
.Columns(new ProgressColumn[]
|
||||||
|
{
|
||||||
|
new TaskDescriptionColumn(),
|
||||||
|
new ProgressBarColumn(),
|
||||||
|
new PercentageColumn()
|
||||||
|
})
|
||||||
|
.StartAsync(async ctx =>
|
||||||
|
{
|
||||||
|
var downloadTask = ctx.AddTask("Downloading plugin...");
|
||||||
|
|
||||||
|
IProgress<float> progress = new Progress<float>(p => { downloadTask.Value = p; });
|
||||||
|
|
||||||
|
await ServerCom.DownloadFileAsync(pluginLink, $"./Data/{pluginType}s/{pluginName}.dll", progress);
|
||||||
|
|
||||||
|
downloadTask.Increment(100);
|
||||||
|
|
||||||
|
ctx.Refresh();
|
||||||
|
});
|
||||||
|
|
||||||
|
if (pluginRequirements == string.Empty)
|
||||||
|
{
|
||||||
|
Console.WriteLine("Finished installing " + pluginName + " successfully");
|
||||||
|
await RefreshPlugins(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<string> requirementsUrLs = new();
|
||||||
|
|
||||||
|
await AnsiConsole.Progress()
|
||||||
|
.Columns(new ProgressColumn[]
|
||||||
|
{
|
||||||
|
new TaskDescriptionColumn(),
|
||||||
|
new ProgressBarColumn(),
|
||||||
|
new PercentageColumn()
|
||||||
|
})
|
||||||
|
.StartAsync(async ctx =>
|
||||||
|
{
|
||||||
|
var gatherInformationTask = ctx.AddTask("Gathering info...");
|
||||||
|
gatherInformationTask.IsIndeterminate = true;
|
||||||
|
requirementsUrLs = await ServerCom.ReadTextFromURL(pluginRequirements);
|
||||||
|
await Task.Delay(2000);
|
||||||
|
gatherInformationTask.Increment(100);
|
||||||
|
});
|
||||||
|
|
||||||
|
await AnsiConsole.Progress()
|
||||||
|
.Columns(new ProgressColumn[]
|
||||||
|
{
|
||||||
|
new TaskDescriptionColumn(),
|
||||||
|
new ProgressBarColumn(),
|
||||||
|
new PercentageColumn()
|
||||||
|
})
|
||||||
|
.StartAsync(async ctx =>
|
||||||
|
{
|
||||||
|
List<Tuple<ProgressTask, IProgress<float>, Task>> downloadTasks = new();
|
||||||
|
|
||||||
|
foreach (var info in requirementsUrLs)
|
||||||
|
{
|
||||||
|
if (info.Length < 2) continue;
|
||||||
|
string[] data = info.Split(',');
|
||||||
|
string url = data[0];
|
||||||
|
string fileName = data[1];
|
||||||
|
|
||||||
|
var task = ctx.AddTask($"Downloading {fileName}...");
|
||||||
|
IProgress<float> progress = new Progress<float>(p =>
|
||||||
|
{
|
||||||
|
task.Value = p;
|
||||||
|
});
|
||||||
|
|
||||||
|
var downloadTask = ServerCom.DownloadFileAsync(url, $"./{fileName}", progress);
|
||||||
|
downloadTasks.Add(new Tuple<ProgressTask, IProgress<float>, Task>(task, progress, downloadTask));
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var task in downloadTasks)
|
||||||
|
{
|
||||||
|
await task.Item3;
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
await RefreshPlugins(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static async Task<bool> LoadPlugins(string[] args)
|
||||||
|
{
|
||||||
|
var loader = new PluginLoader(Config.DiscordBot.client);
|
||||||
|
if (args.Length == 2 && args[1] == "-q")
|
||||||
|
{
|
||||||
|
loader.LoadPlugins();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
var cc = Console.ForegroundColor;
|
||||||
|
loader.onCMDLoad += (name, typeName, success, exception) =>
|
||||||
|
{
|
||||||
|
if (name == null || name.Length < 2)
|
||||||
|
name = typeName;
|
||||||
|
if (success)
|
||||||
|
{
|
||||||
|
Config.Logger.Log("Successfully loaded command : " + name, source: typeof(ICommandAction),
|
||||||
|
type: LogType.INFO);
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Config.Logger.Log("Failed to load command : " + name + " because " + exception?.Message,
|
||||||
|
source: typeof(ICommandAction), type: LogType.ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
Console.ForegroundColor = cc;
|
||||||
|
};
|
||||||
|
loader.onEVELoad += (name, typeName, success, exception) =>
|
||||||
|
{
|
||||||
|
if (name == null || name.Length < 2)
|
||||||
|
name = typeName;
|
||||||
|
|
||||||
|
if (success)
|
||||||
|
{
|
||||||
|
Config.Logger.Log("Successfully loaded event : " + name, source: typeof(ICommandAction),
|
||||||
|
type: LogType.INFO);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Config.Logger.Log("Failed to load event : " + name + " because " + exception?.Message,
|
||||||
|
source: typeof(ICommandAction), type: LogType.ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
Console.ForegroundColor = cc;
|
||||||
|
};
|
||||||
|
|
||||||
|
loader.onSLSHLoad += (name, typeName, success, exception) =>
|
||||||
|
{
|
||||||
|
if (name == null || name.Length < 2)
|
||||||
|
name = typeName;
|
||||||
|
|
||||||
|
if (success)
|
||||||
|
{
|
||||||
|
Config.Logger.Log("Successfully loaded slash command : " + name, source: typeof(ICommandAction),
|
||||||
|
type: LogType.INFO);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Config.Logger.Log("Failed to load slash command : " + name + " because " + exception?.Message,
|
||||||
|
source: typeof(ICommandAction), type: LogType.ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
Console.ForegroundColor = cc;
|
||||||
|
};
|
||||||
|
|
||||||
|
loader.LoadPlugins();
|
||||||
|
Console.ForegroundColor = cc;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,9 +1,8 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Globalization;
|
|
||||||
using System.Threading;
|
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using DiscordBot.Utilities;
|
using System.Windows.Input;
|
||||||
|
using DiscordBot.Bot.Actions.Extra;
|
||||||
using PluginManager;
|
using PluginManager;
|
||||||
using PluginManager.Interfaces;
|
using PluginManager.Interfaces;
|
||||||
using PluginManager.Loaders;
|
using PluginManager.Loaders;
|
||||||
@@ -40,105 +39,26 @@ public class Plugin : ICommandAction
|
|||||||
switch (args[0])
|
switch (args[0])
|
||||||
{
|
{
|
||||||
case "refresh":
|
case "refresh":
|
||||||
await RefreshPlugins(true);
|
await PluginMethods.RefreshPlugins(true);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "list":
|
case "list":
|
||||||
var data = await ConsoleUtilities.ExecuteWithProgressBar(manager.GetAvailablePlugins(), "Loading plugins...");
|
await PluginMethods.List();
|
||||||
|
|
||||||
TableData tableData = new(new List<string> { "Name", "Description", "Type", "Version" });
|
|
||||||
foreach (var plugin in data) tableData.AddRow(plugin);
|
|
||||||
|
|
||||||
tableData.HasRoundBorders = false;
|
|
||||||
tableData.PrintAsTable();
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
||||||
case "load":
|
case "load":
|
||||||
if (pluginsLoaded)
|
if (pluginsLoaded)
|
||||||
|
{
|
||||||
|
Config.Logger.Log("Plugins already loaded", source: typeof(ICommandAction), type: LogType.WARNING);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (Config.DiscordBot is null)
|
if (Config.DiscordBot is null)
|
||||||
{
|
{
|
||||||
AnsiConsole.MarkupLine("[red]Discord bot not initialized[/]");
|
Config.Logger.Log("DiscordBot is null", source: typeof(ICommandAction), type: LogType.WARNING);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
var loader = new PluginLoader(Config.DiscordBot.client);
|
pluginsLoaded = await PluginMethods.LoadPlugins(args);
|
||||||
if (args.Length == 2 && args[1] == "-q")
|
|
||||||
{
|
|
||||||
Console.WriteLine("Loading plugins in quiet mode...");
|
|
||||||
loader.LoadPlugins();
|
|
||||||
pluginsLoaded = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
var cc = Console.ForegroundColor;
|
|
||||||
loader.onCMDLoad += (name, typeName, success, exception) =>
|
|
||||||
{
|
|
||||||
if (name == null || name.Length < 2)
|
|
||||||
name = typeName;
|
|
||||||
if (success)
|
|
||||||
{
|
|
||||||
Console.ForegroundColor = ConsoleColor.Green;
|
|
||||||
Console.WriteLine("[CMD] Successfully loaded command : " + name);
|
|
||||||
}
|
|
||||||
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Console.ForegroundColor = ConsoleColor.Red;
|
|
||||||
if (exception is null)
|
|
||||||
Console.WriteLine("An error occured while loading: " + name);
|
|
||||||
else
|
|
||||||
Console.WriteLine("[CMD] Failed to load command : " + name + " because " +
|
|
||||||
exception!.Message
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Console.ForegroundColor = cc;
|
|
||||||
};
|
|
||||||
loader.onEVELoad += (name, typeName, success, exception) =>
|
|
||||||
{
|
|
||||||
if (name == null || name.Length < 2)
|
|
||||||
name = typeName;
|
|
||||||
|
|
||||||
if (success)
|
|
||||||
{
|
|
||||||
Console.ForegroundColor = ConsoleColor.Green;
|
|
||||||
Console.WriteLine("[EVENT] Successfully loaded event : " + name);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Console.ForegroundColor = ConsoleColor.Red;
|
|
||||||
Console.WriteLine("[EVENT] Failed to load event : " + name + " because " + exception!.Message);
|
|
||||||
}
|
|
||||||
|
|
||||||
Console.ForegroundColor = cc;
|
|
||||||
};
|
|
||||||
|
|
||||||
loader.onSLSHLoad += (name, typeName, success, exception) =>
|
|
||||||
{
|
|
||||||
if (name == null || name.Length < 2)
|
|
||||||
name = typeName;
|
|
||||||
|
|
||||||
if (success)
|
|
||||||
{
|
|
||||||
Console.ForegroundColor = ConsoleColor.Green;
|
|
||||||
Console.WriteLine("[SLASH] Successfully loaded command : " + name);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Console.ForegroundColor = ConsoleColor.Red;
|
|
||||||
Console.WriteLine("[SLASH] Failed to load command : " + name + " because " +
|
|
||||||
exception!.Message
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Console.ForegroundColor = cc;
|
|
||||||
};
|
|
||||||
|
|
||||||
loader.LoadPlugins();
|
|
||||||
Console.ForegroundColor = cc;
|
|
||||||
pluginsLoaded = true;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "install":
|
case "install":
|
||||||
@@ -155,112 +75,8 @@ public class Plugin : ICommandAction
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
await DownloadPlugin(manager, pluginName);
|
await PluginMethods.DownloadPlugin(manager, pluginName);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task RefreshPlugins(bool quiet)
|
|
||||||
{
|
|
||||||
await Program.internalActionManager.Execute("plugin", "load", quiet ? "-q" : string.Empty);
|
|
||||||
await Program.internalActionManager.Refresh();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public async Task DownloadPlugin(PluginsManager manager, string pluginName)
|
|
||||||
{
|
|
||||||
var pluginData = await manager.GetPluginLinkByName(pluginName);
|
|
||||||
if (pluginData.Length == 0)
|
|
||||||
{
|
|
||||||
Console.WriteLine($"Plugin {pluginName} not found. Please check the spelling and try again.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var pluginType = pluginData[0];
|
|
||||||
var pluginLink = pluginData[1];
|
|
||||||
var pluginRequirements = pluginData[2];
|
|
||||||
|
|
||||||
|
|
||||||
await AnsiConsole.Progress()
|
|
||||||
.Columns(new ProgressColumn[]
|
|
||||||
{
|
|
||||||
new TaskDescriptionColumn(),
|
|
||||||
new ProgressBarColumn(),
|
|
||||||
new PercentageColumn()
|
|
||||||
})
|
|
||||||
.StartAsync(async ctx =>
|
|
||||||
{
|
|
||||||
var downloadTask = ctx.AddTask("Downloading plugin...");
|
|
||||||
|
|
||||||
IProgress<float> progress = new Progress<float>(p => { downloadTask.Value = p; });
|
|
||||||
|
|
||||||
await ServerCom.DownloadFileAsync(pluginLink, $"./Data/{pluginType}s/{pluginName}.dll", progress);
|
|
||||||
|
|
||||||
downloadTask.Increment(100);
|
|
||||||
|
|
||||||
ctx.Refresh();
|
|
||||||
});
|
|
||||||
|
|
||||||
if (pluginRequirements == string.Empty)
|
|
||||||
{
|
|
||||||
Console.WriteLine("Finished installing " + pluginName + " successfully");
|
|
||||||
await RefreshPlugins(false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
List<string> requirementsUrLs = new();
|
|
||||||
|
|
||||||
await AnsiConsole.Progress()
|
|
||||||
.Columns(new ProgressColumn[]
|
|
||||||
{
|
|
||||||
new TaskDescriptionColumn(),
|
|
||||||
new ProgressBarColumn(),
|
|
||||||
new PercentageColumn()
|
|
||||||
})
|
|
||||||
.StartAsync(async ctx =>
|
|
||||||
{
|
|
||||||
var gatherInformationTask = ctx.AddTask("Gathering info...");
|
|
||||||
gatherInformationTask.IsIndeterminate = true;
|
|
||||||
requirementsUrLs = await ServerCom.ReadTextFromURL(pluginRequirements);
|
|
||||||
await Task.Delay(2000);
|
|
||||||
gatherInformationTask.Increment(100);
|
|
||||||
});
|
|
||||||
|
|
||||||
await AnsiConsole.Progress()
|
|
||||||
.Columns(new ProgressColumn[]
|
|
||||||
{
|
|
||||||
new TaskDescriptionColumn(),
|
|
||||||
new ProgressBarColumn(),
|
|
||||||
new PercentageColumn()
|
|
||||||
})
|
|
||||||
.StartAsync(async ctx =>
|
|
||||||
{
|
|
||||||
List<Tuple<ProgressTask, IProgress<float>, Task>> downloadTasks = new();
|
|
||||||
|
|
||||||
foreach (var info in requirementsUrLs)
|
|
||||||
{
|
|
||||||
if (info.Length < 2) continue;
|
|
||||||
string[] data = info.Split(',');
|
|
||||||
string url = data[0];
|
|
||||||
string fileName = data[1];
|
|
||||||
|
|
||||||
var task = ctx.AddTask($"Downloading {fileName}...");
|
|
||||||
IProgress<float> progress = new Progress<float>(p =>
|
|
||||||
{
|
|
||||||
task.Value = p;
|
|
||||||
});
|
|
||||||
|
|
||||||
var downloadTask = ServerCom.DownloadFileAsync(url, $"./{fileName}", progress);
|
|
||||||
downloadTasks.Add(new Tuple<ProgressTask, IProgress<float>, Task>(task, progress, downloadTask));
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var task in downloadTasks)
|
|
||||||
{
|
|
||||||
await task.Item3;
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
await RefreshPlugins(false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -23,6 +23,6 @@ public static class Installer
|
|||||||
|
|
||||||
AnsiConsole.MarkupLine("[bold]Config saved ![/]");
|
AnsiConsole.MarkupLine("[bold]Config saved ![/]");
|
||||||
|
|
||||||
Config.Logger.Log("Config Saved", "Installer", isInternal: true);
|
Config.Logger.Log("Config Saved", source: typeof(Installer));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ using DiscordBot.Utilities;
|
|||||||
using PluginManager.Bot;
|
using PluginManager.Bot;
|
||||||
using PluginManager.Others;
|
using PluginManager.Others;
|
||||||
using PluginManager.Others.Actions;
|
using PluginManager.Others.Actions;
|
||||||
|
using Spectre.Console;
|
||||||
using static PluginManager.Config;
|
using static PluginManager.Config;
|
||||||
|
|
||||||
namespace DiscordBot;
|
namespace DiscordBot;
|
||||||
@@ -80,7 +81,7 @@ public class Program
|
|||||||
}
|
}
|
||||||
catch ( Exception ex )
|
catch ( Exception ex )
|
||||||
{
|
{
|
||||||
Logger.Log(ex.ToString(), "Bot", LogLevel.ERROR);
|
Logger.Log(ex.ToString(), source: typeof(Program), type: LogType.CRITICAL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -107,7 +108,7 @@ public class Program
|
|||||||
|
|
||||||
Logger.Log("An error occured while closing the bot last time. Please consider closing the bot using the &rexit&c method !\n" +
|
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 !",
|
"There is a risk of losing all data or corruption of the save file, which in some cases requires to reinstall the bot !",
|
||||||
"Bot", LogLevel.ERROR);
|
source: typeof(Program), type: LogType.ERROR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -116,19 +117,18 @@ public class Program
|
|||||||
{
|
{
|
||||||
await Initialize();
|
await Initialize();
|
||||||
|
|
||||||
Logger.LogEvent += (message, type, isInternal) =>
|
Logger.OnLog += (sender, logMessage) =>
|
||||||
{
|
{
|
||||||
if (type == LogLevel.INFO)
|
string messageColor = logMessage.Type switch
|
||||||
Console.ForegroundColor = ConsoleColor.Green;
|
{
|
||||||
else if (type == LogLevel.WARNING)
|
LogType.INFO => "[green]",
|
||||||
Console.ForegroundColor = ConsoleColor.DarkYellow;
|
LogType.WARNING => "[yellow]",
|
||||||
else if (type == LogLevel.ERROR)
|
LogType.ERROR => "[red]",
|
||||||
Console.ForegroundColor = ConsoleColor.Red;
|
LogType.CRITICAL => "[red]",
|
||||||
else if (type == LogLevel.CRITICAL)
|
_ => "[white]"
|
||||||
Console.ForegroundColor = ConsoleColor.DarkRed;
|
};
|
||||||
|
|
||||||
Console.WriteLine($"[{type.ToString()}] {message}");
|
AnsiConsole.MarkupLine($"{messageColor}{logMessage.ThrowTime} {logMessage.Message} [/]");
|
||||||
Console.ResetColor();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
AppSettings["Version"] = Assembly.GetExecutingAssembly().GetName().Version.ToString();
|
AppSettings["Version"] = Assembly.GetExecutingAssembly().GetName().Version.ToString();
|
||||||
|
|||||||
@@ -85,9 +85,6 @@ public class Boot
|
|||||||
|
|
||||||
await commandServiceHandler.InstallCommandsAsync();
|
await commandServiceHandler.InstallCommandsAsync();
|
||||||
|
|
||||||
|
|
||||||
await Task.Delay(2000);
|
|
||||||
|
|
||||||
Config._DiscordBotClient = this;
|
Config._DiscordBotClient = this;
|
||||||
|
|
||||||
while (!isReady) ;
|
while (!isReady) ;
|
||||||
@@ -108,8 +105,7 @@ public class Boot
|
|||||||
if (arg.Message.Contains("401"))
|
if (arg.Message.Contains("401"))
|
||||||
{
|
{
|
||||||
Config.AppSettings.Remove("token");
|
Config.AppSettings.Remove("token");
|
||||||
Config.Logger.Log("The token is invalid. Please restart the bot and enter a valid token.", this,
|
Config.Logger.Log("The token is invalid. Please restart the bot and enter a valid token.", source:typeof(Boot), type: LogType.CRITICAL);
|
||||||
LogLevel.ERROR);
|
|
||||||
await Config.AppSettings.SaveToFile();
|
await Config.AppSettings.SaveToFile();
|
||||||
await Task.Delay(4000);
|
await Task.Delay(4000);
|
||||||
Environment.Exit(0);
|
Environment.Exit(0);
|
||||||
@@ -118,7 +114,7 @@ public class Boot
|
|||||||
|
|
||||||
private async Task Client_LoggedOut()
|
private async Task Client_LoggedOut()
|
||||||
{
|
{
|
||||||
Config.Logger.Log("Successfully Logged Out", this);
|
Config.Logger.Log("Successfully Logged Out", source: typeof(Boot));
|
||||||
await Log(new LogMessage(LogSeverity.Info, "Boot", "Successfully logged out from discord !"));
|
await Log(new LogMessage(LogSeverity.Info, "Boot", "Successfully logged out from discord !"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -130,7 +126,7 @@ public class Boot
|
|||||||
|
|
||||||
private Task LoggedIn()
|
private Task LoggedIn()
|
||||||
{
|
{
|
||||||
Config.Logger.Log("Successfully Logged In", this);
|
Config.Logger.Log("Successfully Logged In", source: typeof(Boot));
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -140,13 +136,12 @@ public class Boot
|
|||||||
{
|
{
|
||||||
case LogSeverity.Error:
|
case LogSeverity.Error:
|
||||||
case LogSeverity.Critical:
|
case LogSeverity.Critical:
|
||||||
Config.Logger.Log(message.Message, this, LogLevel.ERROR);
|
Config.Logger.Log(message.Message, source: typeof(Boot), type: LogType.ERROR);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LogSeverity.Info:
|
case LogSeverity.Info:
|
||||||
case LogSeverity.Debug:
|
case LogSeverity.Debug:
|
||||||
Config.Logger.Log(message.Message, this);
|
Config.Logger.Log(message.Message, source: typeof(Boot), type: LogType.INFO);
|
||||||
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ internal class CommandHandler
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Config.Logger.Log(ex.Message, "CommandHandler", LogLevel.ERROR);
|
Config.Logger.Log(ex.Message, type: LogType.ERROR, source: typeof(CommandHandler));
|
||||||
}
|
}
|
||||||
|
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
@@ -145,7 +145,7 @@ internal class CommandHandler
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Config.Logger.Log(ex.Message, this, LogLevel.ERROR);
|
Config.Logger.Log(ex.Message, type: LogType.ERROR, source: typeof(CommandHandler));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ namespace PluginManager;
|
|||||||
public class Config
|
public class Config
|
||||||
{
|
{
|
||||||
private static bool _isLoaded;
|
private static bool _isLoaded;
|
||||||
public static DBLogger? Logger;
|
public static Logger Logger;
|
||||||
public static SettingsDictionary<string, string> AppSettings;
|
public static SettingsDictionary<string, string> AppSettings;
|
||||||
|
|
||||||
internal static Boot? _DiscordBotClient;
|
internal static Boot? _DiscordBotClient;
|
||||||
@@ -30,15 +30,14 @@ public class Config
|
|||||||
AppSettings = new SettingsDictionary<string, string>("./Data/Resources/config.json");
|
AppSettings = new SettingsDictionary<string, string>("./Data/Resources/config.json");
|
||||||
|
|
||||||
AppSettings["LogFolder"] = "./Data/Logs/Logs";
|
AppSettings["LogFolder"] = "./Data/Logs/Logs";
|
||||||
AppSettings["ErrorFolder"] = "./Data/Logs/Errors";
|
|
||||||
|
|
||||||
Logger = new DBLogger(true);
|
Logger = new Logger(false, true);
|
||||||
|
|
||||||
ArchiveManager.Initialize();
|
ArchiveManager.Initialize();
|
||||||
|
|
||||||
_isLoaded = true;
|
_isLoaded = true;
|
||||||
|
|
||||||
Logger.Log("Config initialized", LogLevel.INFO);
|
await Logger.Log(message: "Config initialized", source: typeof(Config));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,17 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
namespace PluginManager.Interfaces.Exceptions;
|
|
||||||
|
|
||||||
public interface IException
|
|
||||||
{
|
|
||||||
public List<string> Messages { get; set; }
|
|
||||||
public bool isFatal { get; }
|
|
||||||
public string GenerateFullMessage();
|
|
||||||
public void HandleException();
|
|
||||||
|
|
||||||
public IException AppendError(string message);
|
|
||||||
|
|
||||||
public IException AppendError(List<string> messages);
|
|
||||||
public IException IsFatal(bool isFatal = true);
|
|
||||||
|
|
||||||
}
|
|
||||||
15
PluginManager/Interfaces/Logger/ILog.cs
Normal file
15
PluginManager/Interfaces/Logger/ILog.cs
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
using System;
|
||||||
|
using PluginManager.Others;
|
||||||
|
|
||||||
|
namespace PluginManager.Interfaces.Logger;
|
||||||
|
|
||||||
|
internal interface ILog
|
||||||
|
{
|
||||||
|
string Message { get; set; }
|
||||||
|
string OutputFile { get; set; }
|
||||||
|
|
||||||
|
Type? Source { get; set; }
|
||||||
|
|
||||||
|
LogType Type { get; set; }
|
||||||
|
DateTime ThrowTime { get; set; }
|
||||||
|
}
|
||||||
17
PluginManager/Interfaces/Logger/ILogger.cs
Normal file
17
PluginManager/Interfaces/Logger/ILogger.cs
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
using System;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using PluginManager.Others;
|
||||||
|
using PluginManager.Others.Logger;
|
||||||
|
|
||||||
|
namespace PluginManager.Interfaces.Logger;
|
||||||
|
|
||||||
|
internal interface ILogger
|
||||||
|
{
|
||||||
|
bool IsEnabled { get; init; }
|
||||||
|
bool OutputToFile { get; init; }
|
||||||
|
|
||||||
|
event EventHandler<Log> OnLog;
|
||||||
|
Task Log(
|
||||||
|
string message = "", string outputFile = "", Type? source = default, LogType type = LogType.INFO,
|
||||||
|
DateTime throwTime = default);
|
||||||
|
}
|
||||||
@@ -53,10 +53,9 @@ internal class Loader
|
|||||||
{
|
{
|
||||||
Assembly.LoadFrom(file);
|
Assembly.LoadFrom(file);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch
|
||||||
{
|
{
|
||||||
Config.Logger.Log("PluginName: " + new FileInfo(file).Name.Split('.')[0] + " not loaded", this,
|
Config.Logger.Log("PluginName: " + new FileInfo(file).Name.Split('.')[0] + " not loaded", source: typeof(Loader), type: LogType.ERROR);
|
||||||
LogLevel.ERROR);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -130,7 +129,7 @@ internal class Loader
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Config.Logger.Log(ex.Message, this, LogLevel.ERROR);
|
Config.Logger.Log(ex.Message, source: typeof(Loader), type: LogType.ERROR);
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -88,11 +88,10 @@ public class PluginLoader
|
|||||||
Events = new List<DBEvent>();
|
Events = new List<DBEvent>();
|
||||||
SlashCommands = new List<DBSlashCommand>();
|
SlashCommands = new List<DBSlashCommand>();
|
||||||
|
|
||||||
Config.Logger.Log("Starting plugin loader ... Client: " + _client.CurrentUser.Username, this,
|
Config.Logger.Log("Starting plugin loader ... Client: " + _client.CurrentUser.Username, source: typeof(PluginLoader), type: LogType.INFO);
|
||||||
LogLevel.INFO);
|
|
||||||
|
|
||||||
var loader = new Loader("./Data/Plugins", "dll");
|
var loader = new Loader("./Data/Plugins", "dll");
|
||||||
loader.FileLoaded += args => Config.Logger.Log($"{args.PluginName} file Loaded", this, LogLevel.INFO);
|
loader.FileLoaded += args => Config.Logger.Log($"{args.PluginName} file Loaded", source: typeof(PluginLoader), type: LogType.INFO);
|
||||||
loader.PluginLoaded += Loader_PluginLoaded;
|
loader.PluginLoaded += Loader_PluginLoaded;
|
||||||
var res = loader.Load();
|
var res = loader.Load();
|
||||||
Events = res.Item1;
|
Events = res.Item1;
|
||||||
@@ -117,7 +116,7 @@ public class PluginLoader
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Config.Logger.Log(ex.Message, this, LogLevel.ERROR);
|
Config.Logger.Log(ex.Message, source: typeof(PluginLoader), type: LogType.ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@@ -151,13 +150,13 @@ public class PluginLoader
|
|||||||
var instance = (DBEvent)Activator.CreateInstance(type);
|
var instance = (DBEvent)Activator.CreateInstance(type);
|
||||||
instance.Start(client);
|
instance.Start(client);
|
||||||
Events.Add(instance);
|
Events.Add(instance);
|
||||||
Config.Logger.Log($"[EVENT] Loaded external {type.FullName}!", LogLevel.INFO);
|
Config.Logger.Log($"[EVENT] Loaded external {type.FullName}!", source: typeof(PluginLoader));
|
||||||
}
|
}
|
||||||
else if (type.IsClass && typeof(DBCommand).IsAssignableFrom(type))
|
else if (type.IsClass && typeof(DBCommand).IsAssignableFrom(type))
|
||||||
{
|
{
|
||||||
var instance = (DBCommand)Activator.CreateInstance(type);
|
var instance = (DBCommand)Activator.CreateInstance(type);
|
||||||
Commands.Add(instance);
|
Commands.Add(instance);
|
||||||
Config.Logger.Log($"[CMD] Instance: {type.FullName} loaded !", LogLevel.INFO);
|
Config.Logger.Log($"[CMD] Instance: {type.FullName} loaded !", source: typeof(PluginLoader));
|
||||||
}
|
}
|
||||||
else if (type.IsClass && typeof(DBSlashCommand).IsAssignableFrom(type))
|
else if (type.IsClass && typeof(DBSlashCommand).IsAssignableFrom(type))
|
||||||
{
|
{
|
||||||
@@ -170,13 +169,13 @@ public class PluginLoader
|
|||||||
|
|
||||||
await client.CreateGlobalApplicationCommandAsync(builder.Build());
|
await client.CreateGlobalApplicationCommandAsync(builder.Build());
|
||||||
SlashCommands.Add(instance);
|
SlashCommands.Add(instance);
|
||||||
Config.Logger.Log($"[SLASH] Instance: {type.FullName} loaded !", LogLevel.INFO);
|
Config.Logger.Log($"[SLASH] Instance: {type.FullName} loaded !", source: typeof(PluginLoader));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
//Console.WriteLine(ex.Message);
|
//Console.WriteLine(ex.Message);
|
||||||
Config.Logger.Error(ex);
|
Config.Logger.Log(ex.Message, source: typeof(PluginLoader), type: LogType.ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -89,8 +89,7 @@ public class PluginsManager
|
|||||||
}
|
}
|
||||||
catch (Exception exception)
|
catch (Exception exception)
|
||||||
{
|
{
|
||||||
Config.Logger.Log("Failed to execute command: listplugs\nReason: " + exception.Message, this,
|
Config.Logger.Log(message: "Failed to execute command: listplugs\nReason: " + exception.Message, source: typeof(PluginsManager), type: LogType.ERROR );
|
||||||
LogLevel.ERROR);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
@@ -142,8 +141,7 @@ public class PluginsManager
|
|||||||
}
|
}
|
||||||
catch (Exception exception)
|
catch (Exception exception)
|
||||||
{
|
{
|
||||||
Config.Logger.Log("Failed to execute command: listplugs\nReason: " + exception.Message, this,
|
Config.Logger.Log("Failed to execute command: plugin list\nReason: " + exception.Message, source: typeof(PluginsManager), type: LogType.ERROR);
|
||||||
LogLevel.ERROR);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ public class InternalActionManager
|
|||||||
{
|
{
|
||||||
if (!Actions.ContainsKey(actionName))
|
if (!Actions.ContainsKey(actionName))
|
||||||
{
|
{
|
||||||
Config.Logger.Log($"Action {actionName} not found", "InternalActionManager", LogLevel.WARNING, true);
|
Config.Logger.Log($"Action {actionName} not found", type: LogType.ERROR, source: typeof(InternalActionManager));
|
||||||
return "Action not found";
|
return "Action not found";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -59,7 +59,7 @@ public class InternalActionManager
|
|||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
Config.Logger.Log(e.Message, "InternalActionManager", LogLevel.ERROR);
|
Config.Logger.Log(e.Message , type: LogType.ERROR, source: typeof(InternalActionManager));
|
||||||
return e.Message;
|
return e.Message;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using System.IO.Compression;
|
using System.IO.Compression;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Runtime.Serialization.Formatters.Binary;
|
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace PluginManager.Others;
|
namespace PluginManager.Others;
|
||||||
@@ -94,7 +93,7 @@ public static class ArchiveManager
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Config.Logger.Log(ex.Message, "Archive Manager", LogLevel.ERROR); // Write the error to a file
|
Config.Logger.Log(message: ex.Message, source: typeof(ArchiveManager), type: LogType.ERROR); // Write the error to a file
|
||||||
await Task.Delay(100);
|
await Task.Delay(100);
|
||||||
return await ReadFromPakAsync(FileName, archFile);
|
return await ReadFromPakAsync(FileName, archFile);
|
||||||
}
|
}
|
||||||
@@ -132,8 +131,7 @@ public static class ArchiveManager
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Config.Logger.Log($"Failed to extract {entry.Name}. Exception: {ex.Message}",
|
Config.Logger.Log(ex.Message, source: typeof(ArchiveManager), type: LogType.ERROR);
|
||||||
"Archive Manager", LogLevel.ERROR);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
currentZIPFile++;
|
currentZIPFile++;
|
||||||
@@ -165,8 +163,7 @@ public static class ArchiveManager
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Config.Logger.Log($"Failed to extract {entry.Name}. Exception: {ex.Message}",
|
Config.Logger.Log(ex.Message, source: typeof(ArchiveManager), type: LogType.ERROR);
|
||||||
"Archive Manager", LogLevel.ERROR);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
await Task.Delay(10);
|
await Task.Delay(10);
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ public enum OperatingSystem
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The output log type
|
/// The output log type
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public enum LogLevel
|
public enum LogType
|
||||||
{
|
{
|
||||||
INFO,
|
INFO,
|
||||||
WARNING,
|
WARNING,
|
||||||
|
|||||||
@@ -1,91 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using PluginManager.Interfaces.Exceptions;
|
|
||||||
|
|
||||||
namespace PluginManager.Others.Exceptions;
|
|
||||||
|
|
||||||
public class ConfigFailedToLoad : IException
|
|
||||||
{
|
|
||||||
public List<string>? Messages { get; set; }
|
|
||||||
public bool isFatal { get; private set; }
|
|
||||||
public string? File { get; }
|
|
||||||
|
|
||||||
|
|
||||||
public ConfigFailedToLoad(string message, bool isFatal, string file)
|
|
||||||
{
|
|
||||||
this.isFatal = isFatal;
|
|
||||||
Messages = new List<string>() {message};
|
|
||||||
this.File = file;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ConfigFailedToLoad(string message, bool isFatal)
|
|
||||||
{
|
|
||||||
this.isFatal = isFatal;
|
|
||||||
Messages = new List<string>() {message};
|
|
||||||
this.File = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ConfigFailedToLoad(string message)
|
|
||||||
{
|
|
||||||
this.isFatal = false;
|
|
||||||
Messages = new List<string>() {message};
|
|
||||||
this.File = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public string GenerateFullMessage()
|
|
||||||
{
|
|
||||||
string messages = "";
|
|
||||||
foreach (var message in Messages)
|
|
||||||
{
|
|
||||||
messages += message + "\n";
|
|
||||||
}
|
|
||||||
return $"\nMessage: {messages}\nIsFatal: {isFatal}\nFile: {File ?? "null"}";
|
|
||||||
}
|
|
||||||
|
|
||||||
public void HandleException()
|
|
||||||
{
|
|
||||||
if (isFatal)
|
|
||||||
{
|
|
||||||
Config.Logger.Log(GenerateFullMessage(), LogLevel.CRITICAL, true);
|
|
||||||
Environment.Exit((int)ExceptionExitCode.CONFIG_FAILED_TO_LOAD);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
Config.Logger.Log(GenerateFullMessage(), LogLevel.WARNING);
|
|
||||||
}
|
|
||||||
|
|
||||||
public IException AppendError(string message)
|
|
||||||
{
|
|
||||||
Messages.Add(message);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public IException AppendError(List<string> messages)
|
|
||||||
{
|
|
||||||
Messages.AddRange(messages);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public IException IsFatal(bool isFatal = true)
|
|
||||||
{
|
|
||||||
this.isFatal = isFatal;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public static ConfigFailedToLoad CreateError(string message, bool isFatal, string? file = null)
|
|
||||||
{
|
|
||||||
if (file is not null)
|
|
||||||
return new ConfigFailedToLoad(message, isFatal, file);
|
|
||||||
return new ConfigFailedToLoad(message, isFatal);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ConfigFailedToLoad CreateError(string message)
|
|
||||||
{
|
|
||||||
return new ConfigFailedToLoad(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,75 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using PluginManager.Interfaces.Exceptions;
|
|
||||||
|
|
||||||
namespace PluginManager.Others.Exceptions;
|
|
||||||
|
|
||||||
public class ConfigNoKeyWasPresent: IException
|
|
||||||
{
|
|
||||||
public List<string> Messages { get; set; }
|
|
||||||
public bool isFatal { get; private set; }
|
|
||||||
|
|
||||||
public ConfigNoKeyWasPresent(string message, bool isFatal)
|
|
||||||
{
|
|
||||||
this.Messages = new List<string>() { message };
|
|
||||||
this.isFatal = isFatal;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ConfigNoKeyWasPresent(string message)
|
|
||||||
{
|
|
||||||
this.Messages = new List<string>() { message };
|
|
||||||
this.isFatal = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public string GenerateFullMessage()
|
|
||||||
{
|
|
||||||
string messages = "";
|
|
||||||
foreach (var message in Messages)
|
|
||||||
{
|
|
||||||
messages += message + "\n";
|
|
||||||
}
|
|
||||||
return $"\nMessage: {messages}\nIsFatal: {isFatal}";
|
|
||||||
}
|
|
||||||
|
|
||||||
public void HandleException()
|
|
||||||
{
|
|
||||||
if (isFatal)
|
|
||||||
{
|
|
||||||
|
|
||||||
Config.Logger.Log(GenerateFullMessage(), LogLevel.CRITICAL, true);
|
|
||||||
Environment.Exit((int)ExceptionExitCode.CONFIG_KEY_NOT_FOUND);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
Config.Logger.Log(GenerateFullMessage(), LogLevel.WARNING);
|
|
||||||
}
|
|
||||||
|
|
||||||
public IException AppendError(string message)
|
|
||||||
{
|
|
||||||
Messages.Add(message);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public IException AppendError(List<string> messages)
|
|
||||||
{
|
|
||||||
Messages.AddRange(messages);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public IException IsFatal(bool isFatal = true)
|
|
||||||
{
|
|
||||||
this.isFatal = isFatal;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ConfigNoKeyWasPresent CreateError(string message)
|
|
||||||
{
|
|
||||||
return new ConfigNoKeyWasPresent(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ConfigNoKeyWasPresent CreateError(string message, bool isFatal)
|
|
||||||
{
|
|
||||||
return new ConfigNoKeyWasPresent(message, isFatal);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,95 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace PluginManager.Others.Logger;
|
|
||||||
|
|
||||||
public class DBLogger
|
|
||||||
{
|
|
||||||
public delegate void LogHandler(string message, LogLevel logType, bool isInternal = false);
|
|
||||||
|
|
||||||
private readonly string _errFolder;
|
|
||||||
|
|
||||||
private readonly string _logFolder;
|
|
||||||
private readonly List<LogMessage> ErrorHistory = new();
|
|
||||||
private readonly List<LogMessage> LogHistory = new();
|
|
||||||
|
|
||||||
private readonly bool _continuousSave;
|
|
||||||
private readonly bool _LogErrorsOnly;
|
|
||||||
|
|
||||||
public DBLogger(bool continuousSave = true, bool logErrorsOnly = true)
|
|
||||||
{
|
|
||||||
_logFolder = Config.AppSettings["LogFolder"];
|
|
||||||
_errFolder = Config.AppSettings["ErrorFolder"];
|
|
||||||
|
|
||||||
_continuousSave = continuousSave;
|
|
||||||
_LogErrorsOnly = logErrorsOnly;
|
|
||||||
}
|
|
||||||
|
|
||||||
public IReadOnlyList<LogMessage> Logs => LogHistory;
|
|
||||||
public IReadOnlyList<LogMessage> Errors => ErrorHistory;
|
|
||||||
|
|
||||||
public event LogHandler? LogEvent;
|
|
||||||
|
|
||||||
public void Log(string message, LogLevel type = LogLevel.INFO)
|
|
||||||
{
|
|
||||||
Log(new LogMessage(message, type));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Log(string message, LogLevel type= LogLevel.INFO, bool isInternal = false)
|
|
||||||
{
|
|
||||||
Log(new LogMessage(message, type,"unknown", isInternal));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Log(string message, string sender = "unknown", LogLevel type = LogLevel.INFO, bool isInternal = false)
|
|
||||||
{
|
|
||||||
Log(new LogMessage(message, type,sender,isInternal));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Log(string message, string sender = "unknown", LogLevel type = LogLevel.INFO)
|
|
||||||
{
|
|
||||||
Log(new LogMessage(message, type, sender));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Error(Exception? e)
|
|
||||||
{
|
|
||||||
Log(e.Message, e.Source, LogLevel.ERROR);
|
|
||||||
}
|
|
||||||
|
|
||||||
private async void Log(LogMessage message)
|
|
||||||
{
|
|
||||||
LogEvent?.Invoke(message.Message, message.Type);
|
|
||||||
|
|
||||||
if (message.Type != LogLevel.ERROR && message.Type != LogLevel.CRITICAL)
|
|
||||||
LogHistory.Add(message);
|
|
||||||
else
|
|
||||||
ErrorHistory.Add(message);
|
|
||||||
|
|
||||||
if (_continuousSave)
|
|
||||||
await SaveToFile();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Log(string message, object sender, LogLevel type = LogLevel.INFO)
|
|
||||||
{
|
|
||||||
Log(message, sender.GetType().Name, type);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task SaveToFile()
|
|
||||||
{
|
|
||||||
await SaveToTxt();
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task SaveToTxt()
|
|
||||||
{
|
|
||||||
if (!_LogErrorsOnly)
|
|
||||||
{
|
|
||||||
var logFile = new LogFile(_logFolder + $"/{DateTime.Today.ToShortDateString().Replace('/', '_')}_log.txt");
|
|
||||||
foreach (var logMessage in LogHistory)
|
|
||||||
logFile.Write(logMessage);
|
|
||||||
}
|
|
||||||
|
|
||||||
var errFile = new LogFile(_errFolder + $"/{DateTime.Today.ToShortDateString().Replace('/', '_')}_err.txt");
|
|
||||||
foreach (var logMessage in ErrorHistory)
|
|
||||||
errFile.Write(logMessage);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
78
PluginManager/Others/Logger/Log.cs
Normal file
78
PluginManager/Others/Logger/Log.cs
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using PluginManager.Interfaces.Logger;
|
||||||
|
|
||||||
|
namespace PluginManager.Others.Logger;
|
||||||
|
|
||||||
|
public class Log : ILog
|
||||||
|
{
|
||||||
|
public string Message { get; set; }
|
||||||
|
public string OutputFile { get; set; }
|
||||||
|
public Type? Source { get; set; }
|
||||||
|
public LogType Type { get; set; }
|
||||||
|
public DateTime ThrowTime { get; set; }
|
||||||
|
|
||||||
|
public Log(string message, string outputFile, Type? source, LogType type, DateTime throwTime)
|
||||||
|
{
|
||||||
|
Message = message;
|
||||||
|
OutputFile = outputFile;
|
||||||
|
Source = source;
|
||||||
|
Type = type;
|
||||||
|
ThrowTime = throwTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Log(string message, string outputFile, Type? source, LogType type)
|
||||||
|
{
|
||||||
|
Message = message;
|
||||||
|
OutputFile = outputFile;
|
||||||
|
Source = source;
|
||||||
|
Type = type;
|
||||||
|
ThrowTime = DateTime.Now;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Log(string message, string outputFile, Type? source)
|
||||||
|
{
|
||||||
|
Message = message;
|
||||||
|
OutputFile = outputFile;
|
||||||
|
Source = source;
|
||||||
|
Type = LogType.INFO;
|
||||||
|
ThrowTime = DateTime.Now;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Log(string message, string outputFile)
|
||||||
|
{
|
||||||
|
Message = message;
|
||||||
|
OutputFile = outputFile;
|
||||||
|
Source = typeof(Log);
|
||||||
|
Type = LogType.INFO;
|
||||||
|
ThrowTime = DateTime.Now;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Log(string message)
|
||||||
|
{
|
||||||
|
Message = message;
|
||||||
|
OutputFile = "";
|
||||||
|
Source = typeof(Log);
|
||||||
|
Type = LogType.INFO;
|
||||||
|
ThrowTime = DateTime.Now;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static implicit operator Log(string message) => new (message);
|
||||||
|
|
||||||
|
public static implicit operator string(Log log) => $"[{log.ThrowTime}] {log.Message}";
|
||||||
|
|
||||||
|
public string AsLongString()
|
||||||
|
{
|
||||||
|
return $"[{ThrowTime}] [{Source}] [{Type}] {Message}";
|
||||||
|
}
|
||||||
|
|
||||||
|
public string AsShortString()
|
||||||
|
{
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string FormatedLongString()
|
||||||
|
{
|
||||||
|
return $"[{ThrowTime}]\t[{Source}]\t\t\t[{Type}]\t{Message}";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
using System.IO;
|
|
||||||
|
|
||||||
namespace PluginManager.Others.Logger;
|
|
||||||
|
|
||||||
public class LogFile
|
|
||||||
{
|
|
||||||
public FileInfo File { get; set; }
|
|
||||||
public LogFile(string path)
|
|
||||||
{
|
|
||||||
File = new FileInfo(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Write(string message)
|
|
||||||
{
|
|
||||||
using var sw = File.AppendText();
|
|
||||||
sw.WriteLine(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Write(string message, LogLevel type)
|
|
||||||
{
|
|
||||||
using var sw = File.AppendText();
|
|
||||||
sw.WriteLine($"[{type}] {message}");
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Write(string message, string sender, LogLevel type)
|
|
||||||
{
|
|
||||||
using var sw = File.AppendText();
|
|
||||||
sw.WriteLine($"[{type}] [{sender}] {message}");
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Write(LogMessage logMessage)
|
|
||||||
{
|
|
||||||
using var sw = File.AppendText();
|
|
||||||
sw.WriteLine(logMessage.ToString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,51 +0,0 @@
|
|||||||
using System;
|
|
||||||
|
|
||||||
namespace PluginManager.Others.Logger;
|
|
||||||
|
|
||||||
public class LogMessage
|
|
||||||
{
|
|
||||||
public LogMessage(string message, LogLevel type)
|
|
||||||
{
|
|
||||||
Message = message;
|
|
||||||
Type = type;
|
|
||||||
Time = DateTime.Now.ToString("HH:mm:ss");
|
|
||||||
isInternal = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public LogMessage(string message, LogLevel type, string sender, bool isInternal) : this(message, type)
|
|
||||||
{
|
|
||||||
Sender = sender;
|
|
||||||
this.isInternal = isInternal;
|
|
||||||
}
|
|
||||||
|
|
||||||
public LogMessage(string message, LogLevel type, string sender) : this (message, type, sender, false)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public string Message { get; set; }
|
|
||||||
public LogLevel Type { get; set; }
|
|
||||||
public string Time { get; set; }
|
|
||||||
public string Sender { get; set; }
|
|
||||||
public bool isInternal { get; set; }
|
|
||||||
|
|
||||||
public override string ToString()
|
|
||||||
{
|
|
||||||
return $"[{Time}] {Message}";
|
|
||||||
}
|
|
||||||
|
|
||||||
public static explicit operator LogMessage(string message)
|
|
||||||
{
|
|
||||||
return new LogMessage(message, LogLevel.INFO);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static explicit operator LogMessage((string message, LogLevel type) tuple)
|
|
||||||
{
|
|
||||||
return new LogMessage(tuple.message, tuple.type);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static explicit operator LogMessage((string message, LogLevel type, string sender) tuple)
|
|
||||||
{
|
|
||||||
return new LogMessage(tuple.message, tuple.type, tuple.sender);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
57
PluginManager/Others/Logger/Logger.cs
Normal file
57
PluginManager/Others/Logger/Logger.cs
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using PluginManager.Interfaces.Logger;
|
||||||
|
|
||||||
|
namespace PluginManager.Others.Logger;
|
||||||
|
|
||||||
|
public sealed class Logger : ILogger
|
||||||
|
{
|
||||||
|
public bool IsEnabled { get; init; }
|
||||||
|
public bool OutputToFile { get; init; }
|
||||||
|
|
||||||
|
public LogType LowestLogLevel { get; set; }
|
||||||
|
private bool UseShortVersion { get; }
|
||||||
|
|
||||||
|
public Logger(bool useShortVersion, bool outputToFile, LogType lowestLogLevel = LogType.INFO)
|
||||||
|
{
|
||||||
|
UseShortVersion = useShortVersion;
|
||||||
|
OutputToFile = outputToFile;
|
||||||
|
IsEnabled = true;
|
||||||
|
LowestLogLevel = lowestLogLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public event EventHandler<Log>? OnLog;
|
||||||
|
|
||||||
|
private async Task Log(Log logMessage)
|
||||||
|
{
|
||||||
|
if (!IsEnabled) return;
|
||||||
|
|
||||||
|
OnLog?.Invoke(this, logMessage);
|
||||||
|
|
||||||
|
if (logMessage.Type < LowestLogLevel) return;
|
||||||
|
|
||||||
|
if (OutputToFile)
|
||||||
|
await File.AppendAllTextAsync(
|
||||||
|
logMessage.OutputFile,
|
||||||
|
(UseShortVersion ? logMessage : logMessage.AsLongString()) + "\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task Log(string message = "", string outputFile = "", Type? source = default, LogType type = LogType.INFO, DateTime throwTime = default)
|
||||||
|
{
|
||||||
|
if (!IsEnabled) return;
|
||||||
|
|
||||||
|
if (type < LowestLogLevel) return;
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(message)) return;
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(outputFile)) outputFile = Config.AppSettings["LogFolder"] + "/" + DateTime.Now.ToString("yyyy-MM-dd") + ".log";
|
||||||
|
|
||||||
|
if(throwTime == default) throwTime = DateTime.Now;
|
||||||
|
|
||||||
|
if (source == default) source = typeof(Log);
|
||||||
|
|
||||||
|
await Log(new Log(message, outputFile, source, type, throwTime));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,7 +2,6 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using PluginManager.Others.Exceptions;
|
|
||||||
|
|
||||||
namespace PluginManager.Others;
|
namespace PluginManager.Others;
|
||||||
|
|
||||||
@@ -16,10 +15,8 @@ public class SettingsDictionary<TKey, TValue> : IDictionary<TKey, TValue>
|
|||||||
_file = file;
|
_file = file;
|
||||||
if (!LoadFromFile())
|
if (!LoadFromFile())
|
||||||
{
|
{
|
||||||
ConfigFailedToLoad.CreateError("Failed to load config")
|
_dictionary = new Dictionary<TKey, TValue>();
|
||||||
.AppendError("The file is empty or does not exist")
|
SaveToFile();
|
||||||
.IsFatal()
|
|
||||||
.HandleException();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -50,10 +47,6 @@ public class SettingsDictionary<TKey, TValue> : IDictionary<TKey, TValue>
|
|||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
ConfigFailedToLoad
|
|
||||||
.CreateError("Failed to load config")
|
|
||||||
.IsFatal()
|
|
||||||
.HandleException();
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -126,11 +119,6 @@ public class SettingsDictionary<TKey, TValue> : IDictionary<TKey, TValue>
|
|||||||
if(this._dictionary[key] is string s && !string.IsNullOrEmpty(s) && !string.IsNullOrWhiteSpace(s))
|
if(this._dictionary[key] is string s && !string.IsNullOrEmpty(s) && !string.IsNullOrWhiteSpace(s))
|
||||||
return this._dictionary[key];
|
return this._dictionary[key];
|
||||||
|
|
||||||
ConfigNoKeyWasPresent.CreateError($"Key {(key is string ? key : typeof(TKey).Name)} was not present in {_file ?? "config"}")
|
|
||||||
.AppendError("Deleting the file may fix this issue")
|
|
||||||
.IsFatal()
|
|
||||||
.HandleException();
|
|
||||||
|
|
||||||
return default!;
|
return default!;
|
||||||
}
|
}
|
||||||
set => this._dictionary![key] = value;
|
set => this._dictionary![key] = value;
|
||||||
|
|||||||
Reference in New Issue
Block a user