Renamed PluginManager to DiscordBotCore.

Revamped the Logger
This commit is contained in:
2024-05-12 20:10:52 +03:00
parent 413d465d7f
commit 17147d920d
66 changed files with 529 additions and 556 deletions

153
DiscordBotCore/Bot/Boot.cs Normal file
View File

@@ -0,0 +1,153 @@
using System;
using System.Threading.Tasks;
using Discord;
using Discord.Commands;
using Discord.WebSocket;
using DiscordBotCore.Others;
namespace DiscordBotCore.Bot;
public class Boot
{
/// <summary>
/// The bot prefix
/// </summary>
public readonly string BotPrefix;
/// <summary>
/// The bot token
/// </summary>
public readonly string BotToken;
/// <summary>
/// The bot client
/// </summary>
public DiscordSocketClient Client;
/// <summary>
/// The bot command handler
/// </summary>
private CommandHandler _commandServiceHandler;
/// <summary>
/// The command service
/// </summary>
private CommandService _service;
/// <summary>
/// The main Boot constructor
/// </summary>
/// <param name="botToken">The bot token</param>
/// <param name="botPrefix">The bot prefix</param>
public Boot(string botToken, string botPrefix)
{
this.BotPrefix = botPrefix;
this.BotToken = botToken;
}
/// <summary>
/// Checks if the bot is ready
/// </summary>
/// <value> true if the bot is ready, otherwise false </value>
public bool IsReady { get; private set; }
/// <summary>
/// The start method for the bot. This method is used to load the bot
/// </summary>
/// <param name="config">
/// The discord socket config. If null then the default one will be applied (AlwaysDownloadUsers=true,
/// UseInteractionSnowflakeDate=false, GatewayIntents=GatewayIntents.All)
/// </param>
/// <returns>Task</returns>
public async Task Awake(DiscordSocketConfig? config = null)
{
if (config is null)
config = new DiscordSocketConfig
{
AlwaysDownloadUsers = true,
//Disable system clock checkup (for responses at slash commands)
UseInteractionSnowflakeDate = false,
GatewayIntents = GatewayIntents.All
};
Client = new DiscordSocketClient(config);
_service = new CommandService();
CommonTasks();
await Client.LoginAsync(TokenType.Bot, BotToken);
await Client.StartAsync();
_commandServiceHandler = new CommandHandler(Client, _service, BotPrefix);
await _commandServiceHandler.InstallCommandsAsync();
Application.CurrentApplication.DiscordBotClient = this;
while (!IsReady) ;
}
private void CommonTasks()
{
if (Client == null) return;
Client.LoggedOut += Client_LoggedOut;
Client.Log += Log;
Client.LoggedIn += LoggedIn;
Client.Ready += Ready;
Client.Disconnected += Client_Disconnected;
}
private async Task Client_Disconnected(Exception arg)
{
if (arg.Message.Contains("401"))
{
Application.CurrentApplication.ApplicationEnvironmentVariables.Remove("token");
Application.CurrentApplication.Logger.Log("The token is invalid. Please restart the bot and follow the instructions", typeof(Boot), LogType.CRITICAL);
await Application.CurrentApplication.ApplicationEnvironmentVariables.SaveToFile();
Environment.Exit(0);
}
}
private async Task Client_LoggedOut()
{
Application.CurrentApplication.Logger.Log("Successfully Logged Out", typeof(Boot));
await Log(new LogMessage(LogSeverity.Info, "Boot", "Successfully logged out from discord !"));
}
private Task Ready()
{
IsReady = true;
return Task.CompletedTask;
}
private Task LoggedIn()
{
Application.CurrentApplication.Logger.Log("Successfully Logged In", typeof(Boot));
return Task.CompletedTask;
}
private Task Log(LogMessage message)
{
switch (message.Severity)
{
case LogSeverity.Error:
case LogSeverity.Critical:
Application.CurrentApplication.Logger.Log(message.Message, typeof(Boot), LogType.ERROR);
break;
case LogSeverity.Info:
case LogSeverity.Debug:
Application.CurrentApplication.Logger.Log(message.Message, typeof(Boot), LogType.INFO);
break;
}
return Task.CompletedTask;
}
}

