Adding CommandHandler

This commit is contained in:
Sean "Solao Bajiuik" Stoves 2020-06-02 21:35:21 -04:00
parent d23f00c94c
commit 64b6f39033
5 changed files with 166 additions and 26 deletions

View File

@ -10,6 +10,9 @@
<e p="ChaosBot.csproj" t="IncludeRecursive" /> <e p="ChaosBot.csproj" t="IncludeRecursive" />
<e p="Discord" t="Include"> <e p="Discord" t="Include">
<e p="DiscordConnect.cs" t="Include" /> <e p="DiscordConnect.cs" t="Include" />
<e p="Modules" t="Include">
<e p="ExampleCommand.cs" t="Include" />
</e>
<e p="Services" t="Include"> <e p="Services" t="Include">
<e p="CommandHandler.cs" t="Include" /> <e p="CommandHandler.cs" t="Include" />
</e> </e>

View File

@ -1,11 +1,14 @@
using NLog; using NLog;
using System; using System;
using System.Reflection;
using Discord; using Discord;
using Discord.Net;
using Discord.Commands;
using System.Reflection;
using Discord.WebSocket; using Discord.WebSocket;
using System.Threading.Tasks; using System.Threading.Tasks;
using Discord.Commands; using ChaosBot.Discord.Services;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
namespace ChaosBot.Discord namespace ChaosBot.Discord
@ -15,31 +18,58 @@ namespace ChaosBot.Discord
private static DiscordSocketClient _client; private static DiscordSocketClient _client;
private static Logger _logger = Program._logger; private static Logger _logger = Program._logger;
public static async Task Connect() public static async Task StartUp()
{ {
try try
{ {
/* using (var services = ConfigureServices())
* Perform Connection {
*/ // get the client and assign to client
_client = new DiscordSocketClient(); // you get the services via GetRequiredService<T>
_client.Log += Log; var client = services.GetRequiredService<DiscordSocketClient>();
_client = client;
await _client.LoginAsync(TokenType.Bot, Program.Cfg.GetValue<string>("Discord:Token")); // setup logging and the ready event
await _client.StartAsync(); client.Log += Log;
client.Ready += ReadyAsync;
services.GetRequiredService<CommandService>().Log += Log;
/* // this is where we get the Token value from the configuration file, and start the bot
* Let's keep the Task open and happy. await client.LoginAsync(TokenType.Bot, Program.Cfg.GetValue<string>("Discord:Token"));
*/ await client.StartAsync();
await Task.Delay(-1);
// we get the CommandHandler class here and call the InitializeAsync method to start things up for the CommandHandler service
await services.GetRequiredService<CommandHandler>().InitializeAsync();
await Task.Delay(-1);
}
} }
catch (Exception ex) catch (Exception ex)
{ {
_logger.Error($"dBot.Connect: Exception [{ex}] thrown, <[{ex.Message}]>."); _logger.Error($"DiscordConnect.StartUp: Exception [{ex}] thrown, <[{ex.Message}]>.");
} }
} }
private static Task ReadyAsync()
{
_logger.Info($"Connected as -> [{_client.CurrentUser}] :)");
return Task.CompletedTask;
}
private static ServiceProvider ConfigureServices()
{
// this returns a ServiceProvider that is used later to call for those services
// we can add types we have access to here, hence adding the new using statement:
// using csharpi.Services;
// the config we build is also added, which comes in handy for setting the command prefix!
return new ServiceCollection()
.AddSingleton(Program.Cfg)
.AddSingleton<DiscordSocketClient>()
.AddSingleton<CommandService>()
.AddSingleton<CommandHandler>()
.BuildServiceProvider();
}
private static Task Log(LogMessage msg) private static Task Log(LogMessage msg)
{ {
switch (msg.Severity) switch (msg.Severity)

View File

@ -0,0 +1,109 @@
using System;
using Discord;
using System.Text;
using Discord.Commands;
using System.Threading.Tasks;
using System.Collections.Generic;
namespace ChaosBot.Discord.Modules
{
// for commands to be available, and have the Context passed to them, we must inherit ModuleBase
public class ExampleCommands : ModuleBase
{
[Command("hello")]
public async Task HelloCommand()
{
// initialize empty string builder for reply
var sb = new StringBuilder();
// get user info from the Context
var user = Context.User;
// build out the reply
sb.AppendLine($"You are -> [{user.Username}]");
sb.AppendLine("I must now say, World!");
// send simple string reply
await ReplyAsync(sb.ToString());
}
[Command("8ball")]
[Alias("ask")]
[RequireUserPermission(GuildPermission.KickMembers)]
public async Task AskEightBall([Remainder]string args = null)
{
// I like using StringBuilder to build out the reply
var sb = new StringBuilder();
// let's use an embed for this one!
var embed = new EmbedBuilder();
// now to create a list of possible replies
var replies = new List<string>();
// add our possible replies
replies.Add("yes");
replies.Add("no");
replies.Add("maybe");
replies.Add("hazzzzy....");
// time to add some options to the embed (like color and title)
embed.WithColor(new Color(0, 255,0));
embed.Title = "Welcome to the 8-ball!";
// we can get lots of information from the Context that is passed into the commands
// here I'm setting up the preface with the user's name and a comma
sb.AppendLine($"{Context.User.Username},");
sb.AppendLine();
// let's make sure the supplied question isn't null
if (args == null)
{
// if no question is asked (args are null), reply with the below text
sb.AppendLine("Sorry, can't answer a question you didn't ask!");
}
else
{
// if we have a question, let's give an answer!
// get a random number to index our list with (arrays start at zero so we subtract 1 from the count)
var answer = replies[new Random().Next(replies.Count - 1)];
// build out our reply with the handy StringBuilder
sb.AppendLine($"You asked: [**{args}**]...");
sb.AppendLine();
sb.AppendLine($"...your answer is [**{answer}**]");
// bonus - let's switch out the reply and change the color based on it
switch (answer)
{
case "yes":
{
embed.WithColor(new Color(0, 255, 0));
break;
}
case "no":
{
embed.WithColor(new Color(255, 0, 0));
break;
}
case "maybe":
{
embed.WithColor(new Color(255,255,0));
break;
}
case "hazzzzy....":
{
embed.WithColor(new Color(255,0,255));
break;
}
}
}
// now we can assign the description of the embed to the contents of the StringBuilder we created
embed.Description = sb.ToString();
// this will reply with the embed
await ReplyAsync(null, false, embed.Build());
}
}
}

View File

@ -1,9 +1,7 @@
using NLog; using NLog;
using System; using System;
using Discord;
using Discord.WebSocket;
using System.Threading.Tasks;
using ChaosBot.Discord; using ChaosBot.Discord;
using System.Threading.Tasks;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
@ -14,7 +12,7 @@ namespace ChaosBot
public static IConfiguration Cfg { get; set; } public static IConfiguration Cfg { get; set; }
public static Logger _logger; public static Logger _logger;
public static void Main(string[] args) private static void Main(string[] args)
{ {
new Program().MainFunction().GetAwaiter().GetResult(); new Program().MainFunction().GetAwaiter().GetResult();
} }
@ -40,9 +38,8 @@ namespace ChaosBot
*/ */
_logger.Info($"Starting Up {Cfg.GetValue<string>("Bot:Name")} v{Cfg.GetValue<string>("Bot:Version")}"); _logger.Info($"Starting Up {Cfg.GetValue<string>("Bot:Name")} v{Cfg.GetValue<string>("Bot:Version")}");
var discordBot = DiscordConnect.StartUp();
var DiscordBot = DiscordConnect.Connect(); await discordBot;
await DiscordBot;
} }
catch (Exception ex) catch (Exception ex)
{ {

View File

@ -6,7 +6,8 @@
"Discord": { "Discord": {
"Secret": "TPtJeNzPXPM0vptm3igbh8_G3KEfbPdA", "Secret": "TPtJeNzPXPM0vptm3igbh8_G3KEfbPdA",
"ClientID": "717523478890414090", "ClientID": "717523478890414090",
"Token": "NzE3NTIzNDc4ODkwNDE0MDkw.XtbkDw.RpsISqttv27m2Pknq3c5nEVvXWg" "Token": "NzE3NTIzNDc4ODkwNDE0MDkw.XtbkDw.RpsISqttv27m2Pknq3c5nEVvXWg",
"Prefix": "!"
}, },
"NLog": { "NLog": {
"internalLogLevel": "Info", "internalLogLevel": "Info",