diff --git a/libs/DSharpPlus b/libs/DSharpPlus index 69a3cca..2f84b9c 160000 --- a/libs/DSharpPlus +++ b/libs/DSharpPlus @@ -1 +1 @@ -Subproject commit 69a3ccaf3c78dcaa082c9f335aae43efeb967f6c +Subproject commit 2f84b9c6376635112b62bf7cd95599ee350e91db diff --git a/src/Commands/Common/CalculateCommand.cs b/src/Commands/Common/CalculateCommand.cs index 4f5b179..715e6f9 100644 --- a/src/Commands/Common/CalculateCommand.cs +++ b/src/Commands/Common/CalculateCommand.cs @@ -1,4 +1,3 @@ -using System; using System.Data; using System.Threading.Tasks; using DSharpPlus.Commands; diff --git a/src/Commands/Common/InfoCommand/InfoCommand.Bot.cs b/src/Commands/Common/InfoCommand/InfoCommand.Bot.cs index e316615..5ddd3b6 100644 --- a/src/Commands/Common/InfoCommand/InfoCommand.Bot.cs +++ b/src/Commands/Common/InfoCommand/InfoCommand.Bot.cs @@ -57,9 +57,16 @@ public async ValueTask BotInfoAsync(CommandContext context) StringBuilder stringBuilder = new(); stringBuilder.Append(context.Client.CurrentUser.Mention); - stringBuilder.Append(", `"); - stringBuilder.Append(((DefaultPrefixResolver)context.Extension.GetProcessor().Configuration.PrefixResolver.Target!).Prefix); - stringBuilder.Append("`, `/`"); + stringBuilder.Append(", "); + foreach (string prefix in ((DefaultPrefixResolver)context.Extension.GetProcessor().Configuration.PrefixResolver.Target!).Prefixes) + { + stringBuilder.Append('`'); + stringBuilder.Append(prefix); + stringBuilder.Append('`'); + stringBuilder.Append(", "); + } + + stringBuilder.Append(", `/`"); embedBuilder.AddField("Prefixes", stringBuilder.ToString(), true); embedBuilder.AddField("Bot Version", _botVersion, true); embedBuilder.AddField("DSharpPlus Library Version", _dSharpPlusVersion, true); diff --git a/src/Commands/Common/TimeOfCommand.cs b/src/Commands/Common/TimeOfCommand.cs index 2e4a092..7c81a97 100644 --- a/src/Commands/Common/TimeOfCommand.cs +++ b/src/Commands/Common/TimeOfCommand.cs @@ -46,7 +46,7 @@ public static async ValueTask ExecuteAsync(CommandContext context, params string foreach (string message in messages) { converterContext.NextArgument(); - MessageCreateEventArgs messageCreateEventArgs = TextCommandUtilities.CreateFakeMessageEventArgs(context, message); + MessageCreatedEventArgs messageCreateEventArgs = TextCommandUtilities.CreateFakeMessageEventArgs(context, message); Optional parsedMessageId = await _uint64Converter.ConvertAsync(converterContext, messageCreateEventArgs); if (parsedMessageId.HasValue) { diff --git a/src/Events/DiscordEventManager.cs b/src/Events/DiscordEventManager.cs index 44f08e0..fd73bf4 100644 --- a/src/Events/DiscordEventManager.cs +++ b/src/Events/DiscordEventManager.cs @@ -3,13 +3,15 @@ using System.Linq; using System.Reflection; using DSharpPlus; +using DSharpPlus.Commands.Processors.SlashCommands; +using DSharpPlus.Commands.Processors.TextCommands; using Microsoft.Extensions.DependencyInjection; namespace OoLunar.Tomoe.Events { public sealed class DiscordEventManager { - public DiscordIntents Intents { get; private set; } + public DiscordIntents Intents { get; private set; } = TextCommandProcessor.RequiredIntents | SlashCommandProcessor.RequiredIntents | DiscordIntents.MessageContents; private readonly IServiceProvider _serviceProvider; private readonly List _eventHandlers = []; @@ -31,6 +33,29 @@ public void GatherEventHandlers(Assembly assembly) } } + public void RegisterEventHandlers(DiscordClientBuilder clientBuilder) + { + ArgumentNullException.ThrowIfNull(clientBuilder, nameof(clientBuilder)); + clientBuilder.ConfigureEventHandlers(eventHandlingBuilder => + { + foreach (MethodInfo methodInfo in typeof(EventHandlingBuilder).GetMethods(BindingFlags.Public | BindingFlags.Instance)) + { + if (!methodInfo.Name.StartsWith("Handle", StringComparison.Ordinal)) + { + continue; + } + + foreach (MethodInfo eventHandler in _eventHandlers) + { + if (methodInfo.GetParameters().Select(parameter => parameter.ParameterType).SequenceEqual(eventHandler.GetParameters().Select(parameter => parameter.ParameterType))) + { + eventHandlingBuilder = (EventHandlingBuilder)methodInfo.Invoke(eventHandlingBuilder, [eventHandler])!; + } + } + } + }); + } + public void RegisterEventHandlers(object obj) { ArgumentNullException.ThrowIfNull(obj, nameof(obj)); diff --git a/src/Events/Handlers/GuildMemberEventHandlers.cs b/src/Events/Handlers/GuildMemberEventHandlers.cs index ab697a0..6457b3c 100644 --- a/src/Events/Handlers/GuildMemberEventHandlers.cs +++ b/src/Events/Handlers/GuildMemberEventHandlers.cs @@ -17,7 +17,7 @@ public sealed class GuildMemberEventHandlers public GuildMemberEventHandlers(ILogger logger) => this.logger = logger ?? NullLogger.Instance; [DiscordEvent(DiscordIntents.Guilds | DiscordIntents.GuildPresences)] - public async Task OnGuildCreateAsync(DiscordClient _, GuildCreateEventArgs eventArgs) + public async Task OnGuildCreateAsync(DiscordClient _, GuildCreatedEventArgs eventArgs) { List guildMemberModels = []; foreach (DiscordMember member in eventArgs.Guild.Members.Values) @@ -37,7 +37,7 @@ public async Task OnGuildCreateAsync(DiscordClient _, GuildCreateEventArgs event } [DiscordEvent(DiscordIntents.GuildMembers)] - public async Task OnGuildMemberAddAsync(DiscordClient _, GuildMemberAddEventArgs eventArgs) + public async Task OnGuildMemberAddAsync(DiscordClient _, GuildMemberAddedEventArgs eventArgs) { GuildMemberModel? guildMemberModel = await GuildMemberModel.FindMemberAsync(eventArgs.Member.Id, eventArgs.Guild.Id); if (guildMemberModel is null) @@ -76,7 +76,7 @@ public async Task OnGuildMemberAddAsync(DiscordClient _, GuildMemberAddEventArgs } [DiscordEvent(DiscordIntents.GuildMembers)] - public static async Task OnGuildMemberRemoveAsync(DiscordClient _, GuildMemberRemoveEventArgs eventArgs) + public static async Task OnGuildMemberRemoveAsync(DiscordClient _, GuildMemberRemovedEventArgs eventArgs) { GuildMemberModel? guildMemberModel = await GuildMemberModel.FindMemberAsync(eventArgs.Member.Id, eventArgs.Guild.Id); if (guildMemberModel is null) @@ -93,7 +93,7 @@ public static async Task OnGuildMemberRemoveAsync(DiscordClient _, GuildMemberRe } [DiscordEvent(DiscordIntents.GuildMembers)] - public static async Task OnGuildMemberUpdateAsync(DiscordClient _, GuildMemberUpdateEventArgs eventArgs) + public static async Task OnGuildMemberUpdateAsync(DiscordClient _, GuildMemberUpdatedEventArgs eventArgs) { GuildMemberModel? guildMemberModel = await GuildMemberModel.FindMemberAsync(eventArgs.Member.Id, eventArgs.Guild.Id); if (guildMemberModel is null) @@ -110,7 +110,7 @@ public static async Task OnGuildMemberUpdateAsync(DiscordClient _, GuildMemberUp } [DiscordEvent(DiscordIntents.GuildMembers)] - public static async Task OnGuildMemberChunkAsync(DiscordClient _, GuildMembersChunkEventArgs eventArgs) + public static async Task OnGuildMemberChunkAsync(DiscordClient _, GuildMembersChunkedEventArgs eventArgs) { foreach (DiscordMember member in eventArgs.Members) { @@ -130,7 +130,7 @@ public static async Task OnGuildMemberChunkAsync(DiscordClient _, GuildMembersCh } [DiscordEvent(DiscordIntents.GuildModeration)] - public static async Task OnGuildMemberAddBanAsync(DiscordClient _, GuildBanAddEventArgs eventArgs) + public static async Task OnGuildMemberAddBanAsync(DiscordClient _, GuildBanAddedEventArgs eventArgs) { GuildMemberModel? guildMemberModel = await GuildMemberModel.FindMemberAsync(eventArgs.Member.Id, eventArgs.Guild.Id); if (guildMemberModel is null) @@ -147,7 +147,7 @@ public static async Task OnGuildMemberAddBanAsync(DiscordClient _, GuildBanAddEv } [DiscordEvent(DiscordIntents.GuildModeration)] - public static async Task OnGuildMemberRemoveBanAsync(DiscordClient _, GuildBanRemoveEventArgs eventArgs) + public static async Task OnGuildMemberRemoveBanAsync(DiscordClient _, GuildBanRemovedEventArgs eventArgs) { GuildMemberModel? guildMemberModel = await GuildMemberModel.FindMemberAsync(eventArgs.Member.Id, eventArgs.Guild.Id); if (guildMemberModel is null) diff --git a/src/Events/Handlers/PollSubmittedEventHandlers.cs b/src/Events/Handlers/PollSubmittedEventHandlers.cs index b728a74..204df80 100644 --- a/src/Events/Handlers/PollSubmittedEventHandlers.cs +++ b/src/Events/Handlers/PollSubmittedEventHandlers.cs @@ -11,7 +11,7 @@ namespace OoLunar.Tomoe.Events.Handlers public sealed class PollSubmittedEventHandlers { [DiscordEvent] - public static async Task OnPollSubmittedAsync(DiscordClient client, InteractionCreateEventArgs eventArgs) + public static async Task OnPollSubmittedAsync(DiscordClient client, InteractionCreatedEventArgs eventArgs) { if (eventArgs.Interaction.Type != DiscordInteractionType.Component) { diff --git a/src/Program.cs b/src/Program.cs index cbad5a9..ea9d1a4 100644 --- a/src/Program.cs +++ b/src/Program.cs @@ -12,6 +12,7 @@ using DSharpPlus.Commands.Processors.TextCommands; using DSharpPlus.Commands.Processors.TextCommands.Parsing; using DSharpPlus.Commands.Processors.UserCommands; +using DSharpPlus.Interactivity.Extensions; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; @@ -22,7 +23,6 @@ using Serilog; using Serilog.Events; using Serilog.Sinks.SystemConsole.Themes; -using DSharpPlusDiscordConfiguration = DSharpPlus.DiscordConfiguration; using SerilogLoggerConfiguration = Serilog.LoggerConfiguration; namespace OoLunar.Tomoe @@ -119,24 +119,22 @@ public static async Task Main(string[] args) } DiscordEventManager eventManager = serviceProvider.GetRequiredService(); - DiscordShardedClient discordClient = new(new DSharpPlusDiscordConfiguration - { - Token = tomoeConfiguration.Discord.Token, - Intents = eventManager.Intents | TextCommandProcessor.RequiredIntents | SlashCommandProcessor.RequiredIntents | DiscordIntents.MessageContents, - LoggerFactory = serviceProvider.GetRequiredService(), - }); - - return discordClient; + DiscordClientBuilder clientBuilder = DiscordClientBuilder.CreateDefault(tomoeConfiguration.Discord.Token, eventManager.Intents, serviceCollection); + //clientBuilder.ConfigureLogging(logger => logger.AddSerilo) + eventManager.RegisterEventHandlers(clientBuilder); + return clientBuilder.Build(); }); // Almost start the program IServiceProvider serviceProvider = serviceCollection.BuildServiceProvider(); DatabaseHandler databaseHandler = serviceProvider.GetRequiredService(); TomoeConfiguration tomoeConfiguration = serviceProvider.GetRequiredService(); - DiscordShardedClient discordClient = serviceProvider.GetRequiredService(); + DiscordClient discordClient = serviceProvider.GetRequiredService(); DiscordEventManager eventManager = serviceProvider.GetRequiredService(); Assembly currentAssembly = typeof(Program).Assembly; + discordClient.UseInteractivity(); + // Connect to the database try { @@ -148,59 +146,54 @@ public static async Task Main(string[] args) } // Register extensions here since these involve asynchronous operations - IReadOnlyDictionary commandsExtensions = await discordClient.UseCommandsAsync(new CommandsConfiguration() + CommandsExtension commandsExtension = discordClient.UseCommands(new CommandsConfiguration() { - ServiceProvider = serviceProvider, DebugGuildId = tomoeConfiguration.Discord.GuildId, UseDefaultCommandErrorHandler = false, RegisterDefaultCommandProcessors = false }); - // Iterate through each Discord shard - foreach (CommandsExtension commandsExtension in commandsExtensions.Values) - { - // Add all commands by scanning the current assembly - commandsExtension.AddCommands(currentAssembly); + // Add all commands by scanning the current assembly + commandsExtension.AddCommands(currentAssembly); - // Enable each command type specified by the user - List processors = []; - foreach (string processor in tomoeConfiguration.Discord.Processors) + // Enable each command type specified by the user + List processors = []; + foreach (string processor in tomoeConfiguration.Discord.Processors) + { + if (processor.Equals("text", StringComparison.OrdinalIgnoreCase)) { - if (processor.Equals("text", StringComparison.OrdinalIgnoreCase)) + TextCommandProcessor textCommandProcessor = new(new() { - TextCommandProcessor textCommandProcessor = new(new() - { - PrefixResolver = new DefaultPrefixResolver(tomoeConfiguration.Discord.Prefix ?? throw new InvalidOperationException("Missing Discord prefix.")).ResolvePrefixAsync - }); + PrefixResolver = new DefaultPrefixResolver(true, tomoeConfiguration.Discord.Prefix ?? throw new InvalidOperationException("Missing Discord prefix.")).ResolvePrefixAsync + }); - textCommandProcessor.AddConverters(currentAssembly); - processors.Add(textCommandProcessor); - } - else if (processor.Equals("slash", StringComparison.OrdinalIgnoreCase)) - { - SlashCommandProcessor slashCommandProcessor = new(); - slashCommandProcessor.AddConverters(currentAssembly); - processors.Add(slashCommandProcessor); - } - else if (processor.Equals("user", StringComparison.OrdinalIgnoreCase)) - { - processors.Add(new UserCommandProcessor()); - } - else if (processor.Equals("message", StringComparison.OrdinalIgnoreCase)) - { - processors.Add(new MessageCommandProcessor()); - } + textCommandProcessor.AddConverters(currentAssembly); + processors.Add(textCommandProcessor); + } + else if (processor.Equals("slash", StringComparison.OrdinalIgnoreCase)) + { + SlashCommandProcessor slashCommandProcessor = new(); + slashCommandProcessor.AddConverters(currentAssembly); + processors.Add(slashCommandProcessor); + } + else if (processor.Equals("user", StringComparison.OrdinalIgnoreCase)) + { + processors.Add(new UserCommandProcessor()); + } + else if (processor.Equals("message", StringComparison.OrdinalIgnoreCase)) + { + processors.Add(new MessageCommandProcessor()); } - - await commandsExtension.AddProcessorsAsync(processors); - eventManager.RegisterEventHandlers(commandsExtension); } + await commandsExtension.AddProcessorsAsync(processors); + eventManager.RegisterEventHandlers(commandsExtension); + // Register event handlers for the Discord Client itself eventManager.RegisterEventHandlers(discordClient); // Connect the bot to the Discord gateway. - await discordClient.StartAsync(); + await discordClient.ConnectAsync(); // Wait indefinitely await Task.Delay(-1); diff --git a/src/TextCommandUtilities.cs b/src/TextCommandUtilities.cs index 7ba2e4a..9b40d01 100644 --- a/src/TextCommandUtilities.cs +++ b/src/TextCommandUtilities.cs @@ -19,11 +19,11 @@ public static partial class TextCommandUtilities [GeneratedRegex(@"<@!?(\d+)>", RegexOptions.Compiled)] private static partial Regex _userMentionRegex(); [GeneratedRegex(@"<#(\d+)>", RegexOptions.Compiled)] private static partial Regex _channelMentionRegex(); - [UnsafeAccessor(UnsafeAccessorKind.Constructor)] private static extern MessageCreateEventArgs _messageCreateEventArgsConstructor(); - [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_Message")] private static extern void _messageCreateEventArgsMessageSetter(MessageCreateEventArgs messageCreateEventArgs, DiscordMessage message); - [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_MentionedUsers")] private static extern void _messageCreateEventArgsMentionedUsersSetter(MessageCreateEventArgs messageCreateEventArgs, IReadOnlyList mentionedUsers); - [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_MentionedRoles")] private static extern void _messageCreateEventArgsMentionedRolesSetter(MessageCreateEventArgs messageCreateEventArgs, IReadOnlyList mentionedRoles); - [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_MentionedChannels")] private static extern void _messageCreateEventArgsMentionedChannelsSetter(MessageCreateEventArgs messageCreateEventArgs, IReadOnlyList mentionedChannels); + [UnsafeAccessor(UnsafeAccessorKind.Constructor)] private static extern MessageCreatedEventArgs _messageCreateEventArgsConstructor(); + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_Message")] private static extern void _messageCreateEventArgsMessageSetter(MessageCreatedEventArgs messageCreateEventArgs, DiscordMessage message); + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_MentionedUsers")] private static extern void _messageCreateEventArgsMentionedUsersSetter(MessageCreatedEventArgs messageCreateEventArgs, IReadOnlyList mentionedUsers); + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_MentionedRoles")] private static extern void _messageCreateEventArgsMentionedRolesSetter(MessageCreatedEventArgs messageCreateEventArgs, IReadOnlyList mentionedRoles); + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_MentionedChannels")] private static extern void _messageCreateEventArgsMentionedChannelsSetter(MessageCreatedEventArgs messageCreateEventArgs, IReadOnlyList mentionedChannels); [UnsafeAccessor(UnsafeAccessorKind.Constructor)] private static extern DiscordMessage _messageConstructor(); [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_Content")] private static extern void _messageContentSetter(DiscordMessage message, string content); @@ -52,11 +52,11 @@ public static Task> ExecuteAsync(this ITextArgumentConverter c return converter.ConvertAsync(converterContext, CreateFakeMessageEventArgs(context, value)); } - public static MessageCreateEventArgs CreateFakeMessageEventArgs(TextCommandContext context) + public static MessageCreatedEventArgs CreateFakeMessageEventArgs(TextCommandContext context) { ArgumentNullException.ThrowIfNull(context, nameof(context)); - MessageCreateEventArgs messageCreateEventArgs = _messageCreateEventArgsConstructor(); + MessageCreatedEventArgs messageCreateEventArgs = _messageCreateEventArgsConstructor(); _messageCreateEventArgsMessageSetter(messageCreateEventArgs, context.Message); _messageCreateEventArgsMentionedUsersSetter(messageCreateEventArgs, context.Message.MentionedUsers); _messageCreateEventArgsMentionedRolesSetter(messageCreateEventArgs, context.Message.MentionedRoles); @@ -65,13 +65,13 @@ public static MessageCreateEventArgs CreateFakeMessageEventArgs(TextCommandConte return messageCreateEventArgs; } - public static MessageCreateEventArgs CreateFakeMessageEventArgs(CommandContext context, string content) + public static MessageCreatedEventArgs CreateFakeMessageEventArgs(CommandContext context, string content) { ArgumentNullException.ThrowIfNull(context, nameof(context)); ArgumentException.ThrowIfNullOrWhiteSpace(content, nameof(content)); DiscordMessage message = CreateFakeMessage(context, content); - MessageCreateEventArgs messageCreateEventArgs = _messageCreateEventArgsConstructor(); + MessageCreatedEventArgs messageCreateEventArgs = _messageCreateEventArgsConstructor(); _messageCreateEventArgsMessageSetter(messageCreateEventArgs, message); _messageCreateEventArgsMentionedUsersSetter(messageCreateEventArgs, message.MentionedUsers); _messageCreateEventArgsMentionedRolesSetter(messageCreateEventArgs, message.MentionedRoles); diff --git a/src/Tomoe.csproj b/src/Tomoe.csproj index cc6049c..1815ebd 100644 --- a/src/Tomoe.csproj +++ b/src/Tomoe.csproj @@ -29,6 +29,7 @@ +