[Activity] Add thread ping and refactor activity join/leave
This commit is contained in:
@@ -138,8 +138,7 @@ public partial class ActivityModule : InteractionModuleBase<SocketInteractionCon
|
|||||||
|
|
||||||
private async Task CreateActivity(ActivityName activityName, string description, bool areRolesEnabled = true, uint? maxPlayers = null, uint? stage = null, InterstellarColor? interstellarColor = null)
|
private async Task CreateActivity(ActivityName activityName, string description, bool areRolesEnabled = true, uint? maxPlayers = null, uint? stage = null, InterstellarColor? interstellarColor = null)
|
||||||
{
|
{
|
||||||
var user = (SocketGuildUser)Context.User;
|
_logger.LogTrace("{User} is creating activity {Activity}", User.DisplayName, activityName);
|
||||||
_logger.LogTrace("{User} is creating activity {Activity}", user.DisplayName, activityName);
|
|
||||||
|
|
||||||
// Activities are identified using their original message id
|
// Activities are identified using their original message id
|
||||||
await RespondAsync("> ***Création de l'activité en cours...***");
|
await RespondAsync("> ***Création de l'activité en cours...***");
|
||||||
@@ -147,7 +146,7 @@ public partial class ActivityModule : InteractionModuleBase<SocketInteractionCon
|
|||||||
var response = await GetOriginalResponseAsync();
|
var response = await GetOriginalResponseAsync();
|
||||||
|
|
||||||
// Create associated thread
|
// Create associated thread
|
||||||
var threadId = await CreateThread(activityName, user.DisplayName);
|
var threadId = await CreateThread(activityName, User.DisplayName);
|
||||||
|
|
||||||
var activityType = ActivityHelper.ActivityNameToType(activityName);
|
var activityType = ActivityHelper.ActivityNameToType(activityName);
|
||||||
maxPlayers ??= ActivityHelper.ActivityTypeToMaxPlayers(activityType);
|
maxPlayers ??= ActivityHelper.ActivityTypeToMaxPlayers(activityType);
|
||||||
@@ -202,7 +201,7 @@ public partial class ActivityModule : InteractionModuleBase<SocketInteractionCon
|
|||||||
Description = description,
|
Description = description,
|
||||||
Type = activityType,
|
Type = activityType,
|
||||||
Name = activityName,
|
Name = activityName,
|
||||||
AreRolesEnabled = true,
|
AreRolesEnabled = areRolesEnabled,
|
||||||
MaxPlayers = (uint) maxPlayers
|
MaxPlayers = (uint) maxPlayers
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -211,7 +210,7 @@ public partial class ActivityModule : InteractionModuleBase<SocketInteractionCon
|
|||||||
await _activitiesRepository.AddActivity(activity);
|
await _activitiesRepository.AddActivity(activity);
|
||||||
|
|
||||||
// Add creator to activity
|
// Add creator to activity
|
||||||
var rolePlayer = CreateActivityPlayer(activity, user, areRolesEnabled);
|
var rolePlayer = CreateActivityPlayer(activity, User, areRolesEnabled);
|
||||||
|
|
||||||
activity.ActivityPlayers.Add(rolePlayer);
|
activity.ActivityPlayers.Add(rolePlayer);
|
||||||
|
|
||||||
@@ -247,8 +246,6 @@ public partial class ActivityModule : InteractionModuleBase<SocketInteractionCon
|
|||||||
[ComponentInteraction("activity join:*", ignoreGroupNames: true)]
|
[ComponentInteraction("activity join:*", ignoreGroupNames: true)]
|
||||||
public async Task JoinActivity(ulong messageId)
|
public async Task JoinActivity(ulong messageId)
|
||||||
{
|
{
|
||||||
var user = (SocketGuildUser)Context.User;
|
|
||||||
|
|
||||||
// Check if activity exists
|
// Check if activity exists
|
||||||
if (await _activitiesRepository.FindActivity(Context.Guild.Id, Context.Channel.Id, messageId) is not { } activity)
|
if (await _activitiesRepository.FindActivity(Context.Guild.Id, Context.Channel.Id, messageId) is not { } activity)
|
||||||
{
|
{
|
||||||
@@ -260,39 +257,11 @@ public partial class ActivityModule : InteractionModuleBase<SocketInteractionCon
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If player is already registered
|
if (!await AddUserToActivity(activity, User, self: true))
|
||||||
if (await _activitiesRepository.FindActivityPlayer( Context.Guild.Id, Context.Channel.Id, messageId, user.Id) is not null)
|
|
||||||
{
|
{
|
||||||
await RespondAsync(
|
|
||||||
ephemeral: true,
|
|
||||||
embed: EmbedUtils.ErrorEmbed("Vous êtes **déjà inscrit** à cette activité").Build()
|
|
||||||
);
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if activity is full
|
|
||||||
if (_activitiesRepository.ActivityPlayerCount(activity) >= activity.MaxPlayers)
|
|
||||||
{
|
|
||||||
await RespondAsync(
|
|
||||||
ephemeral: true,
|
|
||||||
embed: EmbedUtils.ErrorEmbed("L'activité est **complète**").Build()
|
|
||||||
);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_logger.LogTrace("Player {Player} joined activity {Id}", user.DisplayName, messageId);
|
|
||||||
|
|
||||||
var activityPlayer = CreateActivityPlayer(activity, User, activity.AreRolesEnabled);
|
|
||||||
|
|
||||||
// Add player to activity
|
|
||||||
activity.ActivityPlayers.Add(activityPlayer);
|
|
||||||
await _activitiesRepository.SaveChanges();
|
|
||||||
|
|
||||||
// Update activity embed
|
|
||||||
await UpdateActivityEmbed(activity, ActivityUpdateReason.PlayerJoin);
|
|
||||||
|
|
||||||
await RespondAsync(
|
await RespondAsync(
|
||||||
ephemeral: true,
|
ephemeral: true,
|
||||||
embed: EmbedUtils.SuccessEmbed("Vous avez bien été **inscrit** pour cette activité").Build()
|
embed: EmbedUtils.SuccessEmbed("Vous avez bien été **inscrit** pour cette activité").Build()
|
||||||
@@ -302,8 +271,6 @@ public partial class ActivityModule : InteractionModuleBase<SocketInteractionCon
|
|||||||
[ComponentInteraction("activity leave:*", ignoreGroupNames: true)]
|
[ComponentInteraction("activity leave:*", ignoreGroupNames: true)]
|
||||||
public async Task LeaveActivity(ulong messageId)
|
public async Task LeaveActivity(ulong messageId)
|
||||||
{
|
{
|
||||||
var user = (IGuildUser)Context.User;
|
|
||||||
|
|
||||||
// Check if activity exists
|
// Check if activity exists
|
||||||
if (await _activitiesRepository.FindActivity(Context.Guild.Id, Context.Channel.Id, messageId) is not { } activity)
|
if (await _activitiesRepository.FindActivity(Context.Guild.Id, Context.Channel.Id, messageId) is not { } activity)
|
||||||
{
|
{
|
||||||
@@ -315,25 +282,11 @@ public partial class ActivityModule : InteractionModuleBase<SocketInteractionCon
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if player is in activity
|
if (!await RemovePlayerFromActivity(activity, User, self: true))
|
||||||
if (await _activitiesRepository.FindActivityPlayer(Context.Guild.Id, Context.Channel.Id, messageId, user.Id) is not { } activityPlayer)
|
|
||||||
{
|
{
|
||||||
await RespondAsync(
|
|
||||||
ephemeral: true,
|
|
||||||
embed: EmbedUtils.ErrorEmbed("Vous n'êtes **pas inscrit** à cette activité").Build()
|
|
||||||
);
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_logger.LogTrace("Player {Player} left activity {Id}", user.DisplayName, messageId);
|
|
||||||
|
|
||||||
activity.ActivityPlayers.Remove(activityPlayer);
|
|
||||||
await _activitiesRepository.SaveChanges();
|
|
||||||
|
|
||||||
// Update activity embed
|
|
||||||
await UpdateActivityEmbed(activity, ActivityUpdateReason.PlayerLeave);
|
|
||||||
|
|
||||||
await RespondAsync(
|
await RespondAsync(
|
||||||
ephemeral: true,
|
ephemeral: true,
|
||||||
embed: EmbedUtils.SuccessEmbed("Vous avez bien été **désinscrit** pour cette activité").Build()
|
embed: EmbedUtils.SuccessEmbed("Vous avez bien été **désinscrit** pour cette activité").Build()
|
||||||
@@ -343,8 +296,6 @@ public partial class ActivityModule : InteractionModuleBase<SocketInteractionCon
|
|||||||
[ComponentInteraction("activity delete:*", ignoreGroupNames: true)]
|
[ComponentInteraction("activity delete:*", ignoreGroupNames: true)]
|
||||||
public async Task DeleteActivity(ulong messageId)
|
public async Task DeleteActivity(ulong messageId)
|
||||||
{
|
{
|
||||||
var user = (SocketGuildUser) Context.User;
|
|
||||||
|
|
||||||
// Check if activity exists
|
// Check if activity exists
|
||||||
if (await _activitiesRepository.FindActivity(Context.Guild.Id, Context.Channel.Id, messageId) is not { } activity)
|
if (await _activitiesRepository.FindActivity(Context.Guild.Id, Context.Channel.Id, messageId) is not { } activity)
|
||||||
{
|
{
|
||||||
@@ -357,7 +308,7 @@ public partial class ActivityModule : InteractionModuleBase<SocketInteractionCon
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check if user has permission to delete this activity
|
// Check if user has permission to delete this activity
|
||||||
if (user.Id != activity.CreatorUserId && !user.GetPermissions((IGuildChannel) Context.Channel).ManageMessages)
|
if (User.Id != activity.CreatorUserId && !User.GetPermissions((IGuildChannel) Context.Channel).ManageMessages)
|
||||||
{
|
{
|
||||||
await RespondAsync(
|
await RespondAsync(
|
||||||
ephemeral: true,
|
ephemeral: true,
|
||||||
@@ -378,6 +329,107 @@ public partial class ActivityModule : InteractionModuleBase<SocketInteractionCon
|
|||||||
await Context.Channel.DeleteMessageAsync(messageId);
|
await Context.Channel.DeleteMessageAsync(messageId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async Task<bool> AddUserToActivity(Activity activity, SocketGuildUser user, bool self)
|
||||||
|
{
|
||||||
|
// If player is already registered
|
||||||
|
if (await _activitiesRepository.FindActivityPlayer(activity.GuildId, activity.ChannelId, activity.MessageId, user.Id) is not
|
||||||
|
null)
|
||||||
|
{
|
||||||
|
await RespondAsync(
|
||||||
|
ephemeral: true,
|
||||||
|
embed: EmbedUtils.ErrorEmbed(self ? "Vous êtes **déjà inscrit** à cette activité" : $"{user.DisplayName} est **déjà inscrit** à cette activité").Build()
|
||||||
|
);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if activity is full
|
||||||
|
if (await _activitiesRepository.ActivityPlayerCount(activity) >= activity.MaxPlayers)
|
||||||
|
{
|
||||||
|
await RespondAsync(
|
||||||
|
ephemeral: true,
|
||||||
|
embed: EmbedUtils.ErrorEmbed("L'activité est **complète**").Build()
|
||||||
|
);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
_logger.LogTrace("Player {Player} joined activity {Id}", user.DisplayName, activity.MessageId);
|
||||||
|
|
||||||
|
var activityPlayer = CreateActivityPlayer(activity, user, activity.AreRolesEnabled);
|
||||||
|
|
||||||
|
// Add player to activity
|
||||||
|
activity.ActivityPlayers.Add(activityPlayer);
|
||||||
|
await _activitiesRepository.SaveChanges();
|
||||||
|
|
||||||
|
// Update activity embed
|
||||||
|
await UpdateActivityEmbed(activity, ActivityUpdateReason.PlayerJoin);
|
||||||
|
|
||||||
|
// Send join message to thread and add user to thread
|
||||||
|
var thread = Context.Guild.GetThreadChannel(activity.ThreadId);
|
||||||
|
|
||||||
|
await thread.AddUserAsync(user);
|
||||||
|
|
||||||
|
string embedContent = $"**{user.DisplayName}** a été **ajouté** à l'activité";
|
||||||
|
if (self)
|
||||||
|
{
|
||||||
|
await thread.SendMessageAsync(
|
||||||
|
embed: EmbedUtils.InfoEmbed(embedContent).Build()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
await RespondAsync(
|
||||||
|
embed: EmbedUtils.InfoEmbed(embedContent).Build()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task<bool> RemovePlayerFromActivity(Activity activity, SocketGuildUser user, bool self)
|
||||||
|
{
|
||||||
|
// Check if player is in activity
|
||||||
|
if (await _activitiesRepository.FindActivityPlayer(activity.GuildId, activity.ChannelId, activity.MessageId, user.Id) is not { } activityPlayer)
|
||||||
|
{
|
||||||
|
await RespondAsync(
|
||||||
|
ephemeral: true,
|
||||||
|
embed: EmbedUtils.ErrorEmbed(self ? "Vous n'êtes **pas inscrit** à cette activité" : $"{user.DisplayName} n'est **pas inscrit** à cette activité").Build()
|
||||||
|
);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
_logger.LogTrace("Player {Player} left activity {Id}", user.DisplayName, activity.MessageId);
|
||||||
|
|
||||||
|
activity.ActivityPlayers.Remove(activityPlayer);
|
||||||
|
await _activitiesRepository.SaveChanges();
|
||||||
|
|
||||||
|
// Update activity embed
|
||||||
|
await UpdateActivityEmbed(activity, ActivityUpdateReason.PlayerLeave);
|
||||||
|
|
||||||
|
// Send leave message to thread and remove user from thread
|
||||||
|
var thread = Context.Guild.GetThreadChannel(activity.ThreadId);
|
||||||
|
|
||||||
|
await thread.RemoveUserAsync(user);
|
||||||
|
|
||||||
|
string embedContent = $"{user.DisplayName} a été **enlevé** de l'activité";
|
||||||
|
if (self)
|
||||||
|
{
|
||||||
|
await thread.SendMessageAsync(
|
||||||
|
embed: EmbedUtils.InfoEmbed(embedContent).Build()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
await RespondAsync(
|
||||||
|
embed: EmbedUtils.InfoEmbed(embedContent).Build()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
private async Task UpdateActivityEmbed(Activity activity, ActivityUpdateReason updateReason)
|
private async Task UpdateActivityEmbed(Activity activity, ActivityUpdateReason updateReason)
|
||||||
{
|
{
|
||||||
// Get channel
|
// Get channel
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
using System.Text;
|
||||||
using Cocotte.Modules.Activities.Models;
|
using Cocotte.Modules.Activities.Models;
|
||||||
using Cocotte.Utils;
|
using Cocotte.Utils;
|
||||||
using Discord;
|
using Discord;
|
||||||
@@ -56,34 +57,12 @@ public partial class ActivityModule
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check that the user is not already in the activity
|
await AddUserToActivity(activity, (SocketGuildUser) user, self: false);
|
||||||
if (await _activitiesRepository.ActivityContainsUser(activity, user.Id))
|
|
||||||
{
|
|
||||||
await RespondAsync(
|
|
||||||
ephemeral: true,
|
|
||||||
embed: EmbedUtils.ErrorEmbed("Cet utilisateur est **déjà inscrit** à cette activité").Build()
|
|
||||||
);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var activityPlayer = CreateActivityPlayer(activity, (SocketGuildUser) user, activity.AreRolesEnabled);
|
|
||||||
|
|
||||||
activity.ActivityPlayers.Add(activityPlayer);
|
|
||||||
await _activitiesRepository.SaveChanges();
|
|
||||||
|
|
||||||
await UpdateActivityEmbed(activity, ActivityUpdateReason.PlayerJoin);
|
|
||||||
|
|
||||||
await RespondAsync(
|
|
||||||
ephemeral: true,
|
|
||||||
embed: EmbedUtils.SuccessEmbed($"{((IGuildUser) user).DisplayName} a bien été **ajouté** à l'activité").Build()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[SlashCommand("ajouter", "Ajouter un joueur à cette activité")]
|
[SlashCommand("enlever", "Enlever un joueur de cette activité")]
|
||||||
public async Task ThreadRemovePlayer(IUser user)
|
public async Task ThreadRemovePlayer(IUser user)
|
||||||
{
|
{
|
||||||
// TODO: Autocomplete
|
|
||||||
// Get activity linked to this thread
|
// Get activity linked to this thread
|
||||||
var activity = _activitiesRepository.FindActivityByThreadId(Context.Channel.Id);
|
var activity = _activitiesRepository.FindActivityByThreadId(Context.Channel.Id);
|
||||||
|
|
||||||
@@ -92,31 +71,32 @@ public partial class ActivityModule
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check that the user is not already in the activity
|
await RemovePlayerFromActivity(activity, (SocketGuildUser) user, self: false);
|
||||||
if (await _activitiesRepository.ActivityContainsUser(activity, user.Id))
|
}
|
||||||
{
|
|
||||||
await RespondAsync(
|
|
||||||
ephemeral: true,
|
|
||||||
embed: EmbedUtils.ErrorEmbed("Cet utilisateur est **déjà inscrit** à cette activité").Build()
|
|
||||||
);
|
|
||||||
|
|
||||||
|
[SlashCommand("ping", "Ping les joueurs inscrits à cette activité")]
|
||||||
|
public async Task ThreadPingPlayers(string message = "**Appel de groupe**")
|
||||||
|
{
|
||||||
|
// Get activity linked to this thread
|
||||||
|
var activity = _activitiesRepository.FindActivityByThreadId(Context.Channel.Id);
|
||||||
|
|
||||||
|
if (!await CheckCommandInThread(activity) || activity is null)
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var activityPlayer = CreateActivityPlayer(activity, (SocketGuildUser) user, activity.AreRolesEnabled);
|
// Get user ids
|
||||||
|
var userIds = await _activitiesRepository.GetActivityPlayerIds(activity);
|
||||||
|
|
||||||
activity.ActivityPlayers.Add(activityPlayer);
|
|
||||||
await _activitiesRepository.SaveChanges();
|
|
||||||
|
|
||||||
await UpdateActivityEmbed(activity, ActivityUpdateReason.PlayerJoin);
|
// Generate message
|
||||||
|
var pingMessageBuilder = new StringBuilder(message);
|
||||||
|
pingMessageBuilder.AppendLine("\n");
|
||||||
|
pingMessageBuilder.Append(string.Join(", ", userIds.Select(id => MentionUtils.MentionUser(id))));
|
||||||
|
|
||||||
await RespondAsync(
|
await RespondAsync(pingMessageBuilder.ToString());
|
||||||
ephemeral: true,
|
|
||||||
embed: EmbedUtils.SuccessEmbed($"{((IGuildUser) user).DisplayName} a bien été **ajouté** à l'activité").Build()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private async Task<bool> CheckCommandInThread(Activity? activity)
|
private async Task<bool> CheckCommandInThread(Activity? activity)
|
||||||
{
|
{
|
||||||
// Check if activity is not null (means we are in a valid thread)
|
// Check if activity is not null (means we are in a valid thread)
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ public class ActivitiesRepository
|
|||||||
return await _cocotteDbContext.ActivityPlayers.FindAsync(guildId, channelId, messageId, userId);
|
return await _cocotteDbContext.ActivityPlayers.FindAsync(guildId, channelId, messageId, userId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int ActivityPlayerCount(Activity activity) => activity.ActivityPlayers.Count;
|
public async Task<int> ActivityPlayerCount(Activity activity) => await _cocotteDbContext.Entry(activity).Collection(a => a.ActivityPlayers).Query().CountAsync();
|
||||||
|
|
||||||
public async Task<IReadOnlyCollection<ActivityPlayer>> LoadActivityPlayers(Activity activity)
|
public async Task<IReadOnlyCollection<ActivityPlayer>> LoadActivityPlayers(Activity activity)
|
||||||
{
|
{
|
||||||
@@ -61,4 +61,13 @@ public class ActivitiesRepository
|
|||||||
.Query()
|
.Query()
|
||||||
.AnyAsync(p => p.UserId == userId);
|
.AnyAsync(p => p.UserId == userId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<IList<ulong>> GetActivityPlayerIds(Activity activity)
|
||||||
|
{
|
||||||
|
return await _cocotteDbContext.Entry(activity)
|
||||||
|
.Collection(a => a.ActivityPlayers)
|
||||||
|
.Query()
|
||||||
|
.Select(p => p.UserId)
|
||||||
|
.ToListAsync();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -72,7 +72,7 @@ await using(var scope = host.Services.CreateAsyncScope())
|
|||||||
if (hostEnvironment.IsDevelopment())
|
if (hostEnvironment.IsDevelopment())
|
||||||
{
|
{
|
||||||
var dbContext = scope.ServiceProvider.GetRequiredService<CocotteDbContext>();
|
var dbContext = scope.ServiceProvider.GetRequiredService<CocotteDbContext>();
|
||||||
await dbContext.Database.EnsureDeletedAsync();
|
// await dbContext.Database.EnsureDeletedAsync();
|
||||||
await dbContext.Database.EnsureCreatedAsync();
|
await dbContext.Database.EnsureCreatedAsync();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user