diff --git a/.idea/.idea.ChaosBot/.idea/contentModel.xml b/.idea/.idea.ChaosBot/.idea/contentModel.xml
index d678b00..192f79c 100644
--- a/.idea/.idea.ChaosBot/.idea/contentModel.xml
+++ b/.idea/.idea.ChaosBot/.idea/contentModel.xml
@@ -10,6 +10,9 @@
+
+
+
diff --git a/ChaosBot/Discord/DiscordConnect.cs b/ChaosBot/Discord/DiscordConnect.cs
index 06d1de6..301a003 100644
--- a/ChaosBot/Discord/DiscordConnect.cs
+++ b/ChaosBot/Discord/DiscordConnect.cs
@@ -1,11 +1,14 @@
using NLog;
using System;
-using System.Reflection;
using Discord;
+using Discord.Net;
+using Discord.Commands;
+using System.Reflection;
using Discord.WebSocket;
using System.Threading.Tasks;
-using Discord.Commands;
+using ChaosBot.Discord.Services;
using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.DependencyInjection;
namespace ChaosBot.Discord
@@ -15,31 +18,58 @@ namespace ChaosBot.Discord
private static DiscordSocketClient _client;
private static Logger _logger = Program._logger;
- public static async Task Connect()
+ public static async Task StartUp()
{
try
{
- /*
- * Perform Connection
- */
- _client = new DiscordSocketClient();
- _client.Log += Log;
-
- await _client.LoginAsync(TokenType.Bot, Program.Cfg.GetValue("Discord:Token"));
- await _client.StartAsync();
-
- /*
- * Let's keep the Task open and happy.
- */
- await Task.Delay(-1);
+ using (var services = ConfigureServices())
+ {
+ // get the client and assign to client
+ // you get the services via GetRequiredService
+ var client = services.GetRequiredService();
+ _client = client;
+ // setup logging and the ready event
+ client.Log += Log;
+ client.Ready += ReadyAsync;
+ services.GetRequiredService().Log += Log;
+
+ // this is where we get the Token value from the configuration file, and start the bot
+ await client.LoginAsync(TokenType.Bot, Program.Cfg.GetValue("Discord:Token"));
+ await client.StartAsync();
+
+ // we get the CommandHandler class here and call the InitializeAsync method to start things up for the CommandHandler service
+ await services.GetRequiredService().InitializeAsync();
+
+ await Task.Delay(-1);
+ }
}
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()
+ .AddSingleton()
+ .AddSingleton()
+ .BuildServiceProvider();
+ }
+
private static Task Log(LogMessage msg)
{
switch (msg.Severity)
diff --git a/ChaosBot/Discord/Modules/ExampleCommand.cs b/ChaosBot/Discord/Modules/ExampleCommand.cs
new file mode 100644
index 0000000..af835f2
--- /dev/null
+++ b/ChaosBot/Discord/Modules/ExampleCommand.cs
@@ -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();
+
+ // 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());
+ }
+ }
+}
\ No newline at end of file
diff --git a/ChaosBot/Program.cs b/ChaosBot/Program.cs
index f5f6a61..6c86185 100644
--- a/ChaosBot/Program.cs
+++ b/ChaosBot/Program.cs
@@ -1,9 +1,7 @@
using NLog;
using System;
-using Discord;
-using Discord.WebSocket;
-using System.Threading.Tasks;
using ChaosBot.Discord;
+using System.Threading.Tasks;
using Microsoft.Extensions.Configuration;
@@ -13,8 +11,8 @@ namespace ChaosBot
{
public static IConfiguration Cfg { get; set; }
public static Logger _logger;
-
- public static void Main(string[] args)
+
+ private static void Main(string[] args)
{
new Program().MainFunction().GetAwaiter().GetResult();
}
@@ -40,9 +38,8 @@ namespace ChaosBot
*/
_logger.Info($"Starting Up {Cfg.GetValue("Bot:Name")} v{Cfg.GetValue("Bot:Version")}");
-
- var DiscordBot = DiscordConnect.Connect();
- await DiscordBot;
+ var discordBot = DiscordConnect.StartUp();
+ await discordBot;
}
catch (Exception ex)
{
diff --git a/ChaosBot/appsettings.json b/ChaosBot/appsettings.json
index b9f31ee..d74e236 100644
--- a/ChaosBot/appsettings.json
+++ b/ChaosBot/appsettings.json
@@ -6,7 +6,8 @@
"Discord": {
"Secret": "TPtJeNzPXPM0vptm3igbh8_G3KEfbPdA",
"ClientID": "717523478890414090",
- "Token": "NzE3NTIzNDc4ODkwNDE0MDkw.XtbkDw.RpsISqttv27m2Pknq3c5nEVvXWg"
+ "Token": "NzE3NTIzNDc4ODkwNDE0MDkw.XtbkDw.RpsISqttv27m2Pknq3c5nEVvXWg",
+ "Prefix": "!"
},
"NLog": {
"internalLogLevel": "Info",