Command Manager - koreanpanda345/Discord_Net_Example GitHub Wiki

Command Manager

What is a Command Manager? Just how it sounds it manages all commands. this will benefit your code, and such later on, and is actually prefer to use in a lot of languages such as Java, C#, Js, Rust, etc. So how does one make a command manager? well first thing we need to do is make a new file called Command manager. while we are at it, lets remake the entire bot. lets make the Program file do as little as it can to increase runtime.

Why does making a file to do less affect runtime?

The answer is vague, but is understanding. computers are similar to humans. computers are experts at multitasking, but just like humans when we are giving a lot of things to do at once, we have to increase amount of time we spend on one thing, computers do this as well. So, we will use the principle of humans and do the only logical thing, which is ask someone else to help us with them. This is what makes runtime slightly faster, you're asking others to do stuff for you, allowing you to do other task.

Anyways lets do the Program file. we are going to remove everything in the class, except for the main method. we can remove all the dependencies except the System on.

Next lets make a new file. you can call this whatever you want, preferable to be either Bot, or your bot name. I am going to refer to it as the Bot file. make sure to put public in front of the class keyword, we will need to access the class later on. next we are going to add our dependencies:

using System.Threading.Task;
using Discord;
using Discord.Commands;
using Discord.Websocket;

neat, let's make two variables:

private DiscordSocketClient client;
private CommandService command;

so I already explain the DiscordSocketClient, but let me explain the CommandService. CommandService will allow us to use the command manager, it also allows us to use the SocketCommandContext Macros later on in the commands.

next we need to make the configs for them, lets make a constructor, remember that my class is called Bot, your constructor name is what the class name is.

public Bot()
{
  client = new DiscordSocketClient(new DiscordSocketConfig
  {
      LogLevel = LogSeverity.Debug
  });
  command = new CommandService(new CommandServiceConfig
  {
      LogLevel = LogSeverity.Debug,
      CaseSensitiveCommands = true,
      DefaultRunMode = RunMode.Async
   });
}

So we already know what LogLevel does. But what about the other two? CaseSensitiveCommands will make all commands to be case sensitive. DefaultRunMode will set what the commands will default to, we want it to be async to allow us to do multiple things at once.

next we need to make the MainAsync Method

public async Task MainAsync(){

}

now go back to the Program.cs file, and change the main method to look something like this:

static void Main(string[] args)
  => new Bot().MainAsync().GetAwaiter().GetResult();

this will call on the MainAsync when the program file is executed.

Go back to the Bot file, and make two new variables

private string token = "<YOUR_TOKEN>";
private string prefix = "<YOUR_PREFIX>";

replace <YOUR_TOKEN> with your bot token, and <YOUR_PREFIX> with your prefix.

next lets work in the MainAsync method. we need to do a few things here.

client.Log += Log_Event;
client.Ready += Ready_Event;
await client.LoginAsync(TokenType.Bot, token);
await client.StartAsync();
await Taks.Delay(-1);

We are making two Events, Log_Event, and Ready_Event. You can look at the Basics page to see how to set them up.

next Lets make the Command Manager. Make a new file called CommandManager.cs we will need a few things in here:

using System.Threading.Task;
using System.Linq;
using System.Reflection;
using Discord;
using Discord.Commands;
using Discord.Websocket;

make the class public. next we are going to make two variables:

private readonly DiscordSocketClient client;
private readonly CommandService command;

seems familiar right? well thats because it is, we are going to pass them from the Bot file to the CommandManger.

Next lets make the constructor.

public CommandManager(DiscordSocketClient client, CommandService command)
{

}

neat next we are going to make the variables equal the actual parameters.

this.client = client;
this.command = command;

What are Actual Parameters?

The answer is really simple, so simple it is more simple if we explain what formal parameters are. Formal Parameters is what your asking. kind of like formally asking someone if you can use their pencil or something. then we have Actual parameters. these are what your actually using. you can think of it like Formally asking, and Actually using for the different types of parameters.

we are done, lets go back to the Bot File and pass these variables in. in the MainAsync method add:

CommandManager cmdManager = new CommandManger(client, command);

neat we made a connection between the two files, lets go back to the CommandManger file.

lets make a method called InitAsync()

public async Task InitAsync()
{

}

go back to the Bot file, and just under the declaration of the cmdManager add:

await cmdManager.InitAsync();

ok we are done in the Bot File, lets finish the CommandManager file.

in the CommandManager, inside the InitAsync method lets add the following.

client.MessageReceived += Message_Event;
command.Log += Log_Event;

cool, we are almost done here, lets do the Log_Event first;

Console.WriteLine($"{DateTime.Now} at {arg.Source}] - {arg.Message}");
return Task.CompletedTask;

ok next we are going to do the Message_Event, make it async. and change the parameter name to be MessageParam. lets add the following in:

var Message = MessageParam as SocketUserMessage;
            var Context = new SocketCommandContext(Client, Message);

            if (Context.Message == null || Context.Message.Content == "") return;
            if (Context.User.IsBot) return;

            int ArgsPos = 0;
            if (!(Message.HasStringPrefix("+", ref ArgsPos) || Message.HasMentionPrefix(Client.CurrentUser, ref ArgsPos))) return;

            var Result = await Commands.ExecuteAsync(Context, ArgsPos, null);
            if (!Result.IsSuccess && Result.Error != CommandError.UnknownCommand)
            {
                Console.WriteLine($"{DateTime.Now} at Command: {Commands.Search(Context, ArgsPos).Commands[0].Command.Name} in {Commands.Search(Context, ArgsPos).Commands[0].Command.Module.Name}] {Result.ErrorReason}");
                var embed = new EmbedBuilder();
                embed.WithTitle("***ERROR***);
                if (Result.ErrorReason == "The input text has too few parameters.")
                    embed.WithDescription("This command requires something check help command to see what it needs,");
                else
                    embed.WithDescription(Result.ErrorReason);
                
                await Context.Channel.SendMessageAsync("", embed: embed.Build());
            }

Neat we are done. lets make a command. first thing is first we need to make a Core folder. Then a Command Folder.

alright lets make a new Class called Miscellaneous. neat lets add stuff we need:

using System.Threading.Task;
using Discord;
using Discord.Commands;

alright we need to modify the class, so lets make it look like this:

public class Miscellaneous : ModuleBase<SocketCommandContext>

neat all we need to do is make the command. add the following:

[Command("latency")]
[Alias("ping")]
[Summary("This Displays the bot's current latency)]
public async Task PingCommand()
{
   await Context.Channel.SendMessageAsync($"Pong! Bot's Latency is {Context.Client.Latency} ms");
}

there you go. lets break it down now [Command("latency")] is a Macro, or called tag. This will set the command name. [Alias("ping")] is another Macro, this will create our aliases list, which we can add more like so: [Alias("1", "2", "3")]. [Summary("This Displays the bot's current latency")] is a Macro as well, and sets the description for the command. the Method name can be anything you want.

now all is left is for you to test it, and make more commands.

⚠️ **GitHub.com Fallback** ⚠️