From 33dea9bba96f91e1d893554ea0238f014f8c6743 Mon Sep 17 00:00:00 2001 From: InFTord Date: Wed, 31 Jan 2024 23:21:43 +0500 Subject: [PATCH 1/7] update to .net 8; update d#+ to latest prerelease version --- .../DSharpPlus.Examples.Basics.HelloWorld.csproj | 4 ++-- .../DSharpPlus.Examples.Basics.Logging.csproj | 4 ++-- .../DSharpPlus.Examples.Basics.MessageBuilder.csproj | 4 ++-- .../DSharpPlus.Examples.CommandsNext.Basics.csproj | 6 +++--- ...DSharpPlus.Examples.CommandsNext.CommandArguments.csproj | 6 +++--- ...Plus.Examples.CommandsNext.CustomCommandArguments.csproj | 6 +++--- .../DSharpPlus.Examples.CommandsNext.ErrorHandling.csproj | 6 +++--- .../DSharpPlus.Examples.CommandsNext.GroupCommands.csproj | 6 +++--- .../DSharpPlus.Examples.Components.Buttons.csproj | 4 ++-- .../DSharpPlus.Examples.Components.Modals.csproj | 4 ++-- .../DSharpPlus.Examples.Components.Selects.csproj | 4 ++-- 11 files changed, 27 insertions(+), 27 deletions(-) diff --git a/src/DSharpPlus.Examples.Basics.HelloWorld/DSharpPlus.Examples.Basics.HelloWorld.csproj b/src/DSharpPlus.Examples.Basics.HelloWorld/DSharpPlus.Examples.Basics.HelloWorld.csproj index 1641155..22dabcd 100644 --- a/src/DSharpPlus.Examples.Basics.HelloWorld/DSharpPlus.Examples.Basics.HelloWorld.csproj +++ b/src/DSharpPlus.Examples.Basics.HelloWorld/DSharpPlus.Examples.Basics.HelloWorld.csproj @@ -1,10 +1,10 @@  Exe - net7.0 + net8.0 enable - + \ No newline at end of file diff --git a/src/DSharpPlus.Examples.Basics.Logging/DSharpPlus.Examples.Basics.Logging.csproj b/src/DSharpPlus.Examples.Basics.Logging/DSharpPlus.Examples.Basics.Logging.csproj index 66f7d3f..eee5a79 100644 --- a/src/DSharpPlus.Examples.Basics.Logging/DSharpPlus.Examples.Basics.Logging.csproj +++ b/src/DSharpPlus.Examples.Basics.Logging/DSharpPlus.Examples.Basics.Logging.csproj @@ -1,11 +1,11 @@  Exe - net7.0 + net8.0 enable - + diff --git a/src/DSharpPlus.Examples.Basics.MessageBuilder/DSharpPlus.Examples.Basics.MessageBuilder.csproj b/src/DSharpPlus.Examples.Basics.MessageBuilder/DSharpPlus.Examples.Basics.MessageBuilder.csproj index 1641155..22dabcd 100644 --- a/src/DSharpPlus.Examples.Basics.MessageBuilder/DSharpPlus.Examples.Basics.MessageBuilder.csproj +++ b/src/DSharpPlus.Examples.Basics.MessageBuilder/DSharpPlus.Examples.Basics.MessageBuilder.csproj @@ -1,10 +1,10 @@  Exe - net7.0 + net8.0 enable - + \ No newline at end of file diff --git a/src/DSharpPlus.Examples.CommandsNext.Basics/DSharpPlus.Examples.CommandsNext.Basics.csproj b/src/DSharpPlus.Examples.CommandsNext.Basics/DSharpPlus.Examples.CommandsNext.Basics.csproj index f8a1bb1..aa3e22a 100644 --- a/src/DSharpPlus.Examples.CommandsNext.Basics/DSharpPlus.Examples.CommandsNext.Basics.csproj +++ b/src/DSharpPlus.Examples.CommandsNext.Basics/DSharpPlus.Examples.CommandsNext.Basics.csproj @@ -1,11 +1,11 @@  Exe - net7.0 + net8.0 enable - - + + \ No newline at end of file diff --git a/src/DSharpPlus.Examples.CommandsNext.CommandArguments/DSharpPlus.Examples.CommandsNext.CommandArguments.csproj b/src/DSharpPlus.Examples.CommandsNext.CommandArguments/DSharpPlus.Examples.CommandsNext.CommandArguments.csproj index f8a1bb1..aa3e22a 100644 --- a/src/DSharpPlus.Examples.CommandsNext.CommandArguments/DSharpPlus.Examples.CommandsNext.CommandArguments.csproj +++ b/src/DSharpPlus.Examples.CommandsNext.CommandArguments/DSharpPlus.Examples.CommandsNext.CommandArguments.csproj @@ -1,11 +1,11 @@  Exe - net7.0 + net8.0 enable - - + + \ No newline at end of file diff --git a/src/DSharpPlus.Examples.CommandsNext.CustomCommandArguments/DSharpPlus.Examples.CommandsNext.CustomCommandArguments.csproj b/src/DSharpPlus.Examples.CommandsNext.CustomCommandArguments/DSharpPlus.Examples.CommandsNext.CustomCommandArguments.csproj index fedeafc..30e19ea 100644 --- a/src/DSharpPlus.Examples.CommandsNext.CustomCommandArguments/DSharpPlus.Examples.CommandsNext.CustomCommandArguments.csproj +++ b/src/DSharpPlus.Examples.CommandsNext.CustomCommandArguments/DSharpPlus.Examples.CommandsNext.CustomCommandArguments.csproj @@ -1,12 +1,12 @@  Exe - net7.0 + net8.0 enable - - + + \ No newline at end of file diff --git a/src/DSharpPlus.Examples.CommandsNext.ErrorHandling/DSharpPlus.Examples.CommandsNext.ErrorHandling.csproj b/src/DSharpPlus.Examples.CommandsNext.ErrorHandling/DSharpPlus.Examples.CommandsNext.ErrorHandling.csproj index f8a1bb1..aa3e22a 100644 --- a/src/DSharpPlus.Examples.CommandsNext.ErrorHandling/DSharpPlus.Examples.CommandsNext.ErrorHandling.csproj +++ b/src/DSharpPlus.Examples.CommandsNext.ErrorHandling/DSharpPlus.Examples.CommandsNext.ErrorHandling.csproj @@ -1,11 +1,11 @@  Exe - net7.0 + net8.0 enable - - + + \ No newline at end of file diff --git a/src/DSharpPlus.Examples.CommandsNext.GroupCommands/DSharpPlus.Examples.CommandsNext.GroupCommands.csproj b/src/DSharpPlus.Examples.CommandsNext.GroupCommands/DSharpPlus.Examples.CommandsNext.GroupCommands.csproj index fedeafc..30e19ea 100644 --- a/src/DSharpPlus.Examples.CommandsNext.GroupCommands/DSharpPlus.Examples.CommandsNext.GroupCommands.csproj +++ b/src/DSharpPlus.Examples.CommandsNext.GroupCommands/DSharpPlus.Examples.CommandsNext.GroupCommands.csproj @@ -1,12 +1,12 @@  Exe - net7.0 + net8.0 enable - - + + \ No newline at end of file diff --git a/src/DSharpPlus.Examples.Components.Buttons/DSharpPlus.Examples.Components.Buttons.csproj b/src/DSharpPlus.Examples.Components.Buttons/DSharpPlus.Examples.Components.Buttons.csproj index 1641155..22dabcd 100644 --- a/src/DSharpPlus.Examples.Components.Buttons/DSharpPlus.Examples.Components.Buttons.csproj +++ b/src/DSharpPlus.Examples.Components.Buttons/DSharpPlus.Examples.Components.Buttons.csproj @@ -1,10 +1,10 @@  Exe - net7.0 + net8.0 enable - + \ No newline at end of file diff --git a/src/DSharpPlus.Examples.Components.Modals/DSharpPlus.Examples.Components.Modals.csproj b/src/DSharpPlus.Examples.Components.Modals/DSharpPlus.Examples.Components.Modals.csproj index 1641155..22dabcd 100644 --- a/src/DSharpPlus.Examples.Components.Modals/DSharpPlus.Examples.Components.Modals.csproj +++ b/src/DSharpPlus.Examples.Components.Modals/DSharpPlus.Examples.Components.Modals.csproj @@ -1,10 +1,10 @@  Exe - net7.0 + net8.0 enable - + \ No newline at end of file diff --git a/src/DSharpPlus.Examples.Components.Selects/DSharpPlus.Examples.Components.Selects.csproj b/src/DSharpPlus.Examples.Components.Selects/DSharpPlus.Examples.Components.Selects.csproj index 1641155..22dabcd 100644 --- a/src/DSharpPlus.Examples.Components.Selects/DSharpPlus.Examples.Components.Selects.csproj +++ b/src/DSharpPlus.Examples.Components.Selects/DSharpPlus.Examples.Components.Selects.csproj @@ -1,10 +1,10 @@  Exe - net7.0 + net8.0 enable - + \ No newline at end of file From 98674dbd3a80959b52d273906eee77d01ef22e2c Mon Sep 17 00:00:00 2001 From: InFTord Date: Thu, 1 Feb 2024 22:55:11 +0500 Subject: [PATCH 2/7] update basics example to use Commands instead of CNext --- Example-Bots.sln | 2 +- .../Commands/PingCommand.cs | 13 +++++ ...DSharpPlus.Examples.Commands.Basics.csproj | 16 ++++++ .../Program.cs | 56 +++++++++++++++++++ .../Commands/.editorconfig | 5 -- .../Commands/PingCommand.cs | 20 ------- ...rpPlus.Examples.CommandsNext.Basics.csproj | 11 ---- .../Program.cs | 52 ----------------- 8 files changed, 86 insertions(+), 89 deletions(-) create mode 100644 src/DSharpPlus.Examples.Commands.Basics/Commands/PingCommand.cs create mode 100644 src/DSharpPlus.Examples.Commands.Basics/DSharpPlus.Examples.Commands.Basics.csproj create mode 100644 src/DSharpPlus.Examples.Commands.Basics/Program.cs delete mode 100644 src/DSharpPlus.Examples.CommandsNext.Basics/Commands/.editorconfig delete mode 100644 src/DSharpPlus.Examples.CommandsNext.Basics/Commands/PingCommand.cs delete mode 100644 src/DSharpPlus.Examples.CommandsNext.Basics/DSharpPlus.Examples.CommandsNext.Basics.csproj delete mode 100644 src/DSharpPlus.Examples.CommandsNext.Basics/Program.cs diff --git a/Example-Bots.sln b/Example-Bots.sln index 101209b..d9bd3fe 100644 --- a/Example-Bots.sln +++ b/Example-Bots.sln @@ -17,7 +17,7 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DSharpPlus.Examples.Compone EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DSharpPlus.Examples.Components.Modals", "src\DSharpPlus.Examples.Components.Modals\DSharpPlus.Examples.Components.Modals.csproj", "{C5197139-4026-4EE9-A301-136FC3E10DA3}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DSharpPlus.Examples.CommandsNext.Basics", "src\DSharpPlus.Examples.CommandsNext.Basics\DSharpPlus.Examples.CommandsNext.Basics.csproj", "{7135C15F-A8FD-4CEB-BA07-ED45FFBFFFF5}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DSharpPlus.Examples.Commands.Basics", "src\DSharpPlus.Examples.Commands.Basics\DSharpPlus.Examples.Commands.Basics.csproj", "{7135C15F-A8FD-4CEB-BA07-ED45FFBFFFF5}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DSharpPlus.Examples.CommandsNext.CommandArguments", "src\DSharpPlus.Examples.CommandsNext.CommandArguments\DSharpPlus.Examples.CommandsNext.CommandArguments.csproj", "{1159DF74-2834-4A7B-97C2-384C8578F6A6}" EndProject diff --git a/src/DSharpPlus.Examples.Commands.Basics/Commands/PingCommand.cs b/src/DSharpPlus.Examples.Commands.Basics/Commands/PingCommand.cs new file mode 100644 index 0000000..e789ae2 --- /dev/null +++ b/src/DSharpPlus.Examples.Commands.Basics/Commands/PingCommand.cs @@ -0,0 +1,13 @@ +using System.Threading.Tasks; +using DSharpPlus.Commands.Processors.TextCommands.Attributes; +using DSharpPlus.Commands.Trees; +using DSharpPlus.Commands.Trees.Attributes; + +namespace DSharpPlus.Examples.Commands.Basics +{ + public sealed class PingCommand + { + [Command("ping"), TextAlias("pong")] + public static ValueTask ExecuteAsync(CommandContext context) => context.RespondAsync($"Pong! Latency is {context.Client.Ping}ms."); + } +} diff --git a/src/DSharpPlus.Examples.Commands.Basics/DSharpPlus.Examples.Commands.Basics.csproj b/src/DSharpPlus.Examples.Commands.Basics/DSharpPlus.Examples.Commands.Basics.csproj new file mode 100644 index 0000000..2ae2714 --- /dev/null +++ b/src/DSharpPlus.Examples.Commands.Basics/DSharpPlus.Examples.Commands.Basics.csproj @@ -0,0 +1,16 @@ + + + Exe + net8.0 + enable + DSharpPlus.Examples.Commands.Basics + + + + + + + + + + \ No newline at end of file diff --git a/src/DSharpPlus.Examples.Commands.Basics/Program.cs b/src/DSharpPlus.Examples.Commands.Basics/Program.cs new file mode 100644 index 0000000..8f1ec20 --- /dev/null +++ b/src/DSharpPlus.Examples.Commands.Basics/Program.cs @@ -0,0 +1,56 @@ +using System; +using System.Reflection; +using System.Threading.Tasks; +using DSharpPlus.Commands; +using DSharpPlus.Commands.Processors.SlashCommands; +using DSharpPlus.Commands.Processors.TextCommands; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; + +namespace DSharpPlus.Examples.Commands.Basics +{ + public static class Program + { + public static async Task Main(string[] args) + { + ConfigurationBuilder configurationBuilder = new(); + configurationBuilder.Sources.Clear(); + configurationBuilder.AddEnvironmentVariables(""); + configurationBuilder.AddCommandLine(args); + + IConfiguration configuration = configurationBuilder.Build(); + ServiceCollection serviceCollection = new(); + serviceCollection.AddSingleton(configuration); + Assembly currentAssembly = typeof(Program).Assembly; + + + serviceCollection.AddSingleton(serviceProvider => + { + DiscordClient client = new(new DiscordConfiguration() + { + Token = configuration.GetValue("discord:token") ?? + throw new InvalidOperationException("Missing Discord token."), + Intents = DiscordIntents.AllUnprivileged | DiscordIntents.MessageContents + }); + + CommandsExtension extension = client.UseCommands(new() + { + DebugGuildId = configuration.GetValue("discord:debug_guild_id", null), + ServiceProvider = serviceProvider, + }); + + extension.AddProcessorAsync(new TextCommandProcessor()); + extension.AddProcessorAsync(new SlashCommandProcessor()); + extension.AddCommands(currentAssembly); + + return client; + }); + IServiceProvider serviceProvider = serviceCollection.BuildServiceProvider(); + + DiscordClient client = serviceProvider.GetRequiredService(); + await client.ConnectAsync(); + + await Task.Delay(-1); + } + } +} diff --git a/src/DSharpPlus.Examples.CommandsNext.Basics/Commands/.editorconfig b/src/DSharpPlus.Examples.CommandsNext.Basics/Commands/.editorconfig deleted file mode 100644 index 85cd174..0000000 --- a/src/DSharpPlus.Examples.CommandsNext.Basics/Commands/.editorconfig +++ /dev/null @@ -1,5 +0,0 @@ -# .editorconfig -root = false - -[*.{cs,vb}] -dotnet_diagnostic.CA1822.severity = none # Suppress CA1822 due to CommandsNext not supporting static commands. \ No newline at end of file diff --git a/src/DSharpPlus.Examples.CommandsNext.Basics/Commands/PingCommand.cs b/src/DSharpPlus.Examples.CommandsNext.Basics/Commands/PingCommand.cs deleted file mode 100644 index 09f93c8..0000000 --- a/src/DSharpPlus.Examples.CommandsNext.Basics/Commands/PingCommand.cs +++ /dev/null @@ -1,20 +0,0 @@ -using System.Text; -using System.Threading.Tasks; -using DSharpPlus.CommandsNext; -using DSharpPlus.CommandsNext.Attributes; - -namespace DSharpPlus.Examples.CommandsNext.Basics.Commands -{ - public class PingCommand : BaseCommandModule - { - [Command("ping"), Description("Checks the bot's latency to the Discord API.")] - public async Task ExecuteAsync(CommandContext context) - { - StringBuilder messageBuilder = new(); - messageBuilder.AppendLine($"Pong! Latency is {context.Client.Ping}ms."); - messageBuilder.AppendLine($"Additionally, try running {Formatter.InlineCode($"{context.Prefix}help")} to see a list of commands."); - - await context.RespondAsync(messageBuilder.ToString()); - } - } -} diff --git a/src/DSharpPlus.Examples.CommandsNext.Basics/DSharpPlus.Examples.CommandsNext.Basics.csproj b/src/DSharpPlus.Examples.CommandsNext.Basics/DSharpPlus.Examples.CommandsNext.Basics.csproj deleted file mode 100644 index aa3e22a..0000000 --- a/src/DSharpPlus.Examples.CommandsNext.Basics/DSharpPlus.Examples.CommandsNext.Basics.csproj +++ /dev/null @@ -1,11 +0,0 @@ - - - Exe - net8.0 - enable - - - - - - \ No newline at end of file diff --git a/src/DSharpPlus.Examples.CommandsNext.Basics/Program.cs b/src/DSharpPlus.Examples.CommandsNext.Basics/Program.cs deleted file mode 100644 index 3ddd8a5..0000000 --- a/src/DSharpPlus.Examples.CommandsNext.Basics/Program.cs +++ /dev/null @@ -1,52 +0,0 @@ -using System; -using System.Threading.Tasks; -using DSharpPlus.CommandsNext; - -namespace DSharpPlus.Examples.CommandsNext.Basics -{ - public static class Program - { - /// - /// The prefixes used to trigger Discord text commands through CommandsNext. - /// - private static readonly string[] _prefixes = new[] { "!" }; - - public static async Task Main() - { - // Check for token - // TODO: Load the token up from IConfiguration - string? token = Environment.GetEnvironmentVariable("DISCORD_TOKEN"); - if (string.IsNullOrWhiteSpace(token)) - { - Console.WriteLine("Please set the environment variable DISCORD_TOKEN."); - return; - } - - // Create the client - DiscordClient discord = new(new DiscordConfiguration - { - Token = token, - Intents = DiscordIntents.AllUnprivileged | DiscordIntents.MessageContents - }); - - CommandsNextExtension commandsNext = discord.UseCommandsNext(new CommandsNextConfiguration() - { - // For brevity, we're going to use the string prefixes property. - // However, if you want to do something complicated, such as per-guild prefixes, - // you can pass a prefix resolver delegate instead. - StringPrefixes = _prefixes - }); - - // If we pass our assembly to CommandsNext, it will automatically - // search our program for any Command classes and register them on its own. - // This is very handy so you don't need to manually update a list when you add a new command. - commandsNext.RegisterCommands(typeof(Program).Assembly); - - // Connect to the Discord gateway - await discord.ConnectAsync(); - - // Wait infinitely so the bot stays connected; DiscordClient.ConnectAsync is not a blocking call - await Task.Delay(-1); - } - } -} From c3aa229f2131be199964e923e1afa9505007f192 Mon Sep 17 00:00:00 2001 From: InFTord Date: Thu, 1 Feb 2024 23:15:22 +0500 Subject: [PATCH 3/7] murder CNext examples --- Example-Bots.sln | 28 -------- .../Commands/.editorconfig | 5 -- .../Commands/AvatarCommand.cs | 25 ------- .../Commands/HttpCat.cs | 31 --------- ...mples.CommandsNext.CommandArguments.csproj | 11 --- .../Program.cs | 52 -------------- .../ArgumentConverters/.editorconfig | 5 -- .../UlidArgumentConverter.cs | 21 ------ .../Commands/.editorconfig | 5 -- .../Commands/CreateUlidCommand.cs | 13 ---- .../Commands/UlidInfoCommand.cs | 25 ------- ...CommandsNext.CustomCommandArguments.csproj | 12 ---- .../Program.cs | 57 --------------- .../Commands/.editorconfig | 5 -- .../Commands/ErrorCommand.cs | 15 ---- ...Examples.CommandsNext.ErrorHandling.csproj | 11 --- .../Program.cs | 69 ------------------- .../ArgumentConverters/.editorconfig | 5 -- .../UlidArgumentConverter.cs | 21 ------ .../Commands/.editorconfig | 5 -- .../Commands/UlidCommand.cs | 37 ---------- ...Examples.CommandsNext.GroupCommands.csproj | 12 ---- .../Program.cs | 57 --------------- 23 files changed, 527 deletions(-) delete mode 100644 src/DSharpPlus.Examples.CommandsNext.CommandArguments/Commands/.editorconfig delete mode 100644 src/DSharpPlus.Examples.CommandsNext.CommandArguments/Commands/AvatarCommand.cs delete mode 100644 src/DSharpPlus.Examples.CommandsNext.CommandArguments/Commands/HttpCat.cs delete mode 100644 src/DSharpPlus.Examples.CommandsNext.CommandArguments/DSharpPlus.Examples.CommandsNext.CommandArguments.csproj delete mode 100644 src/DSharpPlus.Examples.CommandsNext.CommandArguments/Program.cs delete mode 100644 src/DSharpPlus.Examples.CommandsNext.CustomCommandArguments/ArgumentConverters/.editorconfig delete mode 100644 src/DSharpPlus.Examples.CommandsNext.CustomCommandArguments/ArgumentConverters/UlidArgumentConverter.cs delete mode 100644 src/DSharpPlus.Examples.CommandsNext.CustomCommandArguments/Commands/.editorconfig delete mode 100644 src/DSharpPlus.Examples.CommandsNext.CustomCommandArguments/Commands/CreateUlidCommand.cs delete mode 100644 src/DSharpPlus.Examples.CommandsNext.CustomCommandArguments/Commands/UlidInfoCommand.cs delete mode 100644 src/DSharpPlus.Examples.CommandsNext.CustomCommandArguments/DSharpPlus.Examples.CommandsNext.CustomCommandArguments.csproj delete mode 100644 src/DSharpPlus.Examples.CommandsNext.CustomCommandArguments/Program.cs delete mode 100644 src/DSharpPlus.Examples.CommandsNext.ErrorHandling/Commands/.editorconfig delete mode 100644 src/DSharpPlus.Examples.CommandsNext.ErrorHandling/Commands/ErrorCommand.cs delete mode 100644 src/DSharpPlus.Examples.CommandsNext.ErrorHandling/DSharpPlus.Examples.CommandsNext.ErrorHandling.csproj delete mode 100644 src/DSharpPlus.Examples.CommandsNext.ErrorHandling/Program.cs delete mode 100644 src/DSharpPlus.Examples.CommandsNext.GroupCommands/ArgumentConverters/.editorconfig delete mode 100644 src/DSharpPlus.Examples.CommandsNext.GroupCommands/ArgumentConverters/UlidArgumentConverter.cs delete mode 100644 src/DSharpPlus.Examples.CommandsNext.GroupCommands/Commands/.editorconfig delete mode 100644 src/DSharpPlus.Examples.CommandsNext.GroupCommands/Commands/UlidCommand.cs delete mode 100644 src/DSharpPlus.Examples.CommandsNext.GroupCommands/DSharpPlus.Examples.CommandsNext.GroupCommands.csproj delete mode 100644 src/DSharpPlus.Examples.CommandsNext.GroupCommands/Program.cs diff --git a/Example-Bots.sln b/Example-Bots.sln index d9bd3fe..4da8623 100644 --- a/Example-Bots.sln +++ b/Example-Bots.sln @@ -19,14 +19,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DSharpPlus.Examples.Compone EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DSharpPlus.Examples.Commands.Basics", "src\DSharpPlus.Examples.Commands.Basics\DSharpPlus.Examples.Commands.Basics.csproj", "{7135C15F-A8FD-4CEB-BA07-ED45FFBFFFF5}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DSharpPlus.Examples.CommandsNext.CommandArguments", "src\DSharpPlus.Examples.CommandsNext.CommandArguments\DSharpPlus.Examples.CommandsNext.CommandArguments.csproj", "{1159DF74-2834-4A7B-97C2-384C8578F6A6}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DSharpPlus.Examples.CommandsNext.CustomCommandArguments", "src\DSharpPlus.Examples.CommandsNext.CustomCommandArguments\DSharpPlus.Examples.CommandsNext.CustomCommandArguments.csproj", "{9424B2A1-C411-4B1E-A0C3-48CAA91CDC4B}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DSharpPlus.Examples.CommandsNext.ErrorHandling", "src\DSharpPlus.Examples.CommandsNext.ErrorHandling\DSharpPlus.Examples.CommandsNext.ErrorHandling.csproj", "{6E106DAA-D075-4AD2-AA10-41327B9D3FF4}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DSharpPlus.Examples.CommandsNext.GroupCommands", "src\DSharpPlus.Examples.CommandsNext.GroupCommands\DSharpPlus.Examples.CommandsNext.GroupCommands.csproj", "{5A3B56EC-DD5E-4D15-859B-94B09ADC2795}" -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -64,22 +56,6 @@ Global {7135C15F-A8FD-4CEB-BA07-ED45FFBFFFF5}.Debug|Any CPU.Build.0 = Debug|Any CPU {7135C15F-A8FD-4CEB-BA07-ED45FFBFFFF5}.Release|Any CPU.ActiveCfg = Release|Any CPU {7135C15F-A8FD-4CEB-BA07-ED45FFBFFFF5}.Release|Any CPU.Build.0 = Release|Any CPU - {1159DF74-2834-4A7B-97C2-384C8578F6A6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {1159DF74-2834-4A7B-97C2-384C8578F6A6}.Debug|Any CPU.Build.0 = Debug|Any CPU - {1159DF74-2834-4A7B-97C2-384C8578F6A6}.Release|Any CPU.ActiveCfg = Release|Any CPU - {1159DF74-2834-4A7B-97C2-384C8578F6A6}.Release|Any CPU.Build.0 = Release|Any CPU - {9424B2A1-C411-4B1E-A0C3-48CAA91CDC4B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {9424B2A1-C411-4B1E-A0C3-48CAA91CDC4B}.Debug|Any CPU.Build.0 = Debug|Any CPU - {9424B2A1-C411-4B1E-A0C3-48CAA91CDC4B}.Release|Any CPU.ActiveCfg = Release|Any CPU - {9424B2A1-C411-4B1E-A0C3-48CAA91CDC4B}.Release|Any CPU.Build.0 = Release|Any CPU - {6E106DAA-D075-4AD2-AA10-41327B9D3FF4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {6E106DAA-D075-4AD2-AA10-41327B9D3FF4}.Debug|Any CPU.Build.0 = Debug|Any CPU - {6E106DAA-D075-4AD2-AA10-41327B9D3FF4}.Release|Any CPU.ActiveCfg = Release|Any CPU - {6E106DAA-D075-4AD2-AA10-41327B9D3FF4}.Release|Any CPU.Build.0 = Release|Any CPU - {5A3B56EC-DD5E-4D15-859B-94B09ADC2795}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {5A3B56EC-DD5E-4D15-859B-94B09ADC2795}.Debug|Any CPU.Build.0 = Debug|Any CPU - {5A3B56EC-DD5E-4D15-859B-94B09ADC2795}.Release|Any CPU.ActiveCfg = Release|Any CPU - {5A3B56EC-DD5E-4D15-859B-94B09ADC2795}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(NestedProjects) = preSolution {43280D9F-9965-4270-9082-12029948F559} = {1DE5170D-7FE0-487D-9EAF-5327832D8A4B} @@ -89,9 +65,5 @@ Global {00471D68-8D82-469D-959F-1B6058248A15} = {1DE5170D-7FE0-487D-9EAF-5327832D8A4B} {C5197139-4026-4EE9-A301-136FC3E10DA3} = {1DE5170D-7FE0-487D-9EAF-5327832D8A4B} {7135C15F-A8FD-4CEB-BA07-ED45FFBFFFF5} = {1DE5170D-7FE0-487D-9EAF-5327832D8A4B} - {1159DF74-2834-4A7B-97C2-384C8578F6A6} = {1DE5170D-7FE0-487D-9EAF-5327832D8A4B} - {9424B2A1-C411-4B1E-A0C3-48CAA91CDC4B} = {1DE5170D-7FE0-487D-9EAF-5327832D8A4B} - {6E106DAA-D075-4AD2-AA10-41327B9D3FF4} = {1DE5170D-7FE0-487D-9EAF-5327832D8A4B} - {5A3B56EC-DD5E-4D15-859B-94B09ADC2795} = {1DE5170D-7FE0-487D-9EAF-5327832D8A4B} EndGlobalSection EndGlobal diff --git a/src/DSharpPlus.Examples.CommandsNext.CommandArguments/Commands/.editorconfig b/src/DSharpPlus.Examples.CommandsNext.CommandArguments/Commands/.editorconfig deleted file mode 100644 index 85cd174..0000000 --- a/src/DSharpPlus.Examples.CommandsNext.CommandArguments/Commands/.editorconfig +++ /dev/null @@ -1,5 +0,0 @@ -# .editorconfig -root = false - -[*.{cs,vb}] -dotnet_diagnostic.CA1822.severity = none # Suppress CA1822 due to CommandsNext not supporting static commands. \ No newline at end of file diff --git a/src/DSharpPlus.Examples.CommandsNext.CommandArguments/Commands/AvatarCommand.cs b/src/DSharpPlus.Examples.CommandsNext.CommandArguments/Commands/AvatarCommand.cs deleted file mode 100644 index 662fb73..0000000 --- a/src/DSharpPlus.Examples.CommandsNext.CommandArguments/Commands/AvatarCommand.cs +++ /dev/null @@ -1,25 +0,0 @@ -using System.Threading.Tasks; -using DSharpPlus.CommandsNext; -using DSharpPlus.CommandsNext.Attributes; -using DSharpPlus.Entities; - -namespace DSharpPlus.Examples.CommandsNext.CommandArguments.Commands -{ - public class AvatarCommand : BaseCommandModule - { - // We can just request for a DiscordMember directly here. The user will either ping the member, send the member's ID, or send the member's username. - // Regardless of input, CommandsNext will do it's best to parse it into a DiscordMember. - [Command("avatar"), Description("Sends the requested user's profile picture in it's own message for easy viewing.")] - public async Task ExecuteAsync(CommandContext context, DiscordMember member) => await context.RespondAsync(member.AvatarUrl); - - // Oh, but what if the DiscordMember isn't in the server? Well, CommandsNext will fallback to the next overload (this command!) - // This time though, we'll need a user mention or user id. Usernames won't work here. - [Command("avatar")] - public async Task ExecuteAsync(CommandContext context, DiscordUser user) => await context.RespondAsync(user.AvatarUrl); - - // What if no arguments are provided? CommandsNext will intelligently execute this overload first, since it has no arguments. - // For now we'll just send the user's avatar. - [Command("avatar")] - public async Task ExecuteAsync(CommandContext context) => await context.RespondAsync(context.User.AvatarUrl); - } -} diff --git a/src/DSharpPlus.Examples.CommandsNext.CommandArguments/Commands/HttpCat.cs b/src/DSharpPlus.Examples.CommandsNext.CommandArguments/Commands/HttpCat.cs deleted file mode 100644 index 6bf6320..0000000 --- a/src/DSharpPlus.Examples.CommandsNext.CommandArguments/Commands/HttpCat.cs +++ /dev/null @@ -1,31 +0,0 @@ -using System; -using System.Net; -using System.Threading.Tasks; -using DSharpPlus.CommandsNext; -using DSharpPlus.CommandsNext.Attributes; - -namespace DSharpPlus.Examples.CommandsNext.CommandArguments.Commands -{ - public class HttpCatCommand : BaseCommandModule - { - // Sometimes, when my strings get really long, I like to put them in constants. - private const string HTTP_COMMAND = "httpcat"; - private const string HTTP_COMMAND_DESCRIPTION = "Returns a http.cat image for the provided HTTP status code."; - private const string HTTP_COMMAND_CODE_DESCRIPTION = "An optional parameter to specify which http code to send. If no argument is provided, a random http code is chosen."; - - private static readonly HttpStatusCode[] _validHttpCodes = Enum.GetValues(); - - // Because the code parameter has a default value (null), this makes the parameter optional. - // Parameters do NOT become optional when they're nullable. - // Parameters DO become optional when they have a default value. - [Command(HTTP_COMMAND), Description(HTTP_COMMAND_DESCRIPTION)] - public async Task ExecuteAsync(CommandContext context, [Description(HTTP_COMMAND_CODE_DESCRIPTION)] int? code = null) - { - // If no code is provided, we'll just pick a random one. - code ??= (int)_validHttpCodes[Random.Shared.Next(_validHttpCodes.Length)]; - - // Cast to an int so we can use it in the URL. - await context.RespondAsync($"https://http.cat/{code}"); - } - } -} diff --git a/src/DSharpPlus.Examples.CommandsNext.CommandArguments/DSharpPlus.Examples.CommandsNext.CommandArguments.csproj b/src/DSharpPlus.Examples.CommandsNext.CommandArguments/DSharpPlus.Examples.CommandsNext.CommandArguments.csproj deleted file mode 100644 index aa3e22a..0000000 --- a/src/DSharpPlus.Examples.CommandsNext.CommandArguments/DSharpPlus.Examples.CommandsNext.CommandArguments.csproj +++ /dev/null @@ -1,11 +0,0 @@ - - - Exe - net8.0 - enable - - - - - - \ No newline at end of file diff --git a/src/DSharpPlus.Examples.CommandsNext.CommandArguments/Program.cs b/src/DSharpPlus.Examples.CommandsNext.CommandArguments/Program.cs deleted file mode 100644 index 442c545..0000000 --- a/src/DSharpPlus.Examples.CommandsNext.CommandArguments/Program.cs +++ /dev/null @@ -1,52 +0,0 @@ -using System; -using System.Threading.Tasks; -using DSharpPlus.CommandsNext; - -namespace DSharpPlus.Examples.CommandsNext.CommandArguments -{ - public static class Program - { - /// - /// The prefixes used to trigger Discord text commands through CommandsNext. - /// - private static readonly string[] _prefixes = new[] { "!" }; - - public static async Task Main() - { - // Check for token - // TODO: Load the token up from IConfiguration - string? token = Environment.GetEnvironmentVariable("DISCORD_TOKEN"); - if (string.IsNullOrWhiteSpace(token)) - { - Console.WriteLine("Please set the environment variable DISCORD_TOKEN."); - return; - } - - // Create the client - DiscordClient discord = new(new DiscordConfiguration - { - Token = token, - Intents = DiscordIntents.AllUnprivileged | DiscordIntents.MessageContents - }); - - CommandsNextExtension commandsNext = discord.UseCommandsNext(new CommandsNextConfiguration() - { - // For brevity, we're going to use the string prefixes property. - // However, if you want to do something complicated, such as per-guild prefixes, - // you can pass a prefix resolver delegate instead. - StringPrefixes = _prefixes - }); - - // If we pass our assembly to CommandsNext, it will automatically - // search our program for any Command classes and register them on its own. - // This is very handy so you don't need to manually update a list when you add a new command. - commandsNext.RegisterCommands(typeof(Program).Assembly); - - // Connect to the Discord gateway - await discord.ConnectAsync(); - - // Wait infinitely so the bot stays connected; DiscordClient.ConnectAsync is not a blocking call - await Task.Delay(-1); - } - } -} diff --git a/src/DSharpPlus.Examples.CommandsNext.CustomCommandArguments/ArgumentConverters/.editorconfig b/src/DSharpPlus.Examples.CommandsNext.CustomCommandArguments/ArgumentConverters/.editorconfig deleted file mode 100644 index 9f997ca..0000000 --- a/src/DSharpPlus.Examples.CommandsNext.CustomCommandArguments/ArgumentConverters/.editorconfig +++ /dev/null @@ -1,5 +0,0 @@ -# .editorconfig -root = false - -[*.{cs,vb}] -dotnet_diagnostic.IDE0046.severity = none # Suppress conditional expressions for readability within the Ulid argument converter. \ No newline at end of file diff --git a/src/DSharpPlus.Examples.CommandsNext.CustomCommandArguments/ArgumentConverters/UlidArgumentConverter.cs b/src/DSharpPlus.Examples.CommandsNext.CustomCommandArguments/ArgumentConverters/UlidArgumentConverter.cs deleted file mode 100644 index 42cae36..0000000 --- a/src/DSharpPlus.Examples.CommandsNext.CustomCommandArguments/ArgumentConverters/UlidArgumentConverter.cs +++ /dev/null @@ -1,21 +0,0 @@ -using System; -using System.Threading.Tasks; -using DSharpPlus.CommandsNext; -using DSharpPlus.CommandsNext.Converters; -using DSharpPlus.Entities; - -namespace DSharpPlus.Examples.CommandsNext.CustomCommandArguments.ArgumentConverters -{ - public sealed class UlidArgumentConverter : IArgumentConverter - { - public Task> ConvertAsync(string value, CommandContext ctx) - { - if (Ulid.TryParse(value, out Ulid ulid)) - { - return Task.FromResult(Optional.FromValue(ulid)); - } - - return Task.FromResult(Optional.FromNoValue()); - } - } -} diff --git a/src/DSharpPlus.Examples.CommandsNext.CustomCommandArguments/Commands/.editorconfig b/src/DSharpPlus.Examples.CommandsNext.CustomCommandArguments/Commands/.editorconfig deleted file mode 100644 index 85cd174..0000000 --- a/src/DSharpPlus.Examples.CommandsNext.CustomCommandArguments/Commands/.editorconfig +++ /dev/null @@ -1,5 +0,0 @@ -# .editorconfig -root = false - -[*.{cs,vb}] -dotnet_diagnostic.CA1822.severity = none # Suppress CA1822 due to CommandsNext not supporting static commands. \ No newline at end of file diff --git a/src/DSharpPlus.Examples.CommandsNext.CustomCommandArguments/Commands/CreateUlidCommand.cs b/src/DSharpPlus.Examples.CommandsNext.CustomCommandArguments/Commands/CreateUlidCommand.cs deleted file mode 100644 index 64f95a1..0000000 --- a/src/DSharpPlus.Examples.CommandsNext.CustomCommandArguments/Commands/CreateUlidCommand.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System; -using System.Threading.Tasks; -using DSharpPlus.CommandsNext; -using DSharpPlus.CommandsNext.Attributes; - -namespace DSharpPlus.Examples.CommandsNext.CustomCommandArguments.Commands -{ - public class CreateUlidCommand : BaseCommandModule - { - [Command("create_ulid"), Description("Creates a new Ulid.")] - public async Task ExecuteAsync(CommandContext context) => await context.RespondAsync(Formatter.InlineCode(Ulid.NewUlid().ToString())); - } -} diff --git a/src/DSharpPlus.Examples.CommandsNext.CustomCommandArguments/Commands/UlidInfoCommand.cs b/src/DSharpPlus.Examples.CommandsNext.CustomCommandArguments/Commands/UlidInfoCommand.cs deleted file mode 100644 index eb29d28..0000000 --- a/src/DSharpPlus.Examples.CommandsNext.CustomCommandArguments/Commands/UlidInfoCommand.cs +++ /dev/null @@ -1,25 +0,0 @@ -using System; -using System.Threading.Tasks; -using DSharpPlus.CommandsNext; -using DSharpPlus.CommandsNext.Attributes; -using DSharpPlus.Entities; - -namespace DSharpPlus.Examples.CommandsNext.CustomCommandArguments.Commands -{ - public class UlidInfoCommand : BaseCommandModule - { - [Command("ulid_info"), Description("Returns information about a Ulid.")] - public async Task ExecuteAsync(CommandContext context, Ulid ulid) - { - DiscordEmbedBuilder embedBuilder = new(); - embedBuilder.WithTitle("Ulid Information"); - embedBuilder.WithColor(DiscordColor.Blurple); - embedBuilder.WithDescription($"Ulid: {Formatter.InlineCode(ulid.ToString())}"); - embedBuilder.AddField("Base64", Formatter.InlineCode(ulid.ToBase64())); - embedBuilder.AddField("Timestamp", Formatter.Timestamp(ulid.Time, TimestampFormat.LongDateTime)); - embedBuilder.AddField("Randomness", Formatter.InlineCode(Convert.ToBase64String(ulid.Random))); - - await context.RespondAsync(embedBuilder.Build()); - } - } -} diff --git a/src/DSharpPlus.Examples.CommandsNext.CustomCommandArguments/DSharpPlus.Examples.CommandsNext.CustomCommandArguments.csproj b/src/DSharpPlus.Examples.CommandsNext.CustomCommandArguments/DSharpPlus.Examples.CommandsNext.CustomCommandArguments.csproj deleted file mode 100644 index 30e19ea..0000000 --- a/src/DSharpPlus.Examples.CommandsNext.CustomCommandArguments/DSharpPlus.Examples.CommandsNext.CustomCommandArguments.csproj +++ /dev/null @@ -1,12 +0,0 @@ - - - Exe - net8.0 - enable - - - - - - - \ No newline at end of file diff --git a/src/DSharpPlus.Examples.CommandsNext.CustomCommandArguments/Program.cs b/src/DSharpPlus.Examples.CommandsNext.CustomCommandArguments/Program.cs deleted file mode 100644 index f1a1fe1..0000000 --- a/src/DSharpPlus.Examples.CommandsNext.CustomCommandArguments/Program.cs +++ /dev/null @@ -1,57 +0,0 @@ -using System; -using System.Threading.Tasks; -using DSharpPlus.CommandsNext; -using DSharpPlus.Examples.CommandsNext.CustomCommandArguments.ArgumentConverters; - -namespace DSharpPlus.Examples.CommandsNext.CustomCommandArguments -{ - public static class Program - { - /// - /// The prefixes used to trigger Discord text commands through CommandsNext. - /// - private static readonly string[] _prefixes = new[] { "!" }; - - public static async Task Main() - { - // Check for token - // TODO: Load the token up from IConfiguration - string? token = Environment.GetEnvironmentVariable("DISCORD_TOKEN"); - if (string.IsNullOrWhiteSpace(token)) - { - Console.WriteLine("Please set the environment variable DISCORD_TOKEN."); - return; - } - - // Create the client - DiscordClient discord = new(new DiscordConfiguration - { - Token = token, - Intents = DiscordIntents.AllUnprivileged | DiscordIntents.MessageContents - }); - - CommandsNextExtension commandsNext = discord.UseCommandsNext(new CommandsNextConfiguration() - { - // For brevity, we're going to use the string prefixes property. - // However, if you want to do something complicated, such as per-guild prefixes, - // you can pass a prefix resolver delegate instead. - StringPrefixes = _prefixes - }); - - // Register our argument converters. - // This is a global registration, so these converters will be used for all commands. - commandsNext.RegisterConverter(new UlidArgumentConverter()); - - // If we pass our assembly to CommandsNext, it will automatically - // search our program for any Command classes and register them on its own. - // This is very handy so you don't need to manually update a list when you add a new command. - commandsNext.RegisterCommands(typeof(Program).Assembly); - - // Connect to the Discord gateway - await discord.ConnectAsync(); - - // Wait infinitely so the bot stays connected; DiscordClient.ConnectAsync is not a blocking call - await Task.Delay(-1); - } - } -} diff --git a/src/DSharpPlus.Examples.CommandsNext.ErrorHandling/Commands/.editorconfig b/src/DSharpPlus.Examples.CommandsNext.ErrorHandling/Commands/.editorconfig deleted file mode 100644 index 85cd174..0000000 --- a/src/DSharpPlus.Examples.CommandsNext.ErrorHandling/Commands/.editorconfig +++ /dev/null @@ -1,5 +0,0 @@ -# .editorconfig -root = false - -[*.{cs,vb}] -dotnet_diagnostic.CA1822.severity = none # Suppress CA1822 due to CommandsNext not supporting static commands. \ No newline at end of file diff --git a/src/DSharpPlus.Examples.CommandsNext.ErrorHandling/Commands/ErrorCommand.cs b/src/DSharpPlus.Examples.CommandsNext.ErrorHandling/Commands/ErrorCommand.cs deleted file mode 100644 index 73bd8e4..0000000 --- a/src/DSharpPlus.Examples.CommandsNext.ErrorHandling/Commands/ErrorCommand.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System.Threading.Tasks; -using System.Transactions; -using DSharpPlus.CommandsNext; -using DSharpPlus.CommandsNext.Attributes; - -namespace DSharpPlus.Examples.CommandsNext.ErrorHandling.Commands -{ - public class ErrorCommand : BaseCommandModule - { - // I bet you didn't know this exception existed. - // Unless you did. In which case, my sincerest condolences. - [Command("error"), Description("Throws an exception.")] - public Task ExecuteAsync(CommandContext context) => throw new TransactionManagerCommunicationException("This command is supposed to fail."); - } -} diff --git a/src/DSharpPlus.Examples.CommandsNext.ErrorHandling/DSharpPlus.Examples.CommandsNext.ErrorHandling.csproj b/src/DSharpPlus.Examples.CommandsNext.ErrorHandling/DSharpPlus.Examples.CommandsNext.ErrorHandling.csproj deleted file mode 100644 index aa3e22a..0000000 --- a/src/DSharpPlus.Examples.CommandsNext.ErrorHandling/DSharpPlus.Examples.CommandsNext.ErrorHandling.csproj +++ /dev/null @@ -1,11 +0,0 @@ - - - Exe - net8.0 - enable - - - - - - \ No newline at end of file diff --git a/src/DSharpPlus.Examples.CommandsNext.ErrorHandling/Program.cs b/src/DSharpPlus.Examples.CommandsNext.ErrorHandling/Program.cs deleted file mode 100644 index 1b28725..0000000 --- a/src/DSharpPlus.Examples.CommandsNext.ErrorHandling/Program.cs +++ /dev/null @@ -1,69 +0,0 @@ -using System; -using System.Threading.Tasks; -using DSharpPlus.CommandsNext; -using DSharpPlus.Entities; - -namespace DSharpPlus.Examples.CommandsNext.ErrorHandling -{ - public static class Program - { - /// - /// The prefixes used to trigger Discord text commands through CommandsNext. - /// - private static readonly string[] _prefixes = new[] { "!" }; - - public static async Task Main() - { - // Check for token - // TODO: Load the token up from IConfiguration - string? token = Environment.GetEnvironmentVariable("DISCORD_TOKEN"); - if (string.IsNullOrWhiteSpace(token)) - { - Console.WriteLine("Please set the environment variable DISCORD_TOKEN."); - return; - } - - // Create the client - DiscordClient discord = new(new DiscordConfiguration - { - Token = token, - Intents = DiscordIntents.AllUnprivileged | DiscordIntents.MessageContents - }); - - CommandsNextExtension commandsNext = discord.UseCommandsNext(new CommandsNextConfiguration() - { - // For brevity, we're going to use the string prefixes property. - // However, if you want to do something complicated, such as per-guild prefixes, - // you can pass a prefix resolver delegate instead. - StringPrefixes = _prefixes - }); - - // If we pass our assembly to CommandsNext, it will automatically - // search our program for any Command classes and register them on its own. - // This is very handy so you don't need to manually update a list when you add a new command. - commandsNext.RegisterCommands(typeof(Program).Assembly); - - // Register our error handler - commandsNext.CommandErrored += CommandErroredEventHandlerAsync; - - // Connect to the Discord gateway - await discord.ConnectAsync(); - - // Wait infinitely so the bot stays connected; DiscordClient.ConnectAsync is not a blocking call - await Task.Delay(-1); - } - - private static async Task CommandErroredEventHandlerAsync(CommandsNextExtension extension, CommandErrorEventArgs eventArgs) - { - DiscordEmbedBuilder embedBuilder = new(); - embedBuilder.WithTitle($"An error occurred while executing a command: {eventArgs.Exception.GetType().Name}"); - embedBuilder.WithColor(DiscordColor.DarkRed); - embedBuilder.WithDescription(eventArgs.Exception.Message); - embedBuilder.AddField("Stack Trace", string.IsNullOrWhiteSpace(eventArgs.Exception.StackTrace) - ? "No stack trace available." - : Formatter.BlockCode(eventArgs.Exception.StackTrace.Trim()[3..], "cs")); // The [3..] removes the first three characters (at\n) in the stack trace. - - await eventArgs.Context.RespondAsync(embedBuilder.Build()); - } - } -} diff --git a/src/DSharpPlus.Examples.CommandsNext.GroupCommands/ArgumentConverters/.editorconfig b/src/DSharpPlus.Examples.CommandsNext.GroupCommands/ArgumentConverters/.editorconfig deleted file mode 100644 index 9f997ca..0000000 --- a/src/DSharpPlus.Examples.CommandsNext.GroupCommands/ArgumentConverters/.editorconfig +++ /dev/null @@ -1,5 +0,0 @@ -# .editorconfig -root = false - -[*.{cs,vb}] -dotnet_diagnostic.IDE0046.severity = none # Suppress conditional expressions for readability within the Ulid argument converter. \ No newline at end of file diff --git a/src/DSharpPlus.Examples.CommandsNext.GroupCommands/ArgumentConverters/UlidArgumentConverter.cs b/src/DSharpPlus.Examples.CommandsNext.GroupCommands/ArgumentConverters/UlidArgumentConverter.cs deleted file mode 100644 index 27cbb21..0000000 --- a/src/DSharpPlus.Examples.CommandsNext.GroupCommands/ArgumentConverters/UlidArgumentConverter.cs +++ /dev/null @@ -1,21 +0,0 @@ -using System; -using System.Threading.Tasks; -using DSharpPlus.CommandsNext; -using DSharpPlus.CommandsNext.Converters; -using DSharpPlus.Entities; - -namespace DSharpPlus.Examples.CommandsNext.GroupCommands.ArgumentConverters -{ - public sealed class UlidArgumentConverter : IArgumentConverter - { - public Task> ConvertAsync(string value, CommandContext ctx) - { - if (Ulid.TryParse(value, out Ulid ulid)) - { - return Task.FromResult(Optional.FromValue(ulid)); - } - - return Task.FromResult(Optional.FromNoValue()); - } - } -} diff --git a/src/DSharpPlus.Examples.CommandsNext.GroupCommands/Commands/.editorconfig b/src/DSharpPlus.Examples.CommandsNext.GroupCommands/Commands/.editorconfig deleted file mode 100644 index 85cd174..0000000 --- a/src/DSharpPlus.Examples.CommandsNext.GroupCommands/Commands/.editorconfig +++ /dev/null @@ -1,5 +0,0 @@ -# .editorconfig -root = false - -[*.{cs,vb}] -dotnet_diagnostic.CA1822.severity = none # Suppress CA1822 due to CommandsNext not supporting static commands. \ No newline at end of file diff --git a/src/DSharpPlus.Examples.CommandsNext.GroupCommands/Commands/UlidCommand.cs b/src/DSharpPlus.Examples.CommandsNext.GroupCommands/Commands/UlidCommand.cs deleted file mode 100644 index a6908c7..0000000 --- a/src/DSharpPlus.Examples.CommandsNext.GroupCommands/Commands/UlidCommand.cs +++ /dev/null @@ -1,37 +0,0 @@ -using System; -using System.Threading.Tasks; -using DSharpPlus.CommandsNext; -using DSharpPlus.CommandsNext.Attributes; -using DSharpPlus.Entities; - -namespace DSharpPlus.Examples.CommandsNext.GroupCommands.Commands -{ - // Group is how a command can have subcommands. - [Group("ulid"), Description("Ulid utility commands.")] - public class UlidCommand : BaseCommandModule - { - // The group command is executed when no subcommands are specified. - // It's allowed to have arguments and such, just like a normal command. - [GroupCommand] - public async Task ExecuteAsync(CommandContext context) => await context.RespondAsync($"Ulid utility commands. Use `help ulid` for subcommands. The current Ulid is {Formatter.InlineCode(Ulid.NewUlid().ToString())}"); - - // This subcommand is executed as `!ulid create` - [Command("create"), Description("Generate a new ULID.")] - public async Task CreateAsync(CommandContext context) => await context.RespondAsync(Formatter.InlineCode(Ulid.NewUlid().ToString())); - - // The user would run this subcommand as `!ulid info 01HBF5ZGDHXAJ85HKMBGCJTT99`, where `01HBF5ZGDHXAJ85HKMBGCJTT99` is any valid Ulid. - [Command("info"), Description("Returns information about a Ulid.")] - public async Task ExecuteAsync(CommandContext context, Ulid ulid) - { - DiscordEmbedBuilder embedBuilder = new(); - embedBuilder.WithTitle("Ulid Information"); - embedBuilder.WithColor(DiscordColor.Blurple); - embedBuilder.WithDescription($"Ulid: {Formatter.InlineCode(ulid.ToString())}"); - embedBuilder.AddField("Base64", Formatter.InlineCode(ulid.ToBase64())); - embedBuilder.AddField("Timestamp", Formatter.Timestamp(ulid.Time, TimestampFormat.LongDateTime)); - embedBuilder.AddField("Randomness", Formatter.InlineCode(Convert.ToBase64String(ulid.Random))); - - await context.RespondAsync(embedBuilder.Build()); - } - } -} diff --git a/src/DSharpPlus.Examples.CommandsNext.GroupCommands/DSharpPlus.Examples.CommandsNext.GroupCommands.csproj b/src/DSharpPlus.Examples.CommandsNext.GroupCommands/DSharpPlus.Examples.CommandsNext.GroupCommands.csproj deleted file mode 100644 index 30e19ea..0000000 --- a/src/DSharpPlus.Examples.CommandsNext.GroupCommands/DSharpPlus.Examples.CommandsNext.GroupCommands.csproj +++ /dev/null @@ -1,12 +0,0 @@ - - - Exe - net8.0 - enable - - - - - - - \ No newline at end of file diff --git a/src/DSharpPlus.Examples.CommandsNext.GroupCommands/Program.cs b/src/DSharpPlus.Examples.CommandsNext.GroupCommands/Program.cs deleted file mode 100644 index 6f9e3e3..0000000 --- a/src/DSharpPlus.Examples.CommandsNext.GroupCommands/Program.cs +++ /dev/null @@ -1,57 +0,0 @@ -using System; -using System.Threading.Tasks; -using DSharpPlus.CommandsNext; -using DSharpPlus.Examples.CommandsNext.GroupCommands.ArgumentConverters; - -namespace DSharpPlus.Examples.CommandsNext.GroupCommands -{ - public static class Program - { - /// - /// The prefixes used to trigger Discord text commands through CommandsNext. - /// - private static readonly string[] _prefixes = new[] { "!" }; - - public static async Task Main() - { - // Check for token - // TODO: Load the token up from IConfiguration - string? token = Environment.GetEnvironmentVariable("DISCORD_TOKEN"); - if (string.IsNullOrWhiteSpace(token)) - { - Console.WriteLine("Please set the environment variable DISCORD_TOKEN."); - return; - } - - // Create the client - DiscordClient discord = new(new DiscordConfiguration - { - Token = token, - Intents = DiscordIntents.AllUnprivileged | DiscordIntents.MessageContents - }); - - CommandsNextExtension commandsNext = discord.UseCommandsNext(new CommandsNextConfiguration() - { - // For brevity, we're going to use the string prefixes property. - // However, if you want to do something complicated, such as per-guild prefixes, - // you can pass a prefix resolver delegate instead. - StringPrefixes = _prefixes - }); - - // Register our argument converters. - // This is a global registration, so these converters will be used for all commands. - commandsNext.RegisterConverter(new UlidArgumentConverter()); - - // If we pass our assembly to CommandsNext, it will automatically - // search our program for any Command classes and register them on its own. - // This is very handy so you don't need to manually update a list when you add a new command. - commandsNext.RegisterCommands(typeof(Program).Assembly); - - // Connect to the Discord gateway - await discord.ConnectAsync(); - - // Wait infinitely so the bot stays connected; DiscordClient.ConnectAsync is not a blocking call - await Task.Delay(-1); - } - } -} From 09af9a18a7d19a52df9b9dae31cf1f95e40d2ff0 Mon Sep 17 00:00:00 2001 From: InFTord Date: Thu, 1 Feb 2024 23:17:27 +0500 Subject: [PATCH 4/7] update to latest commands version --- .../DSharpPlus.Examples.Commands.Basics.csproj | 2 +- src/DSharpPlus.Examples.Commands.Basics/Program.cs | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/DSharpPlus.Examples.Commands.Basics/DSharpPlus.Examples.Commands.Basics.csproj b/src/DSharpPlus.Examples.Commands.Basics/DSharpPlus.Examples.Commands.Basics.csproj index 2ae2714..71e90e4 100644 --- a/src/DSharpPlus.Examples.Commands.Basics/DSharpPlus.Examples.Commands.Basics.csproj +++ b/src/DSharpPlus.Examples.Commands.Basics/DSharpPlus.Examples.Commands.Basics.csproj @@ -7,7 +7,7 @@ - + diff --git a/src/DSharpPlus.Examples.Commands.Basics/Program.cs b/src/DSharpPlus.Examples.Commands.Basics/Program.cs index 8f1ec20..5254509 100644 --- a/src/DSharpPlus.Examples.Commands.Basics/Program.cs +++ b/src/DSharpPlus.Examples.Commands.Basics/Program.cs @@ -14,7 +14,6 @@ public static class Program public static async Task Main(string[] args) { ConfigurationBuilder configurationBuilder = new(); - configurationBuilder.Sources.Clear(); configurationBuilder.AddEnvironmentVariables(""); configurationBuilder.AddCommandLine(args); From c50e6ffce61bdce7527ab4274bc87018e6b75005 Mon Sep 17 00:00:00 2001 From: InFTord Date: Thu, 1 Feb 2024 23:22:09 +0500 Subject: [PATCH 5/7] do changes that Lunar requested --- src/DSharpPlus.Examples.Commands.Basics/Program.cs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/DSharpPlus.Examples.Commands.Basics/Program.cs b/src/DSharpPlus.Examples.Commands.Basics/Program.cs index 5254509..5cbedf8 100644 --- a/src/DSharpPlus.Examples.Commands.Basics/Program.cs +++ b/src/DSharpPlus.Examples.Commands.Basics/Program.cs @@ -4,6 +4,7 @@ using DSharpPlus.Commands; using DSharpPlus.Commands.Processors.SlashCommands; using DSharpPlus.Commands.Processors.TextCommands; +using DSharpPlus.Commands.Processors.TextCommands.Parsing; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; @@ -22,31 +23,30 @@ public static async Task Main(string[] args) serviceCollection.AddSingleton(configuration); Assembly currentAssembly = typeof(Program).Assembly; - - serviceCollection.AddSingleton(serviceProvider => + serviceCollection.AddSingleton(async serviceProvider => { DiscordClient client = new(new DiscordConfiguration() { Token = configuration.GetValue("discord:token") ?? throw new InvalidOperationException("Missing Discord token."), - Intents = DiscordIntents.AllUnprivileged | DiscordIntents.MessageContents + Intents = DiscordIntents.AllUnprivileged | DiscordIntents.MessageContents | TextCommandProcessor.RequiredIntents }); CommandsExtension extension = client.UseCommands(new() { DebugGuildId = configuration.GetValue("discord:debug_guild_id", null), ServiceProvider = serviceProvider, + }); - - extension.AddProcessorAsync(new TextCommandProcessor()); - extension.AddProcessorAsync(new SlashCommandProcessor()); + await extension.AddProcessorAsync(new TextCommandProcessor()); + await extension.AddProcessorAsync(new SlashCommandProcessor()); extension.AddCommands(currentAssembly); return client; }); IServiceProvider serviceProvider = serviceCollection.BuildServiceProvider(); - DiscordClient client = serviceProvider.GetRequiredService(); + DiscordClient client = await serviceProvider.GetRequiredService>(); await client.ConnectAsync(); await Task.Delay(-1); From 3162da394222295d37749505704d5adc2dc2f5f5 Mon Sep 17 00:00:00 2001 From: InFTord Date: Fri, 2 Feb 2024 23:41:53 +0500 Subject: [PATCH 6/7] use json config by default instead of env vars --- .../DSharpPlus.Examples.Commands.Basics.csproj | 2 ++ src/DSharpPlus.Examples.Commands.Basics/Program.cs | 8 +++++--- src/DSharpPlus.Examples.Commands.Basics/config.json | 6 ++++++ 3 files changed, 13 insertions(+), 3 deletions(-) create mode 100644 src/DSharpPlus.Examples.Commands.Basics/config.json diff --git a/src/DSharpPlus.Examples.Commands.Basics/DSharpPlus.Examples.Commands.Basics.csproj b/src/DSharpPlus.Examples.Commands.Basics/DSharpPlus.Examples.Commands.Basics.csproj index 71e90e4..809351d 100644 --- a/src/DSharpPlus.Examples.Commands.Basics/DSharpPlus.Examples.Commands.Basics.csproj +++ b/src/DSharpPlus.Examples.Commands.Basics/DSharpPlus.Examples.Commands.Basics.csproj @@ -6,11 +6,13 @@ DSharpPlus.Examples.Commands.Basics + + \ No newline at end of file diff --git a/src/DSharpPlus.Examples.Commands.Basics/Program.cs b/src/DSharpPlus.Examples.Commands.Basics/Program.cs index 5cbedf8..b28be89 100644 --- a/src/DSharpPlus.Examples.Commands.Basics/Program.cs +++ b/src/DSharpPlus.Examples.Commands.Basics/Program.cs @@ -15,7 +15,9 @@ public static class Program public static async Task Main(string[] args) { ConfigurationBuilder configurationBuilder = new(); - configurationBuilder.AddEnvironmentVariables(""); + // you can also use environment vars, just uncomment this + // configurationBuilder.AddEnvironmentVariables(""); + configurationBuilder.AddJsonFile("config.json", true, true); configurationBuilder.AddCommandLine(args); IConfiguration configuration = configurationBuilder.Build(); @@ -27,14 +29,14 @@ public static async Task Main(string[] args) { DiscordClient client = new(new DiscordConfiguration() { - Token = configuration.GetValue("discord:token") ?? + Token = configuration.GetValue("example_bot:token") ?? throw new InvalidOperationException("Missing Discord token."), Intents = DiscordIntents.AllUnprivileged | DiscordIntents.MessageContents | TextCommandProcessor.RequiredIntents }); CommandsExtension extension = client.UseCommands(new() { - DebugGuildId = configuration.GetValue("discord:debug_guild_id", null), + DebugGuildId = configuration.GetValue("example_bot:debug_guild_id", null), ServiceProvider = serviceProvider, }); diff --git a/src/DSharpPlus.Examples.Commands.Basics/config.json b/src/DSharpPlus.Examples.Commands.Basics/config.json new file mode 100644 index 0000000..ba8b42b --- /dev/null +++ b/src/DSharpPlus.Examples.Commands.Basics/config.json @@ -0,0 +1,6 @@ +{ + "example_bot": { + "token": "bottoken", + "debug_guild_id": "" + } +} \ No newline at end of file From 591930015e03fd64a7241c0e751c3d9e8941a895 Mon Sep 17 00:00:00 2001 From: InFTord Date: Sat, 3 Feb 2024 16:38:41 +0500 Subject: [PATCH 7/7] Revert "murder CNext examples" This reverts commit c3aa229f2131be199964e923e1afa9505007f192. --- Example-Bots.sln | 28 ++++++++ .../Commands/.editorconfig | 5 ++ .../Commands/AvatarCommand.cs | 25 +++++++ .../Commands/HttpCat.cs | 31 +++++++++ ...mples.CommandsNext.CommandArguments.csproj | 11 +++ .../Program.cs | 52 ++++++++++++++ .../ArgumentConverters/.editorconfig | 5 ++ .../UlidArgumentConverter.cs | 21 ++++++ .../Commands/.editorconfig | 5 ++ .../Commands/CreateUlidCommand.cs | 13 ++++ .../Commands/UlidInfoCommand.cs | 25 +++++++ ...CommandsNext.CustomCommandArguments.csproj | 12 ++++ .../Program.cs | 57 +++++++++++++++ .../Commands/.editorconfig | 5 ++ .../Commands/ErrorCommand.cs | 15 ++++ ...Examples.CommandsNext.ErrorHandling.csproj | 11 +++ .../Program.cs | 69 +++++++++++++++++++ .../ArgumentConverters/.editorconfig | 5 ++ .../UlidArgumentConverter.cs | 21 ++++++ .../Commands/.editorconfig | 5 ++ .../Commands/UlidCommand.cs | 37 ++++++++++ ...Examples.CommandsNext.GroupCommands.csproj | 12 ++++ .../Program.cs | 57 +++++++++++++++ 23 files changed, 527 insertions(+) create mode 100644 src/DSharpPlus.Examples.CommandsNext.CommandArguments/Commands/.editorconfig create mode 100644 src/DSharpPlus.Examples.CommandsNext.CommandArguments/Commands/AvatarCommand.cs create mode 100644 src/DSharpPlus.Examples.CommandsNext.CommandArguments/Commands/HttpCat.cs create mode 100644 src/DSharpPlus.Examples.CommandsNext.CommandArguments/DSharpPlus.Examples.CommandsNext.CommandArguments.csproj create mode 100644 src/DSharpPlus.Examples.CommandsNext.CommandArguments/Program.cs create mode 100644 src/DSharpPlus.Examples.CommandsNext.CustomCommandArguments/ArgumentConverters/.editorconfig create mode 100644 src/DSharpPlus.Examples.CommandsNext.CustomCommandArguments/ArgumentConverters/UlidArgumentConverter.cs create mode 100644 src/DSharpPlus.Examples.CommandsNext.CustomCommandArguments/Commands/.editorconfig create mode 100644 src/DSharpPlus.Examples.CommandsNext.CustomCommandArguments/Commands/CreateUlidCommand.cs create mode 100644 src/DSharpPlus.Examples.CommandsNext.CustomCommandArguments/Commands/UlidInfoCommand.cs create mode 100644 src/DSharpPlus.Examples.CommandsNext.CustomCommandArguments/DSharpPlus.Examples.CommandsNext.CustomCommandArguments.csproj create mode 100644 src/DSharpPlus.Examples.CommandsNext.CustomCommandArguments/Program.cs create mode 100644 src/DSharpPlus.Examples.CommandsNext.ErrorHandling/Commands/.editorconfig create mode 100644 src/DSharpPlus.Examples.CommandsNext.ErrorHandling/Commands/ErrorCommand.cs create mode 100644 src/DSharpPlus.Examples.CommandsNext.ErrorHandling/DSharpPlus.Examples.CommandsNext.ErrorHandling.csproj create mode 100644 src/DSharpPlus.Examples.CommandsNext.ErrorHandling/Program.cs create mode 100644 src/DSharpPlus.Examples.CommandsNext.GroupCommands/ArgumentConverters/.editorconfig create mode 100644 src/DSharpPlus.Examples.CommandsNext.GroupCommands/ArgumentConverters/UlidArgumentConverter.cs create mode 100644 src/DSharpPlus.Examples.CommandsNext.GroupCommands/Commands/.editorconfig create mode 100644 src/DSharpPlus.Examples.CommandsNext.GroupCommands/Commands/UlidCommand.cs create mode 100644 src/DSharpPlus.Examples.CommandsNext.GroupCommands/DSharpPlus.Examples.CommandsNext.GroupCommands.csproj create mode 100644 src/DSharpPlus.Examples.CommandsNext.GroupCommands/Program.cs diff --git a/Example-Bots.sln b/Example-Bots.sln index 4da8623..d9bd3fe 100644 --- a/Example-Bots.sln +++ b/Example-Bots.sln @@ -19,6 +19,14 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DSharpPlus.Examples.Compone EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DSharpPlus.Examples.Commands.Basics", "src\DSharpPlus.Examples.Commands.Basics\DSharpPlus.Examples.Commands.Basics.csproj", "{7135C15F-A8FD-4CEB-BA07-ED45FFBFFFF5}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DSharpPlus.Examples.CommandsNext.CommandArguments", "src\DSharpPlus.Examples.CommandsNext.CommandArguments\DSharpPlus.Examples.CommandsNext.CommandArguments.csproj", "{1159DF74-2834-4A7B-97C2-384C8578F6A6}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DSharpPlus.Examples.CommandsNext.CustomCommandArguments", "src\DSharpPlus.Examples.CommandsNext.CustomCommandArguments\DSharpPlus.Examples.CommandsNext.CustomCommandArguments.csproj", "{9424B2A1-C411-4B1E-A0C3-48CAA91CDC4B}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DSharpPlus.Examples.CommandsNext.ErrorHandling", "src\DSharpPlus.Examples.CommandsNext.ErrorHandling\DSharpPlus.Examples.CommandsNext.ErrorHandling.csproj", "{6E106DAA-D075-4AD2-AA10-41327B9D3FF4}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DSharpPlus.Examples.CommandsNext.GroupCommands", "src\DSharpPlus.Examples.CommandsNext.GroupCommands\DSharpPlus.Examples.CommandsNext.GroupCommands.csproj", "{5A3B56EC-DD5E-4D15-859B-94B09ADC2795}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -56,6 +64,22 @@ Global {7135C15F-A8FD-4CEB-BA07-ED45FFBFFFF5}.Debug|Any CPU.Build.0 = Debug|Any CPU {7135C15F-A8FD-4CEB-BA07-ED45FFBFFFF5}.Release|Any CPU.ActiveCfg = Release|Any CPU {7135C15F-A8FD-4CEB-BA07-ED45FFBFFFF5}.Release|Any CPU.Build.0 = Release|Any CPU + {1159DF74-2834-4A7B-97C2-384C8578F6A6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1159DF74-2834-4A7B-97C2-384C8578F6A6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1159DF74-2834-4A7B-97C2-384C8578F6A6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1159DF74-2834-4A7B-97C2-384C8578F6A6}.Release|Any CPU.Build.0 = Release|Any CPU + {9424B2A1-C411-4B1E-A0C3-48CAA91CDC4B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9424B2A1-C411-4B1E-A0C3-48CAA91CDC4B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9424B2A1-C411-4B1E-A0C3-48CAA91CDC4B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9424B2A1-C411-4B1E-A0C3-48CAA91CDC4B}.Release|Any CPU.Build.0 = Release|Any CPU + {6E106DAA-D075-4AD2-AA10-41327B9D3FF4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6E106DAA-D075-4AD2-AA10-41327B9D3FF4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6E106DAA-D075-4AD2-AA10-41327B9D3FF4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6E106DAA-D075-4AD2-AA10-41327B9D3FF4}.Release|Any CPU.Build.0 = Release|Any CPU + {5A3B56EC-DD5E-4D15-859B-94B09ADC2795}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5A3B56EC-DD5E-4D15-859B-94B09ADC2795}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5A3B56EC-DD5E-4D15-859B-94B09ADC2795}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5A3B56EC-DD5E-4D15-859B-94B09ADC2795}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(NestedProjects) = preSolution {43280D9F-9965-4270-9082-12029948F559} = {1DE5170D-7FE0-487D-9EAF-5327832D8A4B} @@ -65,5 +89,9 @@ Global {00471D68-8D82-469D-959F-1B6058248A15} = {1DE5170D-7FE0-487D-9EAF-5327832D8A4B} {C5197139-4026-4EE9-A301-136FC3E10DA3} = {1DE5170D-7FE0-487D-9EAF-5327832D8A4B} {7135C15F-A8FD-4CEB-BA07-ED45FFBFFFF5} = {1DE5170D-7FE0-487D-9EAF-5327832D8A4B} + {1159DF74-2834-4A7B-97C2-384C8578F6A6} = {1DE5170D-7FE0-487D-9EAF-5327832D8A4B} + {9424B2A1-C411-4B1E-A0C3-48CAA91CDC4B} = {1DE5170D-7FE0-487D-9EAF-5327832D8A4B} + {6E106DAA-D075-4AD2-AA10-41327B9D3FF4} = {1DE5170D-7FE0-487D-9EAF-5327832D8A4B} + {5A3B56EC-DD5E-4D15-859B-94B09ADC2795} = {1DE5170D-7FE0-487D-9EAF-5327832D8A4B} EndGlobalSection EndGlobal diff --git a/src/DSharpPlus.Examples.CommandsNext.CommandArguments/Commands/.editorconfig b/src/DSharpPlus.Examples.CommandsNext.CommandArguments/Commands/.editorconfig new file mode 100644 index 0000000..85cd174 --- /dev/null +++ b/src/DSharpPlus.Examples.CommandsNext.CommandArguments/Commands/.editorconfig @@ -0,0 +1,5 @@ +# .editorconfig +root = false + +[*.{cs,vb}] +dotnet_diagnostic.CA1822.severity = none # Suppress CA1822 due to CommandsNext not supporting static commands. \ No newline at end of file diff --git a/src/DSharpPlus.Examples.CommandsNext.CommandArguments/Commands/AvatarCommand.cs b/src/DSharpPlus.Examples.CommandsNext.CommandArguments/Commands/AvatarCommand.cs new file mode 100644 index 0000000..662fb73 --- /dev/null +++ b/src/DSharpPlus.Examples.CommandsNext.CommandArguments/Commands/AvatarCommand.cs @@ -0,0 +1,25 @@ +using System.Threading.Tasks; +using DSharpPlus.CommandsNext; +using DSharpPlus.CommandsNext.Attributes; +using DSharpPlus.Entities; + +namespace DSharpPlus.Examples.CommandsNext.CommandArguments.Commands +{ + public class AvatarCommand : BaseCommandModule + { + // We can just request for a DiscordMember directly here. The user will either ping the member, send the member's ID, or send the member's username. + // Regardless of input, CommandsNext will do it's best to parse it into a DiscordMember. + [Command("avatar"), Description("Sends the requested user's profile picture in it's own message for easy viewing.")] + public async Task ExecuteAsync(CommandContext context, DiscordMember member) => await context.RespondAsync(member.AvatarUrl); + + // Oh, but what if the DiscordMember isn't in the server? Well, CommandsNext will fallback to the next overload (this command!) + // This time though, we'll need a user mention or user id. Usernames won't work here. + [Command("avatar")] + public async Task ExecuteAsync(CommandContext context, DiscordUser user) => await context.RespondAsync(user.AvatarUrl); + + // What if no arguments are provided? CommandsNext will intelligently execute this overload first, since it has no arguments. + // For now we'll just send the user's avatar. + [Command("avatar")] + public async Task ExecuteAsync(CommandContext context) => await context.RespondAsync(context.User.AvatarUrl); + } +} diff --git a/src/DSharpPlus.Examples.CommandsNext.CommandArguments/Commands/HttpCat.cs b/src/DSharpPlus.Examples.CommandsNext.CommandArguments/Commands/HttpCat.cs new file mode 100644 index 0000000..6bf6320 --- /dev/null +++ b/src/DSharpPlus.Examples.CommandsNext.CommandArguments/Commands/HttpCat.cs @@ -0,0 +1,31 @@ +using System; +using System.Net; +using System.Threading.Tasks; +using DSharpPlus.CommandsNext; +using DSharpPlus.CommandsNext.Attributes; + +namespace DSharpPlus.Examples.CommandsNext.CommandArguments.Commands +{ + public class HttpCatCommand : BaseCommandModule + { + // Sometimes, when my strings get really long, I like to put them in constants. + private const string HTTP_COMMAND = "httpcat"; + private const string HTTP_COMMAND_DESCRIPTION = "Returns a http.cat image for the provided HTTP status code."; + private const string HTTP_COMMAND_CODE_DESCRIPTION = "An optional parameter to specify which http code to send. If no argument is provided, a random http code is chosen."; + + private static readonly HttpStatusCode[] _validHttpCodes = Enum.GetValues(); + + // Because the code parameter has a default value (null), this makes the parameter optional. + // Parameters do NOT become optional when they're nullable. + // Parameters DO become optional when they have a default value. + [Command(HTTP_COMMAND), Description(HTTP_COMMAND_DESCRIPTION)] + public async Task ExecuteAsync(CommandContext context, [Description(HTTP_COMMAND_CODE_DESCRIPTION)] int? code = null) + { + // If no code is provided, we'll just pick a random one. + code ??= (int)_validHttpCodes[Random.Shared.Next(_validHttpCodes.Length)]; + + // Cast to an int so we can use it in the URL. + await context.RespondAsync($"https://http.cat/{code}"); + } + } +} diff --git a/src/DSharpPlus.Examples.CommandsNext.CommandArguments/DSharpPlus.Examples.CommandsNext.CommandArguments.csproj b/src/DSharpPlus.Examples.CommandsNext.CommandArguments/DSharpPlus.Examples.CommandsNext.CommandArguments.csproj new file mode 100644 index 0000000..aa3e22a --- /dev/null +++ b/src/DSharpPlus.Examples.CommandsNext.CommandArguments/DSharpPlus.Examples.CommandsNext.CommandArguments.csproj @@ -0,0 +1,11 @@ + + + Exe + net8.0 + enable + + + + + + \ No newline at end of file diff --git a/src/DSharpPlus.Examples.CommandsNext.CommandArguments/Program.cs b/src/DSharpPlus.Examples.CommandsNext.CommandArguments/Program.cs new file mode 100644 index 0000000..442c545 --- /dev/null +++ b/src/DSharpPlus.Examples.CommandsNext.CommandArguments/Program.cs @@ -0,0 +1,52 @@ +using System; +using System.Threading.Tasks; +using DSharpPlus.CommandsNext; + +namespace DSharpPlus.Examples.CommandsNext.CommandArguments +{ + public static class Program + { + /// + /// The prefixes used to trigger Discord text commands through CommandsNext. + /// + private static readonly string[] _prefixes = new[] { "!" }; + + public static async Task Main() + { + // Check for token + // TODO: Load the token up from IConfiguration + string? token = Environment.GetEnvironmentVariable("DISCORD_TOKEN"); + if (string.IsNullOrWhiteSpace(token)) + { + Console.WriteLine("Please set the environment variable DISCORD_TOKEN."); + return; + } + + // Create the client + DiscordClient discord = new(new DiscordConfiguration + { + Token = token, + Intents = DiscordIntents.AllUnprivileged | DiscordIntents.MessageContents + }); + + CommandsNextExtension commandsNext = discord.UseCommandsNext(new CommandsNextConfiguration() + { + // For brevity, we're going to use the string prefixes property. + // However, if you want to do something complicated, such as per-guild prefixes, + // you can pass a prefix resolver delegate instead. + StringPrefixes = _prefixes + }); + + // If we pass our assembly to CommandsNext, it will automatically + // search our program for any Command classes and register them on its own. + // This is very handy so you don't need to manually update a list when you add a new command. + commandsNext.RegisterCommands(typeof(Program).Assembly); + + // Connect to the Discord gateway + await discord.ConnectAsync(); + + // Wait infinitely so the bot stays connected; DiscordClient.ConnectAsync is not a blocking call + await Task.Delay(-1); + } + } +} diff --git a/src/DSharpPlus.Examples.CommandsNext.CustomCommandArguments/ArgumentConverters/.editorconfig b/src/DSharpPlus.Examples.CommandsNext.CustomCommandArguments/ArgumentConverters/.editorconfig new file mode 100644 index 0000000..9f997ca --- /dev/null +++ b/src/DSharpPlus.Examples.CommandsNext.CustomCommandArguments/ArgumentConverters/.editorconfig @@ -0,0 +1,5 @@ +# .editorconfig +root = false + +[*.{cs,vb}] +dotnet_diagnostic.IDE0046.severity = none # Suppress conditional expressions for readability within the Ulid argument converter. \ No newline at end of file diff --git a/src/DSharpPlus.Examples.CommandsNext.CustomCommandArguments/ArgumentConverters/UlidArgumentConverter.cs b/src/DSharpPlus.Examples.CommandsNext.CustomCommandArguments/ArgumentConverters/UlidArgumentConverter.cs new file mode 100644 index 0000000..42cae36 --- /dev/null +++ b/src/DSharpPlus.Examples.CommandsNext.CustomCommandArguments/ArgumentConverters/UlidArgumentConverter.cs @@ -0,0 +1,21 @@ +using System; +using System.Threading.Tasks; +using DSharpPlus.CommandsNext; +using DSharpPlus.CommandsNext.Converters; +using DSharpPlus.Entities; + +namespace DSharpPlus.Examples.CommandsNext.CustomCommandArguments.ArgumentConverters +{ + public sealed class UlidArgumentConverter : IArgumentConverter + { + public Task> ConvertAsync(string value, CommandContext ctx) + { + if (Ulid.TryParse(value, out Ulid ulid)) + { + return Task.FromResult(Optional.FromValue(ulid)); + } + + return Task.FromResult(Optional.FromNoValue()); + } + } +} diff --git a/src/DSharpPlus.Examples.CommandsNext.CustomCommandArguments/Commands/.editorconfig b/src/DSharpPlus.Examples.CommandsNext.CustomCommandArguments/Commands/.editorconfig new file mode 100644 index 0000000..85cd174 --- /dev/null +++ b/src/DSharpPlus.Examples.CommandsNext.CustomCommandArguments/Commands/.editorconfig @@ -0,0 +1,5 @@ +# .editorconfig +root = false + +[*.{cs,vb}] +dotnet_diagnostic.CA1822.severity = none # Suppress CA1822 due to CommandsNext not supporting static commands. \ No newline at end of file diff --git a/src/DSharpPlus.Examples.CommandsNext.CustomCommandArguments/Commands/CreateUlidCommand.cs b/src/DSharpPlus.Examples.CommandsNext.CustomCommandArguments/Commands/CreateUlidCommand.cs new file mode 100644 index 0000000..64f95a1 --- /dev/null +++ b/src/DSharpPlus.Examples.CommandsNext.CustomCommandArguments/Commands/CreateUlidCommand.cs @@ -0,0 +1,13 @@ +using System; +using System.Threading.Tasks; +using DSharpPlus.CommandsNext; +using DSharpPlus.CommandsNext.Attributes; + +namespace DSharpPlus.Examples.CommandsNext.CustomCommandArguments.Commands +{ + public class CreateUlidCommand : BaseCommandModule + { + [Command("create_ulid"), Description("Creates a new Ulid.")] + public async Task ExecuteAsync(CommandContext context) => await context.RespondAsync(Formatter.InlineCode(Ulid.NewUlid().ToString())); + } +} diff --git a/src/DSharpPlus.Examples.CommandsNext.CustomCommandArguments/Commands/UlidInfoCommand.cs b/src/DSharpPlus.Examples.CommandsNext.CustomCommandArguments/Commands/UlidInfoCommand.cs new file mode 100644 index 0000000..eb29d28 --- /dev/null +++ b/src/DSharpPlus.Examples.CommandsNext.CustomCommandArguments/Commands/UlidInfoCommand.cs @@ -0,0 +1,25 @@ +using System; +using System.Threading.Tasks; +using DSharpPlus.CommandsNext; +using DSharpPlus.CommandsNext.Attributes; +using DSharpPlus.Entities; + +namespace DSharpPlus.Examples.CommandsNext.CustomCommandArguments.Commands +{ + public class UlidInfoCommand : BaseCommandModule + { + [Command("ulid_info"), Description("Returns information about a Ulid.")] + public async Task ExecuteAsync(CommandContext context, Ulid ulid) + { + DiscordEmbedBuilder embedBuilder = new(); + embedBuilder.WithTitle("Ulid Information"); + embedBuilder.WithColor(DiscordColor.Blurple); + embedBuilder.WithDescription($"Ulid: {Formatter.InlineCode(ulid.ToString())}"); + embedBuilder.AddField("Base64", Formatter.InlineCode(ulid.ToBase64())); + embedBuilder.AddField("Timestamp", Formatter.Timestamp(ulid.Time, TimestampFormat.LongDateTime)); + embedBuilder.AddField("Randomness", Formatter.InlineCode(Convert.ToBase64String(ulid.Random))); + + await context.RespondAsync(embedBuilder.Build()); + } + } +} diff --git a/src/DSharpPlus.Examples.CommandsNext.CustomCommandArguments/DSharpPlus.Examples.CommandsNext.CustomCommandArguments.csproj b/src/DSharpPlus.Examples.CommandsNext.CustomCommandArguments/DSharpPlus.Examples.CommandsNext.CustomCommandArguments.csproj new file mode 100644 index 0000000..30e19ea --- /dev/null +++ b/src/DSharpPlus.Examples.CommandsNext.CustomCommandArguments/DSharpPlus.Examples.CommandsNext.CustomCommandArguments.csproj @@ -0,0 +1,12 @@ + + + Exe + net8.0 + enable + + + + + + + \ No newline at end of file diff --git a/src/DSharpPlus.Examples.CommandsNext.CustomCommandArguments/Program.cs b/src/DSharpPlus.Examples.CommandsNext.CustomCommandArguments/Program.cs new file mode 100644 index 0000000..f1a1fe1 --- /dev/null +++ b/src/DSharpPlus.Examples.CommandsNext.CustomCommandArguments/Program.cs @@ -0,0 +1,57 @@ +using System; +using System.Threading.Tasks; +using DSharpPlus.CommandsNext; +using DSharpPlus.Examples.CommandsNext.CustomCommandArguments.ArgumentConverters; + +namespace DSharpPlus.Examples.CommandsNext.CustomCommandArguments +{ + public static class Program + { + /// + /// The prefixes used to trigger Discord text commands through CommandsNext. + /// + private static readonly string[] _prefixes = new[] { "!" }; + + public static async Task Main() + { + // Check for token + // TODO: Load the token up from IConfiguration + string? token = Environment.GetEnvironmentVariable("DISCORD_TOKEN"); + if (string.IsNullOrWhiteSpace(token)) + { + Console.WriteLine("Please set the environment variable DISCORD_TOKEN."); + return; + } + + // Create the client + DiscordClient discord = new(new DiscordConfiguration + { + Token = token, + Intents = DiscordIntents.AllUnprivileged | DiscordIntents.MessageContents + }); + + CommandsNextExtension commandsNext = discord.UseCommandsNext(new CommandsNextConfiguration() + { + // For brevity, we're going to use the string prefixes property. + // However, if you want to do something complicated, such as per-guild prefixes, + // you can pass a prefix resolver delegate instead. + StringPrefixes = _prefixes + }); + + // Register our argument converters. + // This is a global registration, so these converters will be used for all commands. + commandsNext.RegisterConverter(new UlidArgumentConverter()); + + // If we pass our assembly to CommandsNext, it will automatically + // search our program for any Command classes and register them on its own. + // This is very handy so you don't need to manually update a list when you add a new command. + commandsNext.RegisterCommands(typeof(Program).Assembly); + + // Connect to the Discord gateway + await discord.ConnectAsync(); + + // Wait infinitely so the bot stays connected; DiscordClient.ConnectAsync is not a blocking call + await Task.Delay(-1); + } + } +} diff --git a/src/DSharpPlus.Examples.CommandsNext.ErrorHandling/Commands/.editorconfig b/src/DSharpPlus.Examples.CommandsNext.ErrorHandling/Commands/.editorconfig new file mode 100644 index 0000000..85cd174 --- /dev/null +++ b/src/DSharpPlus.Examples.CommandsNext.ErrorHandling/Commands/.editorconfig @@ -0,0 +1,5 @@ +# .editorconfig +root = false + +[*.{cs,vb}] +dotnet_diagnostic.CA1822.severity = none # Suppress CA1822 due to CommandsNext not supporting static commands. \ No newline at end of file diff --git a/src/DSharpPlus.Examples.CommandsNext.ErrorHandling/Commands/ErrorCommand.cs b/src/DSharpPlus.Examples.CommandsNext.ErrorHandling/Commands/ErrorCommand.cs new file mode 100644 index 0000000..73bd8e4 --- /dev/null +++ b/src/DSharpPlus.Examples.CommandsNext.ErrorHandling/Commands/ErrorCommand.cs @@ -0,0 +1,15 @@ +using System.Threading.Tasks; +using System.Transactions; +using DSharpPlus.CommandsNext; +using DSharpPlus.CommandsNext.Attributes; + +namespace DSharpPlus.Examples.CommandsNext.ErrorHandling.Commands +{ + public class ErrorCommand : BaseCommandModule + { + // I bet you didn't know this exception existed. + // Unless you did. In which case, my sincerest condolences. + [Command("error"), Description("Throws an exception.")] + public Task ExecuteAsync(CommandContext context) => throw new TransactionManagerCommunicationException("This command is supposed to fail."); + } +} diff --git a/src/DSharpPlus.Examples.CommandsNext.ErrorHandling/DSharpPlus.Examples.CommandsNext.ErrorHandling.csproj b/src/DSharpPlus.Examples.CommandsNext.ErrorHandling/DSharpPlus.Examples.CommandsNext.ErrorHandling.csproj new file mode 100644 index 0000000..aa3e22a --- /dev/null +++ b/src/DSharpPlus.Examples.CommandsNext.ErrorHandling/DSharpPlus.Examples.CommandsNext.ErrorHandling.csproj @@ -0,0 +1,11 @@ + + + Exe + net8.0 + enable + + + + + + \ No newline at end of file diff --git a/src/DSharpPlus.Examples.CommandsNext.ErrorHandling/Program.cs b/src/DSharpPlus.Examples.CommandsNext.ErrorHandling/Program.cs new file mode 100644 index 0000000..1b28725 --- /dev/null +++ b/src/DSharpPlus.Examples.CommandsNext.ErrorHandling/Program.cs @@ -0,0 +1,69 @@ +using System; +using System.Threading.Tasks; +using DSharpPlus.CommandsNext; +using DSharpPlus.Entities; + +namespace DSharpPlus.Examples.CommandsNext.ErrorHandling +{ + public static class Program + { + /// + /// The prefixes used to trigger Discord text commands through CommandsNext. + /// + private static readonly string[] _prefixes = new[] { "!" }; + + public static async Task Main() + { + // Check for token + // TODO: Load the token up from IConfiguration + string? token = Environment.GetEnvironmentVariable("DISCORD_TOKEN"); + if (string.IsNullOrWhiteSpace(token)) + { + Console.WriteLine("Please set the environment variable DISCORD_TOKEN."); + return; + } + + // Create the client + DiscordClient discord = new(new DiscordConfiguration + { + Token = token, + Intents = DiscordIntents.AllUnprivileged | DiscordIntents.MessageContents + }); + + CommandsNextExtension commandsNext = discord.UseCommandsNext(new CommandsNextConfiguration() + { + // For brevity, we're going to use the string prefixes property. + // However, if you want to do something complicated, such as per-guild prefixes, + // you can pass a prefix resolver delegate instead. + StringPrefixes = _prefixes + }); + + // If we pass our assembly to CommandsNext, it will automatically + // search our program for any Command classes and register them on its own. + // This is very handy so you don't need to manually update a list when you add a new command. + commandsNext.RegisterCommands(typeof(Program).Assembly); + + // Register our error handler + commandsNext.CommandErrored += CommandErroredEventHandlerAsync; + + // Connect to the Discord gateway + await discord.ConnectAsync(); + + // Wait infinitely so the bot stays connected; DiscordClient.ConnectAsync is not a blocking call + await Task.Delay(-1); + } + + private static async Task CommandErroredEventHandlerAsync(CommandsNextExtension extension, CommandErrorEventArgs eventArgs) + { + DiscordEmbedBuilder embedBuilder = new(); + embedBuilder.WithTitle($"An error occurred while executing a command: {eventArgs.Exception.GetType().Name}"); + embedBuilder.WithColor(DiscordColor.DarkRed); + embedBuilder.WithDescription(eventArgs.Exception.Message); + embedBuilder.AddField("Stack Trace", string.IsNullOrWhiteSpace(eventArgs.Exception.StackTrace) + ? "No stack trace available." + : Formatter.BlockCode(eventArgs.Exception.StackTrace.Trim()[3..], "cs")); // The [3..] removes the first three characters (at\n) in the stack trace. + + await eventArgs.Context.RespondAsync(embedBuilder.Build()); + } + } +} diff --git a/src/DSharpPlus.Examples.CommandsNext.GroupCommands/ArgumentConverters/.editorconfig b/src/DSharpPlus.Examples.CommandsNext.GroupCommands/ArgumentConverters/.editorconfig new file mode 100644 index 0000000..9f997ca --- /dev/null +++ b/src/DSharpPlus.Examples.CommandsNext.GroupCommands/ArgumentConverters/.editorconfig @@ -0,0 +1,5 @@ +# .editorconfig +root = false + +[*.{cs,vb}] +dotnet_diagnostic.IDE0046.severity = none # Suppress conditional expressions for readability within the Ulid argument converter. \ No newline at end of file diff --git a/src/DSharpPlus.Examples.CommandsNext.GroupCommands/ArgumentConverters/UlidArgumentConverter.cs b/src/DSharpPlus.Examples.CommandsNext.GroupCommands/ArgumentConverters/UlidArgumentConverter.cs new file mode 100644 index 0000000..27cbb21 --- /dev/null +++ b/src/DSharpPlus.Examples.CommandsNext.GroupCommands/ArgumentConverters/UlidArgumentConverter.cs @@ -0,0 +1,21 @@ +using System; +using System.Threading.Tasks; +using DSharpPlus.CommandsNext; +using DSharpPlus.CommandsNext.Converters; +using DSharpPlus.Entities; + +namespace DSharpPlus.Examples.CommandsNext.GroupCommands.ArgumentConverters +{ + public sealed class UlidArgumentConverter : IArgumentConverter + { + public Task> ConvertAsync(string value, CommandContext ctx) + { + if (Ulid.TryParse(value, out Ulid ulid)) + { + return Task.FromResult(Optional.FromValue(ulid)); + } + + return Task.FromResult(Optional.FromNoValue()); + } + } +} diff --git a/src/DSharpPlus.Examples.CommandsNext.GroupCommands/Commands/.editorconfig b/src/DSharpPlus.Examples.CommandsNext.GroupCommands/Commands/.editorconfig new file mode 100644 index 0000000..85cd174 --- /dev/null +++ b/src/DSharpPlus.Examples.CommandsNext.GroupCommands/Commands/.editorconfig @@ -0,0 +1,5 @@ +# .editorconfig +root = false + +[*.{cs,vb}] +dotnet_diagnostic.CA1822.severity = none # Suppress CA1822 due to CommandsNext not supporting static commands. \ No newline at end of file diff --git a/src/DSharpPlus.Examples.CommandsNext.GroupCommands/Commands/UlidCommand.cs b/src/DSharpPlus.Examples.CommandsNext.GroupCommands/Commands/UlidCommand.cs new file mode 100644 index 0000000..a6908c7 --- /dev/null +++ b/src/DSharpPlus.Examples.CommandsNext.GroupCommands/Commands/UlidCommand.cs @@ -0,0 +1,37 @@ +using System; +using System.Threading.Tasks; +using DSharpPlus.CommandsNext; +using DSharpPlus.CommandsNext.Attributes; +using DSharpPlus.Entities; + +namespace DSharpPlus.Examples.CommandsNext.GroupCommands.Commands +{ + // Group is how a command can have subcommands. + [Group("ulid"), Description("Ulid utility commands.")] + public class UlidCommand : BaseCommandModule + { + // The group command is executed when no subcommands are specified. + // It's allowed to have arguments and such, just like a normal command. + [GroupCommand] + public async Task ExecuteAsync(CommandContext context) => await context.RespondAsync($"Ulid utility commands. Use `help ulid` for subcommands. The current Ulid is {Formatter.InlineCode(Ulid.NewUlid().ToString())}"); + + // This subcommand is executed as `!ulid create` + [Command("create"), Description("Generate a new ULID.")] + public async Task CreateAsync(CommandContext context) => await context.RespondAsync(Formatter.InlineCode(Ulid.NewUlid().ToString())); + + // The user would run this subcommand as `!ulid info 01HBF5ZGDHXAJ85HKMBGCJTT99`, where `01HBF5ZGDHXAJ85HKMBGCJTT99` is any valid Ulid. + [Command("info"), Description("Returns information about a Ulid.")] + public async Task ExecuteAsync(CommandContext context, Ulid ulid) + { + DiscordEmbedBuilder embedBuilder = new(); + embedBuilder.WithTitle("Ulid Information"); + embedBuilder.WithColor(DiscordColor.Blurple); + embedBuilder.WithDescription($"Ulid: {Formatter.InlineCode(ulid.ToString())}"); + embedBuilder.AddField("Base64", Formatter.InlineCode(ulid.ToBase64())); + embedBuilder.AddField("Timestamp", Formatter.Timestamp(ulid.Time, TimestampFormat.LongDateTime)); + embedBuilder.AddField("Randomness", Formatter.InlineCode(Convert.ToBase64String(ulid.Random))); + + await context.RespondAsync(embedBuilder.Build()); + } + } +} diff --git a/src/DSharpPlus.Examples.CommandsNext.GroupCommands/DSharpPlus.Examples.CommandsNext.GroupCommands.csproj b/src/DSharpPlus.Examples.CommandsNext.GroupCommands/DSharpPlus.Examples.CommandsNext.GroupCommands.csproj new file mode 100644 index 0000000..30e19ea --- /dev/null +++ b/src/DSharpPlus.Examples.CommandsNext.GroupCommands/DSharpPlus.Examples.CommandsNext.GroupCommands.csproj @@ -0,0 +1,12 @@ + + + Exe + net8.0 + enable + + + + + + + \ No newline at end of file diff --git a/src/DSharpPlus.Examples.CommandsNext.GroupCommands/Program.cs b/src/DSharpPlus.Examples.CommandsNext.GroupCommands/Program.cs new file mode 100644 index 0000000..6f9e3e3 --- /dev/null +++ b/src/DSharpPlus.Examples.CommandsNext.GroupCommands/Program.cs @@ -0,0 +1,57 @@ +using System; +using System.Threading.Tasks; +using DSharpPlus.CommandsNext; +using DSharpPlus.Examples.CommandsNext.GroupCommands.ArgumentConverters; + +namespace DSharpPlus.Examples.CommandsNext.GroupCommands +{ + public static class Program + { + /// + /// The prefixes used to trigger Discord text commands through CommandsNext. + /// + private static readonly string[] _prefixes = new[] { "!" }; + + public static async Task Main() + { + // Check for token + // TODO: Load the token up from IConfiguration + string? token = Environment.GetEnvironmentVariable("DISCORD_TOKEN"); + if (string.IsNullOrWhiteSpace(token)) + { + Console.WriteLine("Please set the environment variable DISCORD_TOKEN."); + return; + } + + // Create the client + DiscordClient discord = new(new DiscordConfiguration + { + Token = token, + Intents = DiscordIntents.AllUnprivileged | DiscordIntents.MessageContents + }); + + CommandsNextExtension commandsNext = discord.UseCommandsNext(new CommandsNextConfiguration() + { + // For brevity, we're going to use the string prefixes property. + // However, if you want to do something complicated, such as per-guild prefixes, + // you can pass a prefix resolver delegate instead. + StringPrefixes = _prefixes + }); + + // Register our argument converters. + // This is a global registration, so these converters will be used for all commands. + commandsNext.RegisterConverter(new UlidArgumentConverter()); + + // If we pass our assembly to CommandsNext, it will automatically + // search our program for any Command classes and register them on its own. + // This is very handy so you don't need to manually update a list when you add a new command. + commandsNext.RegisterCommands(typeof(Program).Assembly); + + // Connect to the Discord gateway + await discord.ConnectAsync(); + + // Wait infinitely so the bot stays connected; DiscordClient.ConnectAsync is not a blocking call + await Task.Delay(-1); + } + } +}