View File

@@ -0,0 +1,158 @@
using System;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
using Discord.Commands;
using Discord.WebSocket;
using DiscordBotCore.Interfaces;
using DiscordBotCore.Loaders;
using DiscordBotCore.Others;
using DiscordBotCore.Others.Permissions;
namespace DiscordBotCore.Bot;
internal class CommandHandler
{
private readonly string _botPrefix;
private readonly DiscordSocketClient _client;
private readonly CommandService _commandService;
/// <summary>
/// Command handler constructor
/// </summary>
/// <param name="client">The discord bot client</param>
/// <param name="commandService">The discord bot command service</param>
/// <param name="botPrefix">The prefix to watch for</param>
public CommandHandler(DiscordSocketClient client, CommandService commandService, string botPrefix)
{
_client = client;
_commandService = commandService;
_botPrefix = botPrefix;
}
/// <summary>
/// The method to initialize all commands
/// </summary>
/// <returns></returns>
public async Task InstallCommandsAsync()
{
_client.MessageReceived += MessageHandler;
_client.SlashCommandExecuted += Client_SlashCommandExecuted;
await _commandService.AddModulesAsync(Assembly.GetEntryAssembly(), null);
}
private Task Client_SlashCommandExecuted(SocketSlashCommand arg)
{
try
{
var plugin = PluginLoader.SlashCommands.FirstOrDefault(p => p.Name == arg.Data.Name);
if (plugin is null)
throw new Exception("Failed to run command !");
if (arg.Channel is SocketDMChannel)
plugin.ExecuteDM(arg);
else plugin.ExecuteServer(arg);
}
catch (Exception ex)
{
Application.CurrentApplication.Logger.LogException(ex, this);
}
return Task.CompletedTask;
}
/// <summary>
/// The message handler for the bot
/// </summary>
/// <param name="Message">The message got from the user in discord chat</param>
/// <returns></returns>
private async Task MessageHandler(SocketMessage Message)
{
try
{
if (Message.Author.IsBot)
return;
if (Message as SocketUserMessage == null)
return;
var message = Message as SocketUserMessage;
if (message is null)
return;
var argPos = 0;
if (!message.Content.StartsWith(_botPrefix) && !message.HasMentionPrefix(_client.CurrentUser, ref argPos))
return;
var context = new SocketCommandContext(_client, message);
await _commandService.ExecuteAsync(context, argPos, null);
DBCommand? plugin;
var cleanMessage = "";
if (message.HasMentionPrefix(_client.CurrentUser, ref argPos))
{
var mentionPrefix = "<@" + _client.CurrentUser.Id + ">";
plugin = PluginLoader.Commands!
.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]
)
);
cleanMessage = message.Content.Substring(mentionPrefix.Length + 1);
}
else
{
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)
)
);
cleanMessage = message.Content.Substring(_botPrefix.Length);
}
if (plugin is null)
return;
if (plugin.requireAdmin && !context.Message.Author.IsAdmin())
return;
var split = cleanMessage.Split(' ');
string[]? argsClean = null;
if (split.Length > 1)
argsClean = string.Join(' ', split, 1, split.Length - 1).Split(' ');
DbCommandExecutingArguments cmd = new(context, cleanMessage, split[0], argsClean);
Application.CurrentApplication.Logger.Log(
$"User ({context.User.Username}) from Guild \"{context.Guild.Name}\" executed command \"{cmd.cleanContent}\"",
typeof(CommandHandler),
LogType.INFO
);
if (context.Channel is SocketDMChannel)
plugin.ExecuteDM(cmd);
else plugin.ExecuteServer(cmd);
}
catch (Exception ex)
{
Application.CurrentApplication.Logger.LogException(ex, this);
}
}
}