diff --git a/.idea/.idea.ChaosBot/.idea/contentModel.xml b/.idea/.idea.ChaosBot/.idea/contentModel.xml index 465b175..d678b00 100644 --- a/.idea/.idea.ChaosBot/.idea/contentModel.xml +++ b/.idea/.idea.ChaosBot/.idea/contentModel.xml @@ -9,7 +9,10 @@ - + + + + diff --git a/ChaosBot/Discord/DBot.cs b/ChaosBot/Discord/DiscordConnect.cs similarity index 92% rename from ChaosBot/Discord/DBot.cs rename to ChaosBot/Discord/DiscordConnect.cs index ec07364..06d1de6 100644 --- a/ChaosBot/Discord/DBot.cs +++ b/ChaosBot/Discord/DiscordConnect.cs @@ -1,16 +1,18 @@ using NLog; using System; +using System.Reflection; using Discord; using Discord.WebSocket; using System.Threading.Tasks; +using Discord.Commands; using Microsoft.Extensions.Configuration; namespace ChaosBot.Discord { - public class DBot + public class DiscordConnect { - public static DiscordSocketClient _client; + private static DiscordSocketClient _client; private static Logger _logger = Program._logger; public static async Task Connect() @@ -25,7 +27,7 @@ namespace ChaosBot.Discord await _client.LoginAsync(TokenType.Bot, Program.Cfg.GetValue("Discord:Token")); await _client.StartAsync(); - + /* * Let's keep the Task open and happy. */ @@ -38,7 +40,6 @@ namespace ChaosBot.Discord } } - private static Task Log(LogMessage msg) { switch (msg.Severity) diff --git a/ChaosBot/Discord/Services/CommandHandler.cs b/ChaosBot/Discord/Services/CommandHandler.cs new file mode 100644 index 0000000..224a434 --- /dev/null +++ b/ChaosBot/Discord/Services/CommandHandler.cs @@ -0,0 +1,96 @@ +using System; +using System.Reflection; +using System.Threading.Tasks; +using Microsoft.Extensions.DependencyInjection; +using Discord; +using Discord.Commands; +using Discord.WebSocket; +using Microsoft.Extensions.Configuration; + +namespace ChaosBot.Discord.Services + { + public class CommandHandler + { + // setup fields to be set later in the constructor + private readonly IConfiguration _config; + private readonly CommandService _commands; + private readonly DiscordSocketClient _client; + private readonly IServiceProvider _services; + + public CommandHandler(IServiceProvider services) + { + // juice up the fields with these services + // since we passed the services in, we can use GetRequiredService to pass them into the fields set earlier + _config = services.GetRequiredService(); + _commands = services.GetRequiredService(); + _client = services.GetRequiredService(); + _services = services; + + // take action when we execute a command + _commands.CommandExecuted += CommandExecutedAsync; + + // take action when we receive a message (so we can process it, and see if it is a valid command) + _client.MessageReceived += MessageReceivedAsync; + } + + public async Task InitializeAsync() + { + // register modules that are public and inherit ModuleBase. + await _commands.AddModulesAsync(Assembly.GetEntryAssembly(), _services); + } + + // this class is where the magic starts, and takes actions upon receiving messages + public async Task MessageReceivedAsync(SocketMessage rawMessage) + { + // ensures we don't process system/other bot messages + if (!(rawMessage is SocketUserMessage message)) + { + return; + } + + if (message.Source != MessageSource.User) + { + return; + } + + // sets the argument position away from the prefix we set + var argPos = 0; + + // get prefix from the configuration file + char prefix = Char.Parse(_config["Prefix"]); + + // determine if the message has a valid prefix, and adjust argPos based on prefix + if (!(message.HasMentionPrefix(_client.CurrentUser, ref argPos) || message.HasCharPrefix(prefix, ref argPos))) + { + return; + } + + var context = new SocketCommandContext(_client, message); + + // execute command if one is found that matches + await _commands.ExecuteAsync(context, argPos, _services); + } + + public async Task CommandExecutedAsync(Optional command, ICommandContext context, IResult result) + { + // if a command isn't found, log that info to console and exit this method + if (!command.IsSpecified) + { + System.Console.WriteLine($"Command failed to execute for [{context.User.Username}] <-> [{result.ErrorReason}]!"); + return; + } + + + // log success to the console and exit this method + if (result.IsSuccess) + { + System.Console.WriteLine($"Command [{command.Value.Name}] executed for -> [{context.User.Username}]"); + return; + } + + + // failure scenario, let's let the user know + await context.Channel.SendMessageAsync($"Sorry, {context.User.Username}... something went wrong -> [{result}]!"); + } + } +} \ No newline at end of file diff --git a/ChaosBot/Program.cs b/ChaosBot/Program.cs index 873365e..f5f6a61 100644 --- a/ChaosBot/Program.cs +++ b/ChaosBot/Program.cs @@ -15,7 +15,9 @@ namespace ChaosBot public static Logger _logger; public static void Main(string[] args) - => new Program().MainFunction().GetAwaiter().GetResult(); + { + new Program().MainFunction().GetAwaiter().GetResult(); + } private async Task MainFunction() { @@ -38,8 +40,8 @@ namespace ChaosBot */ _logger.Info($"Starting Up {Cfg.GetValue("Bot:Name")} v{Cfg.GetValue("Bot:Version")}"); - var DiscordBot = DBot.Connect(); - + + var DiscordBot = DiscordConnect.Connect(); await DiscordBot; } catch (Exception ex)