Reputation: 150
So I THINK I know what may be the problem but I'm unsure how to go about fixing it. I'm very new to C# coding. I've been coding Discord bots in node for over a year now so switching over is kinda difficult. I'm following the instructions from the Discord.NET documentations and guide. Here is the code in the Program file
using System;
using System.Threading.Tasks;
using Discord;
using Discord.WebSocket;
namespace GalacticBot
{
class MainClass
{
public static void Main(string[] args) => new MainClass().MainAsync().GetAwaiter().GetResult();
private DiscordSocketClient client;
// Calls the class holding information
private Config config = new Config();
public async Task MainAsync()
{
client = new DiscordSocketClient();
// Logs to console
client.Log += Log;
// Uses the token to start the bot
await client.LoginAsync(TokenType.Bot, config.TestToken);
await client.StartAsync();
await Task.Delay(-1);
}
private Task Log(LogMessage msg)
{
Console.WriteLine(msg.ToString());
return Task.CompletedTask;
}
}
}
Here is the code in the CommandHandler file
using System;
using System.Reflection;
using System.Threading.Tasks;
using Discord;
using Discord.Commands;
using Discord.WebSocket;
namespace GalacticBot
{
public class CommandHandler
{
private readonly DiscordSocketClient client;
private readonly CommandService commands;
private readonly Config config = new Config();
public CommandHandler(DiscordSocketClient _client, CommandService _commands)
{
client = _client;
commands = _commands;
}
public async Task InstallCommandsAsync()
{
client.MessageReceived += HandleCommandAsync;
await commands.AddModulesAsync(assembly: Assembly.GetEntryAssembly(), services: null);
}
private async Task HandleCommandAsync(SocketMessage MessageParam)
{
var message = MessageParam as SocketUserMessage;
if (message == null) return;
int ArgPos = 0;
// If there's no prefix or the message is from a bot then nothing happens
if (!(message.HasCharPrefix('!', ref ArgPos) || message.HasMentionPrefix(client.CurrentUser, ref ArgPos)) || message.Author.IsBot) return;
var context = new SocketCommandContext(client, message);
await commands.ExecuteAsync(
context: context,
argPos: ArgPos,
services: null
);
}
}
}
and here is the code for the commands themselves
using System;
using System.Threading.Tasks;
using Discord.Commands;
public class Hi : ModuleBase<SocketCommandContext>
{
[Command("hey")]
[Summary("Just says hi.")]
public async Task SayAsync()
{
Console.WriteLine("Command used");
await Context.Channel.SendMessageAsync("Just saying hi!");
}
}
The Console.WriteLine in the command is for testing purposes to see if it's even attempting to work. My thought is that I'm not calling and using the CommandHandler class anywhere. I don't know if this is the problem and if it is, I don't know what I need to do.
Upvotes: 0
Views: 2665
Reputation: 150
After a lot more Googling and trying a bunch of different ideas, I finally found a solution. Anu6is was right in that you have to create a new instance and call the install method. This led to returning null when starting the bot. First I made a variable for commands and made it static with the _client variable as well as making a variable for the CommandHandler
private static DiscordSocketClient _client;
private static CommandService _commands;
private CommandHandler commandHandler;
Inside MainAsync I had to create a new instance of the CommandService, a new instance of the command handler passing _client and _commands and then call the InstallCommandsAsync method
_commands = new CommandService();
commandHandler = new CommandHandler(_client, _commands);
await commandHandler.InstallCommandsAsync();
After the changes, build came back successful with no warnings and the test command worked. Hope this helps someone else at some point.
Upvotes: 1