Compare commits
2 Commits
3f2dc16fad
...
ef948dba27
| Author | SHA1 | Date | |
|---|---|---|---|
| ef948dba27 | |||
| 8dcefeeb39 |
@@ -22,13 +22,13 @@ public class ActivityFormatter
|
|||||||
{
|
{
|
||||||
ActivityName.Abyss => "Abîme du Néant",
|
ActivityName.Abyss => "Abîme du Néant",
|
||||||
ActivityName.Raids => "Raids",
|
ActivityName.Raids => "Raids",
|
||||||
ActivityName.FrontierClash => "Conflit Frontalier",
|
ActivityName.FrontierClash => "Conflit frontalier",
|
||||||
ActivityName.VoidRift => "Failles du Néant",
|
ActivityName.VoidRift => "Failles du néant",
|
||||||
ActivityName.OriginsOfWar => "Origine de la Guerre",
|
ActivityName.OriginsOfWar => "Origine de la guerre",
|
||||||
ActivityName.JointOperation => "Opération Conjointe",
|
ActivityName.JointOperation => "Opération conjointe",
|
||||||
ActivityName.InterstellarExploration => "Exploration Interstellaire",
|
ActivityName.InterstellarExploration => "Exploration interstellaire",
|
||||||
ActivityName.BreakFromDestiny => "Échapper au Destin (3v3)",
|
ActivityName.BreakFromDestiny => "Échapper au destin (3v3)",
|
||||||
ActivityName.CriticalAbyss => "Abîme Critique (8v8)",
|
ActivityName.CriticalAbyss => "Abîme critique (8v8)",
|
||||||
ActivityName.Event => "Event",
|
ActivityName.Event => "Event",
|
||||||
ActivityName.Fishing => "Pêche",
|
ActivityName.Fishing => "Pêche",
|
||||||
ActivityName.MirroriaRace => "Course Mirroria",
|
ActivityName.MirroriaRace => "Course Mirroria",
|
||||||
@@ -38,10 +38,16 @@ public class ActivityFormatter
|
|||||||
|
|
||||||
public EmbedBuilder ActivityEmbed(Activity activity, IReadOnlyCollection<ActivityPlayer> players)
|
public EmbedBuilder ActivityEmbed(Activity activity, IReadOnlyCollection<ActivityPlayer> players)
|
||||||
{
|
{
|
||||||
|
// Activity full
|
||||||
|
bool activityFull = players.Count >= activity.MaxPlayers;
|
||||||
|
|
||||||
|
// Compute padding using player with longest name
|
||||||
|
var namePadding = players.Count > 0 ? players.Max(p => p.Name.Length) : 0;
|
||||||
|
|
||||||
// Players field
|
// Players field
|
||||||
var playersField = new EmbedFieldBuilder()
|
var playersField = new EmbedFieldBuilder()
|
||||||
.WithName("Joueurs inscrits")
|
.WithName("Joueurs inscrits")
|
||||||
.WithValue($"{(!players.Any() ? "*Aucun joueur inscrit*" : string.Join("\n", players.Select(FormatActivityPlayer)))}");
|
.WithValue($"{(!players.Any() ? "*Aucun joueur inscrit*" : string.Join("\n", players.Select(p => FormatActivityPlayer(p, namePadding))))}");
|
||||||
|
|
||||||
var title = activity switch
|
var title = activity switch
|
||||||
{
|
{
|
||||||
@@ -50,12 +56,18 @@ public class ActivityFormatter
|
|||||||
_ => $"{FormatActivityName(activity.Name)} ({players.Count}/{activity.MaxPlayers})"
|
_ => $"{FormatActivityName(activity.Name)} ({players.Count}/{activity.MaxPlayers})"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
string description = string.IsNullOrWhiteSpace(activity.Description)
|
||||||
|
? $"Rejoignez l'activité de {MentionUtils.MentionUser(activity.CreatorDiscordId)}"
|
||||||
|
: activity.Description;
|
||||||
|
|
||||||
string bannerUrl = $"https://sage.cdn.ilysix.fr/assets/Cocotte/banner/{GetActivityCode(activity.Name)}.webp";
|
string bannerUrl = $"https://sage.cdn.ilysix.fr/assets/Cocotte/banner/{GetActivityCode(activity.Name)}.webp";
|
||||||
|
|
||||||
|
var color = activityFull ? Colors.CocotteOrange : Colors.CocotteBlue;
|
||||||
|
|
||||||
return new EmbedBuilder()
|
return new EmbedBuilder()
|
||||||
.WithColor(Colors.CocotteBlue)
|
.WithColor(color)
|
||||||
.WithTitle(title)
|
.WithTitle(title)
|
||||||
.WithDescription($"{activity.Description}")
|
.WithDescription(description)
|
||||||
.WithImageUrl(bannerUrl)
|
.WithImageUrl(bannerUrl)
|
||||||
.WithFields(playersField);
|
.WithFields(playersField);
|
||||||
}
|
}
|
||||||
@@ -65,7 +77,7 @@ public class ActivityFormatter
|
|||||||
ActivityName.Abyss => "VA",
|
ActivityName.Abyss => "VA",
|
||||||
ActivityName.OriginsOfWar => "OOW",
|
ActivityName.OriginsOfWar => "OOW",
|
||||||
ActivityName.Raids => "RD",
|
ActivityName.Raids => "RD",
|
||||||
ActivityName.FrontierClash => "FC",
|
ActivityName.FrontierClash => "FCH",
|
||||||
ActivityName.VoidRift => "VR",
|
ActivityName.VoidRift => "VR",
|
||||||
ActivityName.JointOperation => "JO",
|
ActivityName.JointOperation => "JO",
|
||||||
ActivityName.InterstellarExploration => "IE",
|
ActivityName.InterstellarExploration => "IE",
|
||||||
@@ -77,9 +89,9 @@ public class ActivityFormatter
|
|||||||
_ => "NA"
|
_ => "NA"
|
||||||
};
|
};
|
||||||
|
|
||||||
public string FormatActivityPlayer(ActivityPlayer player) => player switch
|
public string FormatActivityPlayer(ActivityPlayer player, int namePadding) => player switch
|
||||||
{
|
{
|
||||||
ActivityRolePlayer rolePlayer => $"{player.Name} - {RolesToEmotes(rolePlayer.Roles)}",
|
ActivityRolePlayer rolePlayer => $"` {player.Name.PadRight(namePadding)} ` **―** {RolesToEmotes(rolePlayer.Roles)}",
|
||||||
_ => $"{player.Name})"
|
_ => $"{player.Name})"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -45,9 +45,9 @@ public partial class ActivityModule : InteractionModuleBase<SocketInteractionCon
|
|||||||
}
|
}
|
||||||
|
|
||||||
[SlashCommand("abime", "Créer un groupe pour l'Abîme du Néant")]
|
[SlashCommand("abime", "Créer un groupe pour l'Abîme du Néant")]
|
||||||
public async Task ActivityAbyss([Summary("étage", "A quel étage êtes vous")] uint stage, [Summary("description", "Message accompagnant la demande de groupe")] string description = "")
|
public async Task ActivityAbyss([Summary("étage", "A quel étage êtes vous")] [MinValue(1), MaxValue(6)] uint stage, [Summary("description", "Message accompagnant la demande de groupe")] string description = "")
|
||||||
{
|
{
|
||||||
const ActivityName activityName = ActivityName.OriginsOfWar;
|
const ActivityName activityName = ActivityName.Abyss;
|
||||||
var activityType = ActivityHelper.ActivityNameToType(activityName);
|
var activityType = ActivityHelper.ActivityNameToType(activityName);
|
||||||
var maxPlayers = ActivityHelper.ActivityTypeToMaxPlayers(activityType);
|
var maxPlayers = ActivityHelper.ActivityTypeToMaxPlayers(activityType);
|
||||||
|
|
||||||
@@ -59,6 +59,7 @@ public partial class ActivityModule : InteractionModuleBase<SocketInteractionCon
|
|||||||
Description = description,
|
Description = description,
|
||||||
Type = activityType,
|
Type = activityType,
|
||||||
Name = activityName,
|
Name = activityName,
|
||||||
|
RoleEnabled = true,
|
||||||
MaxPlayers = maxPlayers,
|
MaxPlayers = maxPlayers,
|
||||||
Stage = stage
|
Stage = stage
|
||||||
};
|
};
|
||||||
@@ -93,7 +94,7 @@ public partial class ActivityModule : InteractionModuleBase<SocketInteractionCon
|
|||||||
await _activitiesRepository.SaveChanges();
|
await _activitiesRepository.SaveChanges();
|
||||||
|
|
||||||
// Add components
|
// Add components
|
||||||
var components = ActivityRoleComponent(activity.ActivityId);
|
var components = ActivityComponents(activity.ActivityId);
|
||||||
|
|
||||||
await ModifyOriginalResponseAsync(m =>
|
await ModifyOriginalResponseAsync(m =>
|
||||||
{
|
{
|
||||||
@@ -103,8 +104,8 @@ public partial class ActivityModule : InteractionModuleBase<SocketInteractionCon
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
[ComponentInteraction("activity join_role:*", ignoreGroupNames: true)]
|
[ComponentInteraction("activity join:*", ignoreGroupNames: true)]
|
||||||
private async Task JoinActivityRole(ulong activityId)
|
private async Task JoinActivity(ulong activityId)
|
||||||
{
|
{
|
||||||
var user = (SocketGuildUser)Context.User;
|
var user = (SocketGuildUser)Context.User;
|
||||||
|
|
||||||
@@ -120,7 +121,7 @@ public partial class ActivityModule : InteractionModuleBase<SocketInteractionCon
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If player is already registered
|
// If player is already registered
|
||||||
if (await _activitiesRepository.FindActivityRolePlayer(activityId, user.Id) is not null)
|
if (await _activitiesRepository.FindActivityPlayer(activityId, user.Id) is not null)
|
||||||
{
|
{
|
||||||
await RespondAsync(
|
await RespondAsync(
|
||||||
ephemeral: true,
|
ephemeral: true,
|
||||||
@@ -143,21 +144,25 @@ public partial class ActivityModule : InteractionModuleBase<SocketInteractionCon
|
|||||||
|
|
||||||
_logger.LogTrace("Player {Player} joined activity {Id}", user.DisplayName, activityId);
|
_logger.LogTrace("Player {Player} joined activity {Id}", user.DisplayName, activityId);
|
||||||
|
|
||||||
var roles = _activityHelper.GetPlayerRoles(user.Roles);
|
var activityPlayer = activity.RoleEnabled ? new ActivityRolePlayer
|
||||||
var activityRolePlayer = new ActivityRolePlayer
|
|
||||||
{
|
{
|
||||||
Activity = activity,
|
Activity = activity,
|
||||||
DiscordId = user.Id,
|
DiscordId = user.Id,
|
||||||
Name = user.DisplayName,
|
Name = user.DisplayName,
|
||||||
Roles = roles
|
Roles = _activityHelper.GetPlayerRoles(user.Roles)
|
||||||
|
} : new ActivityPlayer
|
||||||
|
{
|
||||||
|
Activity = activity,
|
||||||
|
DiscordId = user.Id,
|
||||||
|
Name = user.DisplayName
|
||||||
};
|
};
|
||||||
|
|
||||||
// Add player to activity
|
// Add player to activity
|
||||||
activity.ActivityPlayers.Add(activityRolePlayer);
|
activity.ActivityPlayers.Add(activityPlayer);
|
||||||
await _activitiesRepository.SaveChanges();
|
await _activitiesRepository.SaveChanges();
|
||||||
|
|
||||||
// Update activity embed
|
// Update activity embed
|
||||||
await UpdateActivityEmbed(activity);
|
await UpdateActivityEmbed(activity, ActivityUpdateReason.PlayerJoin);
|
||||||
|
|
||||||
await RespondAsync(
|
await RespondAsync(
|
||||||
ephemeral: true,
|
ephemeral: true,
|
||||||
@@ -165,8 +170,8 @@ public partial class ActivityModule : InteractionModuleBase<SocketInteractionCon
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
[ComponentInteraction("activity leave_role:*", ignoreGroupNames: true)]
|
[ComponentInteraction("activity leave:*", ignoreGroupNames: true)]
|
||||||
private async Task LeaveActivityRole(ulong activityId)
|
private async Task LeaveActivity(ulong activityId)
|
||||||
{
|
{
|
||||||
var user = (IGuildUser)Context.User;
|
var user = (IGuildUser)Context.User;
|
||||||
|
|
||||||
@@ -198,7 +203,7 @@ public partial class ActivityModule : InteractionModuleBase<SocketInteractionCon
|
|||||||
await _activitiesRepository.SaveChanges();
|
await _activitiesRepository.SaveChanges();
|
||||||
|
|
||||||
// Update activity embed
|
// Update activity embed
|
||||||
await UpdateActivityEmbed(activity);
|
await UpdateActivityEmbed(activity, ActivityUpdateReason.PlayerLeave);
|
||||||
|
|
||||||
await RespondAsync(
|
await RespondAsync(
|
||||||
ephemeral: true,
|
ephemeral: true,
|
||||||
@@ -206,15 +211,7 @@ public partial class ActivityModule : InteractionModuleBase<SocketInteractionCon
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// [ComponentInteraction("activity event_join:*", ignoreGroupNames: true)]
|
private async Task UpdateActivityEmbed(Activity activity, ActivityUpdateReason updateReason)
|
||||||
// private async Task JoinEventActivity(ulong activityId)
|
|
||||||
// {
|
|
||||||
// _logger.LogTrace("Player {Player} joined activity {Id}", ((IGuildUser)Context.User).DisplayName, activityId);
|
|
||||||
//
|
|
||||||
// await RespondAsync(activityId.ToString());
|
|
||||||
// }
|
|
||||||
|
|
||||||
private async Task UpdateActivityEmbed(Activity activity)
|
|
||||||
{
|
{
|
||||||
// Get channel
|
// Get channel
|
||||||
var channel = await Context.Interaction.GetChannelAsync();
|
var channel = await Context.Interaction.GetChannelAsync();
|
||||||
@@ -230,22 +227,34 @@ public partial class ActivityModule : InteractionModuleBase<SocketInteractionCon
|
|||||||
await channel.ModifyMessageAsync(activity.ActivityId, properties =>
|
await channel.ModifyMessageAsync(activity.ActivityId, properties =>
|
||||||
{
|
{
|
||||||
properties.Embed = _activityFormatter.ActivityEmbed(activity, players).Build();
|
properties.Embed = _activityFormatter.ActivityEmbed(activity, players).Build();
|
||||||
|
|
||||||
|
// Disable join button if the activity is full on join, enable it on leave if activity is not full anymore
|
||||||
|
var isActivityFull = players.Count >= activity.MaxPlayers;
|
||||||
|
properties.Components = updateReason switch
|
||||||
|
{
|
||||||
|
ActivityUpdateReason.PlayerJoin when isActivityFull => ActivityComponents(activity.ActivityId, disabled: true).Build(),
|
||||||
|
ActivityUpdateReason.PlayerLeave when !isActivityFull => ActivityComponents(activity.ActivityId, disabled: false).Build(),
|
||||||
|
_ => Optional<MessageComponent>.Unspecified
|
||||||
|
};
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ComponentBuilder ActivityRoleComponent(ulong activityId)
|
private static ComponentBuilder ActivityComponents(ulong activityId, bool disabled = false)
|
||||||
{
|
{
|
||||||
return new ComponentBuilder()
|
return new ComponentBuilder()
|
||||||
.AddRow(new ActionRowBuilder()
|
.AddRow(new ActionRowBuilder()
|
||||||
.WithButton(new ButtonBuilder()
|
.WithButton(new ButtonBuilder()
|
||||||
.WithLabel("Rejoindre l'activité")
|
.WithLabel("Rejoindre l'activité")
|
||||||
.WithCustomId($"activity join_role:{activityId}")
|
.WithCustomId($"activity join:{activityId}")
|
||||||
|
.WithEmote(":white_check_mark:".ToEmote())
|
||||||
.WithStyle(ButtonStyle.Primary)
|
.WithStyle(ButtonStyle.Primary)
|
||||||
|
.WithDisabled(disabled)
|
||||||
)
|
)
|
||||||
.WithButton(new ButtonBuilder()
|
.WithButton(new ButtonBuilder()
|
||||||
.WithLabel("Se désinscrire de l'activité")
|
.WithLabel("Se désinscrire de l'activité")
|
||||||
.WithCustomId($"activity leave_role:{activityId}")
|
.WithCustomId($"activity leave:{activityId}")
|
||||||
.WithStyle(ButtonStyle.Danger)
|
.WithEmote(":x:".ToEmote())
|
||||||
|
.WithStyle(ButtonStyle.Secondary)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ public partial class ActivityModule
|
|||||||
activity.ActivityPlayers.Add(player);
|
activity.ActivityPlayers.Add(player);
|
||||||
await _activitiesRepository.SaveChanges();
|
await _activitiesRepository.SaveChanges();
|
||||||
|
|
||||||
await UpdateActivityEmbed(activity);
|
await UpdateActivityEmbed(activity, ActivityUpdateReason.PlayerJoin);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
8
Cocotte/Modules/Activities/ActivityUpdateReason.cs
Normal file
8
Cocotte/Modules/Activities/ActivityUpdateReason.cs
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
namespace Cocotte.Modules.Activities;
|
||||||
|
|
||||||
|
public enum ActivityUpdateReason
|
||||||
|
{
|
||||||
|
PlayerJoin,
|
||||||
|
PlayerLeave,
|
||||||
|
Update
|
||||||
|
}
|
||||||
@@ -17,21 +17,11 @@ public class ActivitiesRepository
|
|||||||
return await _cocotteDbContext.Activities.FindAsync(activityId);
|
return await _cocotteDbContext.Activities.FindAsync(activityId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<StagedActivity?> FindStagedActivity(ulong activityId)
|
|
||||||
{
|
|
||||||
return await _cocotteDbContext.StagedActivities.FindAsync(activityId);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<ActivityPlayer?> FindActivityPlayer(ulong activityId, ulong playerId)
|
public async Task<ActivityPlayer?> FindActivityPlayer(ulong activityId, ulong playerId)
|
||||||
{
|
{
|
||||||
return await _cocotteDbContext.ActivityPlayers.FindAsync(activityId, playerId);
|
return await _cocotteDbContext.ActivityPlayers.FindAsync(activityId, playerId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<ActivityRolePlayer?> FindActivityRolePlayer(ulong activityId, ulong playerId)
|
|
||||||
{
|
|
||||||
return await _cocotteDbContext.ActivityRolePlayers.FindAsync(activityId, playerId);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<int> ActivityPlayerCount(Activity activity) =>
|
public async Task<int> ActivityPlayerCount(Activity activity) =>
|
||||||
await _cocotteDbContext.ActivityPlayers.Where(player => player.ActivityId == activity.ActivityId).CountAsync();
|
await _cocotteDbContext.ActivityPlayers.Where(player => player.ActivityId == activity.ActivityId).CountAsync();
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ public abstract class Activity
|
|||||||
public string? Description { get; init; }
|
public string? Description { get; init; }
|
||||||
public required ActivityType Type { get; init; }
|
public required ActivityType Type { get; init; }
|
||||||
public required ActivityName Name { get; init; }
|
public required ActivityName Name { get; init; }
|
||||||
|
public required bool RoleEnabled { get; init; }
|
||||||
public required uint MaxPlayers { get; set; }
|
public required uint MaxPlayers { get; set; }
|
||||||
|
|
||||||
public List<ActivityPlayer> ActivityPlayers { get; init; } = new();
|
public List<ActivityPlayer> ActivityPlayers { get; init; } = new();
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ public static class Colors
|
|||||||
{
|
{
|
||||||
// Main Cocotte colors
|
// Main Cocotte colors
|
||||||
public static Color CocotteBlue => new(0x3196c8);
|
public static Color CocotteBlue => new(0x3196c8);
|
||||||
|
public static Color CocotteRed => new(0xe40808);
|
||||||
|
public static Color CocotteOrange => new(0xff6d01);
|
||||||
|
|
||||||
// Colors used in embeds
|
// Colors used in embeds
|
||||||
public static Color ErrorColor => new(0xFB6060);
|
public static Color ErrorColor => new(0xFB6060);
|
||||||
|
|||||||
Reference in New Issue
Block a user