184 lines
6.4 KiB
C#
184 lines
6.4 KiB
C#
using System;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Reflection;
|
|
using System.Threading.Tasks;
|
|
|
|
using Discord.Commands;
|
|
using Discord.WebSocket;
|
|
using DiscordBotCore.Configuration;
|
|
using DiscordBotCore.Logging;
|
|
using DiscordBotCore.Others;
|
|
using DiscordBotCore.PluginCore.Helpers;
|
|
using DiscordBotCore.PluginCore.Helpers.Execution.DbCommand;
|
|
using DiscordBotCore.PluginCore.Interfaces;
|
|
using DiscordBotCore.PluginManagement.Loading;
|
|
|
|
namespace DiscordBotCore.Bot;
|
|
|
|
internal class CommandHandler : ICommandHandler
|
|
{
|
|
private static readonly string _DefaultPrefix = ";";
|
|
|
|
private readonly CommandService _commandService;
|
|
private readonly ILogger _logger;
|
|
private readonly IPluginLoader _pluginLoader;
|
|
private readonly IConfiguration _configuration;
|
|
|
|
/// <summary>
|
|
/// Command handler constructor
|
|
/// </summary>
|
|
/// <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>
|
|
/// <param name="logger">The logger</param>
|
|
public CommandHandler(ILogger logger, IPluginLoader pluginLoader, IConfiguration configuration, CommandService commandService)
|
|
{
|
|
_commandService = commandService;
|
|
_logger = logger;
|
|
_pluginLoader = pluginLoader;
|
|
_configuration = configuration;
|
|
}
|
|
|
|
/// <summary>
|
|
/// The method to initialize all commands
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public async Task InstallCommandsAsync(DiscordSocketClient client)
|
|
{
|
|
client.MessageReceived += (message) => MessageHandler(client, message);
|
|
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(_logger, arg);
|
|
else plugin.ExecuteServer(_logger, arg);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_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(DiscordSocketClient socketClient, SocketMessage socketMessage)
|
|
{
|
|
try
|
|
{
|
|
if (socketMessage.Author.IsBot)
|
|
return;
|
|
|
|
if (socketMessage as SocketUserMessage == null)
|
|
return;
|
|
|
|
var message = socketMessage as SocketUserMessage;
|
|
|
|
if (message is null)
|
|
return;
|
|
|
|
var argPos = 0;
|
|
|
|
string botPrefix = this._configuration.Get<string>("prefix", _DefaultPrefix);
|
|
|
|
if (!message.Content.StartsWith(botPrefix) && !message.HasMentionPrefix(socketClient.CurrentUser, ref argPos))
|
|
return;
|
|
|
|
var context = new SocketCommandContext(socketClient, message);
|
|
|
|
await _commandService.ExecuteAsync(context, argPos, null);
|
|
|
|
IDbCommand? plugin;
|
|
var cleanMessage = "";
|
|
|
|
if (message.HasMentionPrefix(socketClient.CurrentUser, ref argPos))
|
|
{
|
|
var mentionPrefix = "<@" + socketClient.CurrentUser.Id + ">";
|
|
|
|
plugin = _pluginLoader.Commands!
|
|
.FirstOrDefault(plug => plug.Command ==
|
|
message.Content.Substring(mentionPrefix.Length + 1)
|
|
.Split(' ')[0] ||
|
|
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.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(' ');
|
|
}
|
|
|
|
DbCommandExecutingArgument cmd = new(_logger,
|
|
context,
|
|
cleanMessage,
|
|
split[0],
|
|
argsClean,
|
|
new DirectoryInfo(Path.Combine(_configuration.Get<string>("ResourcesFolder"), plugin.Command)));
|
|
|
|
_logger.Log(
|
|
$"User ({context.User.Username}) from Guild \"{context.Guild.Name}\" executed command \"{cmd.CleanContent}\"",
|
|
this,
|
|
LogType.Info
|
|
);
|
|
|
|
if (context.Channel is SocketDMChannel)
|
|
{
|
|
await plugin.ExecuteDm(cmd);
|
|
}
|
|
else
|
|
{
|
|
await plugin.ExecuteServer(cmd);
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogException(ex, this);
|
|
}
|
|
}
|
|
}
|