diff --git a/.gitignore b/.gitignore
index 9ddd1c8..51e1adf 100644
--- a/.gitignore
+++ b/.gitignore
@@ -684,5 +684,3 @@ fabric.properties
# Additional files built by Visual Studio
# End of https://www.toptal.com/developers/gitignore/api/visualstudio,visualstudiocode,rider,csharp,dotnetcore
-
-Cocotte/discord.json
\ No newline at end of file
diff --git a/Cocotte/Cocotte.csproj b/Cocotte/Cocotte.csproj
index 55e9e2a..347f228 100644
--- a/Cocotte/Cocotte.csproj
+++ b/Cocotte/Cocotte.csproj
@@ -11,8 +11,4 @@
-
-
-
-
diff --git a/Cocotte/Modules/Groups/GroupModule.cs b/Cocotte/Modules/Groups/GroupModule.cs
new file mode 100644
index 0000000..c82129d
--- /dev/null
+++ b/Cocotte/Modules/Groups/GroupModule.cs
@@ -0,0 +1,42 @@
+using Cocotte.Options;
+using Cocotte.Utils;
+using Discord;
+using Discord.Interactions;
+using Microsoft.Extensions.Options;
+
+namespace Cocotte.Modules.Groups;
+
+///
+/// Module to ask and propose groups for different activities: Abyss, OOW, FC, ...
+///
+[Group("group", "Group related commands")]
+public class GroupModule : InteractionModuleBase
+{
+ private readonly ILogger _logger;
+ private readonly GroupsOptions _options;
+
+ public GroupModule(ILogger logger, IOptions options)
+ {
+ _logger = logger;
+ _options = options.Value;
+ }
+
+ [RequireOwner]
+ [SlashCommand("test", "Test group module")]
+ public async Task Test()
+ {
+ await RespondAsync("Module is active!!");
+ }
+
+ [RequireOwner]
+ [SlashCommand("setup-info", "Display group setup info")]
+ public async Task SetupInfo()
+ {
+ await RespondAsync($"""
+ - Helper: {MentionUtils.MentionRole(_options.HelperRoleId)} {_options.HelperEmote.ToEmote()}
+ - Dps: {MentionUtils.MentionRole(_options.DpsRoleId)} {_options.DpsEmote.ToEmote()}
+ - Tank: {MentionUtils.MentionRole(_options.TankRoleId)} {_options.TankEmote.ToEmote()}
+ - Healer: {MentionUtils.MentionRole(_options.HealerRoleId)} {_options.HealerEmote.ToEmote()}
+ """);
+ }
+}
diff --git a/Cocotte/Options/GroupsOptions.cs b/Cocotte/Options/GroupsOptions.cs
new file mode 100644
index 0000000..23c7ea0
--- /dev/null
+++ b/Cocotte/Options/GroupsOptions.cs
@@ -0,0 +1,18 @@
+namespace Cocotte.Options;
+
+public class GroupsOptions
+{
+ public const string SectionName = "GroupsOptions";
+
+ public ulong HelperRoleId { get; init; }
+ public string HelperEmote { get; init; }
+
+ public ulong DpsRoleId { get; init; }
+ public string DpsEmote { get; init; }
+
+ public ulong TankRoleId { get; init; }
+ public string TankEmote { get; init; }
+
+ public ulong HealerRoleId { get; init; }
+ public string HealerEmote { get; init; }
+}
\ No newline at end of file
diff --git a/Cocotte/Program.cs b/Cocotte/Program.cs
index b6cfe6f..d862e86 100644
--- a/Cocotte/Program.cs
+++ b/Cocotte/Program.cs
@@ -9,18 +9,21 @@ using Discord.WebSocket;
DiscordSocketConfig discordSocketConfig = new()
{
LogLevel = LogSeverity.Debug,
- MessageCacheSize = 200
+ MessageCacheSize = 200,
+ GatewayIntents = GatewayIntents.None
};
IHost host = Host.CreateDefaultBuilder(args)
.ConfigureAppConfiguration((_, configuration) =>
{
configuration.AddJsonFile("discord.json", false, false);
+ configuration.AddJsonFile("groups.json", false, false);
})
.ConfigureServices((context, services) =>
{
// Options
services.Configure(context.Configuration.GetSection(DiscordOptions.SectionName));
+ services.Configure(context.Configuration.GetSection(GroupsOptions.SectionName));
// Discord.Net
services.AddHostedService();
@@ -37,6 +40,8 @@ IHost host = Host.CreateDefaultBuilder(args)
services.AddSingleton();
services.AddSingleton();
+ // Groups
+
// Raids
services.AddTransient();
services.AddSingleton();
diff --git a/Cocotte/Properties/launchSettings.json b/Cocotte/Properties/launchSettings.json
index 0b60e26..0f53703 100644
--- a/Cocotte/Properties/launchSettings.json
+++ b/Cocotte/Properties/launchSettings.json
@@ -5,7 +5,8 @@
"dotnetRunMessages": true,
"environmentVariables": {
"DOTNET_ENVIRONMENT": "Development"
- }
+ },
+ "workingDirectory": "bin/Debug/net7.0"
}
}
}
diff --git a/Cocotte/Services/CocotteService.cs b/Cocotte/Services/CocotteService.cs
index 75672de..6debb4d 100644
--- a/Cocotte/Services/CocotteService.cs
+++ b/Cocotte/Services/CocotteService.cs
@@ -15,18 +15,20 @@ public class CocotteService : BackgroundService
private readonly IHostApplicationLifetime _hostApplicationLifetime;
private readonly DiscordSocketClient _client;
private readonly DiscordOptions _options;
+ private readonly GroupsOptions _groupOptions;
private readonly InteractionService _interactionService;
public CocotteService(ILogger logger, IServiceProvider serviceProvider,
IHostEnvironment hostEnvironment,
IHostApplicationLifetime hostApplicationLifetime, DiscordSocketClient client,
- IOptions options, InteractionService interactionService)
+ IOptions options, IOptions groupOptions, InteractionService interactionService)
{
_logger = logger;
_serviceProvider = serviceProvider;
_hostApplicationLifetime = hostApplicationLifetime;
_client = client;
_options = options.Value;
+ _groupOptions = groupOptions.Value;
_interactionService = interactionService;
_hostEnvironment = hostEnvironment;
}
@@ -34,7 +36,7 @@ public class CocotteService : BackgroundService
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
// Check token first
- if (_options.Token is null)
+ if (string.IsNullOrWhiteSpace(_options.Token))
{
_logger.LogError("Couldn't find any discord bot token, exiting...");
@@ -43,6 +45,11 @@ public class CocotteService : BackgroundService
return;
}
+ if (!ValidateOptions())
+ {
+ return;
+ }
+
// Initialize modules and commands
await _interactionService.AddModulesAsync(Assembly.GetEntryAssembly(), _serviceProvider);
@@ -56,6 +63,22 @@ public class CocotteService : BackgroundService
await Task.Delay(Timeout.Infinite, stoppingToken);
}
+ private bool ValidateOptions()
+ {
+ // Validate group options
+ if ((_groupOptions.HelperRoleId
+ | _groupOptions.DpsRoleId
+ | _groupOptions.TankRoleId
+ | _groupOptions.HealerRoleId) == 0)
+ {
+ _logger.LogError("One of the group options id is invalid, it cannot be 0");
+
+ return false;
+ }
+
+ return true;
+ }
+
private async Task ClientOnReady()
{
// Context & Slash commands can be automatically registered, but this process needs to happen after the client enters the READY state.
@@ -63,7 +86,7 @@ public class CocotteService : BackgroundService
if (_hostEnvironment.IsDevelopment())
{
// Check that a dev guild is set
- if (!_options.DevGuildId.HasValue)
+ if (!_options.DevGuildId.HasValue && _options.DevGuildId!.Value != 0)
{
_logger.LogError("Couldn't find any dev guild while application is run in dev mode, exiting...");
diff --git a/Cocotte/discord.json b/Cocotte/discord.json
new file mode 100644
index 0000000..3688e77
--- /dev/null
+++ b/Cocotte/discord.json
@@ -0,0 +1,6 @@
+{
+ "DiscordOptions": {
+ "Token": "",
+ "DevGuildId": 0
+ }
+}
\ No newline at end of file
diff --git a/Cocotte/groups.json b/Cocotte/groups.json
new file mode 100644
index 0000000..5c7787f
--- /dev/null
+++ b/Cocotte/groups.json
@@ -0,0 +1,15 @@
+{
+ "GroupsOptions": {
+ "HelperRoleId": 0,
+ "HelperEmote": "",
+
+ "DpsRoleId": 0,
+ "DpsEmote": "",
+
+ "TankRoleId": 0,
+ "TankEmote": "",
+
+ "HealerRoleId": 0,
+ "HealerEmote": ""
+ }
+}
\ No newline at end of file