Redesigned the DiscordBotCore by splitting it into multiple projects. Created a WebUI and preparing to remove the DiscordBot application
This commit is contained in:
@@ -1,43 +1,53 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using Discord.Commands;
|
||||
using Discord.WebSocket;
|
||||
using DiscordBotCore.Interfaces;
|
||||
using DiscordBotCore.Loaders;
|
||||
using DiscordBotCore.Configuration;
|
||||
using DiscordBotCore.Logging;
|
||||
using DiscordBotCore.Others;
|
||||
using DiscordBotCore.Others.Permissions;
|
||||
using DiscordBotCore.PluginCore.Helpers;
|
||||
using DiscordBotCore.PluginCore.Helpers.Execution.DbCommand;
|
||||
using DiscordBotCore.PluginCore.Interfaces;
|
||||
using DiscordBotCore.PluginManagement.Loading;
|
||||
|
||||
namespace DiscordBotCore.Bot;
|
||||
|
||||
internal class CommandHandler
|
||||
internal class CommandHandler : ICommandHandler
|
||||
{
|
||||
private readonly string _botPrefix;
|
||||
private readonly DiscordSocketClient _client;
|
||||
private readonly CommandService _commandService;
|
||||
private readonly ILogger _logger;
|
||||
private readonly IPluginLoader _pluginLoader;
|
||||
private readonly IConfiguration _configuration;
|
||||
|
||||
/// <summary>
|
||||
/// Command handler constructor
|
||||
/// </summary>
|
||||
/// <param name="client">The discord bot client</param>
|
||||
/// <param name="pluginLoader">The plugin loader</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)
|
||||
/// <param name="logger">The logger</param>
|
||||
public CommandHandler(ILogger logger, IPluginLoader pluginLoader, IConfiguration configuration, CommandService commandService, string botPrefix)
|
||||
{
|
||||
_client = client;
|
||||
_commandService = commandService;
|
||||
_botPrefix = botPrefix;
|
||||
_logger = logger;
|
||||
_pluginLoader = pluginLoader;
|
||||
_configuration = configuration;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The method to initialize all commands
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public async Task InstallCommandsAsync()
|
||||
public async Task InstallCommandsAsync(DiscordSocketClient client)
|
||||
{
|
||||
_client.MessageReceived += MessageHandler;
|
||||
_client.SlashCommandExecuted += Client_SlashCommandExecuted;
|
||||
client.MessageReceived += (message) => MessageHandler(client, message);
|
||||
client.SlashCommandExecuted += Client_SlashCommandExecuted;
|
||||
await _commandService.AddModulesAsync(Assembly.GetEntryAssembly(), null);
|
||||
}
|
||||
|
||||
@@ -45,18 +55,18 @@ internal class CommandHandler
|
||||
{
|
||||
try
|
||||
{
|
||||
var plugin = PluginLoader.SlashCommands.FirstOrDefault(p => p.Name == arg.Data.Name);
|
||||
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);
|
||||
plugin.ExecuteDm(_logger, arg);
|
||||
else plugin.ExecuteServer(_logger, arg);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Application.CurrentApplication.Logger.LogException(ex, this);
|
||||
_logger.LogException(ex, this);
|
||||
}
|
||||
|
||||
return Task.CompletedTask;
|
||||
@@ -67,38 +77,38 @@ internal class CommandHandler
|
||||
/// </summary>
|
||||
/// <param name="Message">The message got from the user in discord chat</param>
|
||||
/// <returns></returns>
|
||||
private async Task MessageHandler(SocketMessage Message)
|
||||
private async Task MessageHandler(DiscordSocketClient socketClient, SocketMessage socketMessage)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (Message.Author.IsBot)
|
||||
if (socketMessage.Author.IsBot)
|
||||
return;
|
||||
|
||||
if (Message as SocketUserMessage == null)
|
||||
if (socketMessage as SocketUserMessage == null)
|
||||
return;
|
||||
|
||||
var message = Message as SocketUserMessage;
|
||||
var message = socketMessage as SocketUserMessage;
|
||||
|
||||
if (message is null)
|
||||
return;
|
||||
|
||||
var argPos = 0;
|
||||
|
||||
if (!message.Content.StartsWith(_botPrefix) && !message.HasMentionPrefix(_client.CurrentUser, ref argPos))
|
||||
if (!message.Content.StartsWith(_botPrefix) && !message.HasMentionPrefix(socketClient.CurrentUser, ref argPos))
|
||||
return;
|
||||
|
||||
var context = new SocketCommandContext(_client, message);
|
||||
var context = new SocketCommandContext(socketClient, message);
|
||||
|
||||
await _commandService.ExecuteAsync(context, argPos, null);
|
||||
|
||||
IDbCommand? plugin;
|
||||
var cleanMessage = "";
|
||||
|
||||
if (message.HasMentionPrefix(_client.CurrentUser, ref argPos))
|
||||
if (message.HasMentionPrefix(socketClient.CurrentUser, ref argPos))
|
||||
{
|
||||
var mentionPrefix = "<@" + _client.CurrentUser.Id + ">";
|
||||
var mentionPrefix = "<@" + socketClient.CurrentUser.Id + ">";
|
||||
|
||||
plugin = PluginLoader.Commands!
|
||||
plugin = _pluginLoader.Commands!
|
||||
.FirstOrDefault(plug => plug.Command ==
|
||||
message.Content.Substring(mentionPrefix.Length + 1)
|
||||
.Split(' ')[0] ||
|
||||
@@ -114,7 +124,7 @@ internal class CommandHandler
|
||||
|
||||
else
|
||||
{
|
||||
plugin = PluginLoader.Commands!
|
||||
plugin = _pluginLoader.Commands!
|
||||
.FirstOrDefault(p => p.Command ==
|
||||
message.Content.Split(' ')[0].Substring(_botPrefix.Length) ||
|
||||
p.Aliases is not null &&
|
||||
@@ -138,21 +148,26 @@ internal class CommandHandler
|
||||
if (split.Length > 1)
|
||||
argsClean = string.Join(' ', split, 1, split.Length - 1).Split(' ');
|
||||
|
||||
DbCommandExecutingArguments cmd = new(context, cleanMessage, split[0], argsClean);
|
||||
DbCommandExecutingArgument cmd = new(_logger,
|
||||
context,
|
||||
cleanMessage,
|
||||
split[0],
|
||||
argsClean,
|
||||
new DirectoryInfo(Path.Combine(_configuration.Get<string>("ResourcesFolder"), plugin.Command)));
|
||||
|
||||
Application.CurrentApplication.Logger.Log(
|
||||
_logger.Log(
|
||||
$"User ({context.User.Username}) from Guild \"{context.Guild.Name}\" executed command \"{cmd.CleanContent}\"",
|
||||
this,
|
||||
LogType.Info
|
||||
);
|
||||
|
||||
if (context.Channel is SocketDMChannel)
|
||||
plugin.ExecuteDm(cmd);
|
||||
else plugin.ExecuteServer(cmd);
|
||||
await plugin.ExecuteDm(cmd);
|
||||
else await plugin.ExecuteServer(cmd);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Application.CurrentApplication.Logger.LogException(ex, this);
|
||||
_logger.LogException(ex, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,57 +1,37 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Threading.Tasks;
|
||||
using Discord;
|
||||
using Discord.Commands;
|
||||
using Discord.WebSocket;
|
||||
using DiscordBotCore.Others;
|
||||
using DiscordBotCore.Configuration;
|
||||
using DiscordBotCore.Logging;
|
||||
using DiscordBotCore.PluginManagement.Loading;
|
||||
|
||||
|
||||
namespace DiscordBotCore.Bot;
|
||||
|
||||
public class DiscordBotApplication
|
||||
public class DiscordBotApplication : IDiscordBotApplication
|
||||
{
|
||||
/// <summary>
|
||||
/// The bot prefix
|
||||
/// </summary>
|
||||
private readonly string _BotPrefix;
|
||||
|
||||
/// <summary>
|
||||
/// The bot token
|
||||
/// </summary>
|
||||
private 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;
|
||||
private static readonly string _DefaultPrefix = ";";
|
||||
|
||||
private CommandHandler _CommandServiceHandler;
|
||||
private CommandService _Service;
|
||||
private readonly ILogger _Logger;
|
||||
private readonly IConfiguration _Configuration;
|
||||
private readonly IPluginLoader _PluginLoader;
|
||||
|
||||
/// <summary>
|
||||
/// Checks if the bot is ready
|
||||
/// </summary>
|
||||
/// <value> true if the bot is ready, otherwise false </value>
|
||||
private bool IsReady { get; set; }
|
||||
|
||||
public DiscordSocketClient Client { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The main Boot constructor
|
||||
/// </summary>
|
||||
/// <param name="botToken">The bot token</param>
|
||||
/// <param name="botPrefix">The bot prefix</param>
|
||||
public DiscordBotApplication(string botToken, string botPrefix)
|
||||
public DiscordBotApplication(ILogger logger, IConfiguration configuration, IPluginLoader pluginLoader)
|
||||
{
|
||||
this._BotPrefix = botPrefix;
|
||||
this._BotToken = botToken;
|
||||
this._Logger = logger;
|
||||
this._Configuration = configuration;
|
||||
this._PluginLoader = pluginLoader;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -68,25 +48,24 @@ public class DiscordBotApplication
|
||||
GatewayIntents = GatewayIntents.All
|
||||
};
|
||||
|
||||
Client = new DiscordSocketClient(config);
|
||||
DiscordSocketClient client = new DiscordSocketClient(config);
|
||||
Client = client;
|
||||
|
||||
_Service = new CommandService();
|
||||
|
||||
Client.Log += Log;
|
||||
Client.LoggedIn += LoggedIn;
|
||||
Client.Ready += Ready;
|
||||
Client.Disconnected += Client_Disconnected;
|
||||
client.Log += Log;
|
||||
client.LoggedIn += LoggedIn;
|
||||
client.Ready += Ready;
|
||||
client.Disconnected += Client_Disconnected;
|
||||
|
||||
await Client.LoginAsync(TokenType.Bot, _BotToken);
|
||||
await client.LoginAsync(TokenType.Bot, _Configuration.Get<string>("token"));
|
||||
|
||||
await Client.StartAsync();
|
||||
await client.StartAsync();
|
||||
|
||||
_CommandServiceHandler = new CommandHandler(Client, _Service, _BotPrefix);
|
||||
_CommandServiceHandler = new CommandHandler(_Logger, _PluginLoader, _Configuration, _Service, _Configuration.Get<string>("prefix", _DefaultPrefix));
|
||||
|
||||
await _CommandServiceHandler.InstallCommandsAsync();
|
||||
|
||||
Application.CurrentApplication.DiscordBotClient = this;
|
||||
await _CommandServiceHandler.InstallCommandsAsync(client);
|
||||
|
||||
// wait for the bot to be ready
|
||||
while (!IsReady)
|
||||
{
|
||||
await Task.Delay(100);
|
||||
@@ -97,38 +76,21 @@ public class DiscordBotApplication
|
||||
{
|
||||
if (arg.Message.Contains("401"))
|
||||
{
|
||||
Application.CurrentApplication.ApplicationEnvironmentVariables.Remove("token");
|
||||
Application.CurrentApplication.Logger.Log("The token is invalid.", this, LogType.Critical);
|
||||
await Application.CurrentApplication.ApplicationEnvironmentVariables.SaveToFile();
|
||||
_Configuration.Set("token", string.Empty);
|
||||
_Logger.Log("The token is invalid.", this, LogType.Critical);
|
||||
await _Configuration.SaveToFile();
|
||||
}
|
||||
}
|
||||
|
||||
private Task Ready()
|
||||
{
|
||||
IsReady = true;
|
||||
|
||||
if (Application.CurrentApplication.ApplicationEnvironmentVariables.ContainsKey("CustomStatus"))
|
||||
{
|
||||
var status = Application.CurrentApplication.ApplicationEnvironmentVariables.GetDictionary<string, string>("CustomStatus");
|
||||
string type = status["Type"];
|
||||
string message = status["Message"];
|
||||
ActivityType activityType = type switch
|
||||
{
|
||||
"Playing" => ActivityType.Playing,
|
||||
"Listening" => ActivityType.Listening,
|
||||
"Watching" => ActivityType.Watching,
|
||||
"Streaming" => ActivityType.Streaming,
|
||||
_ => ActivityType.Playing
|
||||
};
|
||||
Client.SetGameAsync(message, null, activityType);
|
||||
}
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
private Task LoggedIn()
|
||||
{
|
||||
Application.CurrentApplication.Logger.Log("Successfully Logged In", this);
|
||||
_Logger.Log("Successfully Logged In", this);
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
@@ -138,12 +100,12 @@ public class DiscordBotApplication
|
||||
{
|
||||
case LogSeverity.Error:
|
||||
case LogSeverity.Critical:
|
||||
Application.CurrentApplication.Logger.Log(message.Message, this, LogType.Error);
|
||||
_Logger.Log(message.Message, this, LogType.Error);
|
||||
break;
|
||||
|
||||
case LogSeverity.Info:
|
||||
case LogSeverity.Debug:
|
||||
Application.CurrentApplication.Logger.Log(message.Message, this, LogType.Info);
|
||||
_Logger.Log(message.Message, this, LogType.Info);
|
||||
|
||||
|
||||
break;
|
||||
|
||||
13
DiscordBotCore/Bot/ICommandHandler.cs
Normal file
13
DiscordBotCore/Bot/ICommandHandler.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
using System.Threading.Tasks;
|
||||
using Discord.WebSocket;
|
||||
|
||||
namespace DiscordBotCore.Bot;
|
||||
|
||||
internal interface ICommandHandler
|
||||
{
|
||||
/// <summary>
|
||||
/// The method to initialize all commands
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
Task InstallCommandsAsync(DiscordSocketClient client);
|
||||
}
|
||||
14
DiscordBotCore/Bot/IDiscordBotApplication.cs
Normal file
14
DiscordBotCore/Bot/IDiscordBotApplication.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
using System.Threading.Tasks;
|
||||
using Discord.WebSocket;
|
||||
|
||||
namespace DiscordBotCore.Bot;
|
||||
|
||||
public interface IDiscordBotApplication
|
||||
{
|
||||
public DiscordSocketClient Client { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The start method for the bot. This method is used to load the bot
|
||||
/// </summary>
|
||||
Task StartAsync();
|
||||
}
|
||||
Reference in New Issue
Block a user