diff --git a/Cocotte/Modules/PingModule.cs b/Cocotte/Modules/PingModule.cs
index 7cdac92..bcaf9f6 100644
--- a/Cocotte/Modules/PingModule.cs
+++ b/Cocotte/Modules/PingModule.cs
@@ -1,19 +1,176 @@
-using Discord.Interactions;
+#if DEBUG
+
+using Cocotte.Services;
+using Discord;
+using Discord.Interactions;
namespace Cocotte.Modules;
+///
+/// Module containing different test and debug commands
+///
+[RequireOwner]
public class PingModule : InteractionModuleBase
{
private readonly ILogger _logger;
+ private readonly SharedCounter _sharedCounter;
+ private readonly TransientCounter _transientCounter;
+ private static readonly SemaphoreSlim CounterWait = new(0);
- public PingModule(ILogger logger)
+ public PingModule(ILogger logger, SharedCounter sharedCounter, TransientCounter transientCounter)
{
_logger = logger;
+ _sharedCounter = sharedCounter;
+ _transientCounter = transientCounter;
}
- [SlashCommand("ping", "Check if Coco is alive")]
+ [SlashCommand("ping", "Check if Coco is alive and get latency")]
public async Task Ping()
{
- await RespondAsync($":ping_pong: It took me {Context.Client.Latency}ms to respond to you!", ephemeral: true);
+ _logger.LogTrace("[Ping/ping] Received ping command");
+
+ await RespondAsync($":ping_pong: It took me {Context.Client.Latency}ms to respond to you!");
}
-}
\ No newline at end of file
+
+ [SlashCommand("echo", "Repeat the input")]
+ public async Task Echo(string echo, [Summary(description: "mention the user")] bool mention = false)
+ {
+ _logger.LogTrace("[Ping/echo] Received ping command with arg: {{ echo:'{Echo}', mention:{Mention} }}", echo, mention);
+
+ await RespondAsync($"{echo} {(mention ? Context.User.Mention : string.Empty)}");
+ }
+
+ // This command will greet target user in the channel this was executed in.
+ [UserCommand("Greet")]
+ public async Task GreetUserAsync(IUser user)
+ {
+ await RespondAsync($":wave: {Context.User.Username} said hi to you, <@{user.Id}>!");
+ }
+
+ // Pins a message in the channel it is in.
+ [MessageCommand("Pin")]
+ public async Task PinMessageAsync(IMessage message)
+ {
+ // make a safety cast to check if the message is ISystem- or IUserMessage
+ if (message is not IUserMessage userMessage)
+ await RespondAsync(":x: You cant pin system messages!");
+
+ // if the pins in this channel are equal to or above 50, no more messages can be pinned.
+ else if ((await Context.Channel.GetPinnedMessagesAsync()).Count >= 50)
+ await RespondAsync(":x: You cant pin any more messages, the max has already been reached in this channel!");
+
+ else
+ {
+ await userMessage.PinAsync();
+ await RespondAsync(":white_check_mark: Successfully pinned message!");
+ }
+ }
+
+ [SlashCommand("test-button", "Test buttons components")]
+ public async Task TestButton()
+ {
+ var component = new ComponentBuilder()
+ .WithButton("Button1", $"button:1:{Context.User.Username}")
+ .WithButton("Button2", $"button:2:{Context.User.Username}")
+ .AddRow(new ActionRowBuilder()
+ .WithButton("Button3", $"button:3:{Context.User.Username}"));
+
+ await RespondAsync(components: component.Build());
+ }
+
+ [ComponentInteraction("button:*:*")]
+ public async Task TestButtonClick(int buttonId, string userName)
+ {
+ await RespondAsync($"{userName} clicked on button: {buttonId}");
+ }
+
+ [SlashCommand("counter-shared", "Spawn a shared counter")]
+ public async Task CounterShared()
+ {
+ var component = new ComponentBuilder()
+ .WithButton("Increment", "increment_shared");
+
+ await RespondAsync($"Counter: {_sharedCounter.Count}", components: component.Build());
+ }
+
+ [ComponentInteraction("increment_shared")]
+ public async Task SharedCounterIncrement()
+ {
+ _logger.LogTrace("Received increment on shared counter");
+ _sharedCounter.Count++;
+
+ try
+ {
+ await (Context.Interaction as IComponentInteraction)!.UpdateAsync(msg =>
+ {
+ msg.Content = $"Counter: {_sharedCounter.Count}";
+ });
+ }
+ catch (Exception e)
+ {
+ _logger.LogError(e, "An error occured while updating original message:");
+ }
+ await RespondAsync();
+ }
+
+ [SlashCommand("counter-transient", "Spawn a transient counter")]
+ public async Task CounterTransient()
+ {
+ var component = new ComponentBuilder()
+ .WithButton("Increment", "increment_transient");
+
+ await RespondAsync($"Counter: {_transientCounter.Count}", components: component.Build());
+ }
+
+ [ComponentInteraction("increment_transient")]
+ public async Task TransientCounterIncrement()
+ {
+ _logger.LogTrace("Received increment on transient counter");
+ _transientCounter.Count++;
+
+ try
+ {
+ await (Context.Interaction as IComponentInteraction)!.UpdateAsync(msg =>
+ {
+ msg.Content = $"Counter: {_transientCounter.Count}";
+ });
+ }
+ catch (Exception e)
+ {
+ _logger.LogError(e, "An error occured while updating original message:");
+ }
+ await RespondAsync();
+ }
+
+ [SlashCommand("counter-transient-wait", "Spawn a transient counter using wait")]
+ public async Task CounterTransientWait()
+ {
+ var component = new ComponentBuilder()
+ .WithButton("Increment", "increment_transient_wait");
+
+ await RespondAsync($"Counter: {_transientCounter.Count}", components: component.Build());
+ var response = await GetOriginalResponseAsync();
+
+ while (true)
+ {
+ // Wait for the button to be clicked
+ _logger.LogTrace("Waiting for semaphore release");
+ await CounterWait.WaitAsync();
+
+ _logger.LogTrace("Received increment on transient wait counter");
+ _transientCounter.Count++;
+
+ await ModifyOriginalResponseAsync(m => m.Content = $"Counter: {_transientCounter.Count}");
+ }
+ }
+
+ [ComponentInteraction("increment_transient_wait")]
+ public async Task WaitCounterIncrement()
+ {
+ CounterWait.Release();
+
+ await RespondAsync();
+ }
+}
+
+#endif
\ No newline at end of file
diff --git a/Cocotte/Program.cs b/Cocotte/Program.cs
index 3d8ee51..acef6d9 100644
--- a/Cocotte/Program.cs
+++ b/Cocotte/Program.cs
@@ -34,6 +34,7 @@ IHost host = Host.CreateDefaultBuilder(args)
// Custom
services.AddSingleton();
+ services.AddTransient();
})
.Build();
diff --git a/Cocotte/Properties/launchSettings.json b/Cocotte/Properties/launchSettings.json
index e499d8b..0b60e26 100644
--- a/Cocotte/Properties/launchSettings.json
+++ b/Cocotte/Properties/launchSettings.json
@@ -1,6 +1,6 @@
{
"profiles": {
- "Cocotter": {
+ "Cocotte": {
"commandName": "Project",
"dotnetRunMessages": true,
"environmentVariables": {
diff --git a/Cocotte/Services/CocotteService.cs b/Cocotte/Services/CocotteService.cs
index 49271fd..75672de 100644
--- a/Cocotte/Services/CocotteService.cs
+++ b/Cocotte/Services/CocotteService.cs
@@ -1,6 +1,5 @@
using System.Reflection;
using Cocotte.Options;
-using Cocotte.Utils;
using Discord;
using Discord.Interactions;
using Discord.WebSocket;
@@ -72,7 +71,7 @@ public class CocotteService : BackgroundService
return;
}
- await _interactionService.RegisterCommandsToGuildAsync(_options.DevGuildId.Value, true);
+ await _interactionService.RegisterCommandsToGuildAsync(_options.DevGuildId.Value);
}
else
{
@@ -87,7 +86,7 @@ public class CocotteService : BackgroundService
private async Task HandleInteraction(SocketInteraction interaction)
{
- _logger.LogTrace("[Interaction/Trace] Received interaction: by {user} in #{channel} of type {type}", interaction.User, interaction.Channel, interaction.Type);
+ _logger.LogTrace("[Interaction/Trace] Received interaction: by {User} in #{Channel} of type {Type}", interaction.User, interaction.Channel, interaction.Type);
try
{
@@ -99,14 +98,7 @@ public class CocotteService : BackgroundService
if (!result.IsSuccess)
{
- _logger.LogDebug("[Interaction/Trace] Error while executing interaction: {interaction} in {channel}", interaction.Token, interaction.Channel);
-
- switch (result.Error)
- {
- case InteractionCommandError.UnmetPrecondition:
- // implement
- break;
- }
+ _logger.LogDebug("[Interaction/Trace] Error while executing interaction: {Interaction} in {Channel} because {Error}:{Reason}", interaction.Token, interaction.Channel, result.Error, result.ErrorReason);
}
}
catch
diff --git a/Cocotte/Services/TransientCounter.cs b/Cocotte/Services/TransientCounter.cs
new file mode 100644
index 0000000..edb477f
--- /dev/null
+++ b/Cocotte/Services/TransientCounter.cs
@@ -0,0 +1,6 @@
+namespace Cocotte.Services;
+
+public class TransientCounter
+{
+ public int Count { get; set; } = 0;
+}
\ No newline at end of file
diff --git a/Cocotte/appsettings.Development.json b/Cocotte/appsettings.Development.json
index b2dcdb6..b4be21e 100644
--- a/Cocotte/appsettings.Development.json
+++ b/Cocotte/appsettings.Development.json
@@ -2,7 +2,8 @@
"Logging": {
"LogLevel": {
"Default": "Information",
- "Microsoft.Hosting.Lifetime": "Information"
+ "Microsoft.Hosting.Lifetime": "Information",
+ "Cocotte": "Trace"
}
}
}