From 4b23dfd8a0f6abf0d5adafe7dd9ae495376ff07b Mon Sep 17 00:00:00 2001 From: Eveldee Date: Mon, 10 Apr 2023 12:26:17 +0200 Subject: [PATCH] [Activity] Add has completed command --- ..._AddActivityPlayerHasCompleted.Designer.cs | 689 ++++++++++++++++++ ...410102447_AddActivityPlayerHasCompleted.cs | 29 + .../CocotteDbContextModelSnapshot.cs | 3 + .../Modules/Activities/ActivityFormatter.cs | 9 +- .../Activities/ActivityModuleThread.cs | 62 ++ .../Activities/Models/ActivityPlayer.cs | 1 + 6 files changed, 791 insertions(+), 2 deletions(-) create mode 100644 Cocotte/Migrations/20230410102447_AddActivityPlayerHasCompleted.Designer.cs create mode 100644 Cocotte/Migrations/20230410102447_AddActivityPlayerHasCompleted.cs diff --git a/Cocotte/Migrations/20230410102447_AddActivityPlayerHasCompleted.Designer.cs b/Cocotte/Migrations/20230410102447_AddActivityPlayerHasCompleted.Designer.cs new file mode 100644 index 0000000..ddd50ba --- /dev/null +++ b/Cocotte/Migrations/20230410102447_AddActivityPlayerHasCompleted.Designer.cs @@ -0,0 +1,689 @@ +// +using System; +using Cocotte.Services; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace Cocotte.Migrations +{ + [DbContext(typeof(CocotteDbContext))] + [Migration("20230410102447_AddActivityPlayerHasCompleted")] + partial class AddActivityPlayerHasCompleted + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder.HasAnnotation("ProductVersion", "7.0.4"); + + modelBuilder.Entity("AppAny.Quartz.EntityFrameworkCore.Migrations.QuartzBlobTrigger", b => + { + b.Property("SchedulerName") + .HasColumnType("text") + .HasColumnName("SCHED_NAME"); + + b.Property("TriggerName") + .HasColumnType("text") + .HasColumnName("TRIGGER_NAME"); + + b.Property("TriggerGroup") + .HasColumnType("text") + .HasColumnName("TRIGGER_GROUP"); + + b.Property("BlobData") + .HasColumnType("bytea") + .HasColumnName("BLOB_DATA"); + + b.HasKey("SchedulerName", "TriggerName", "TriggerGroup"); + + b.ToTable("QRTZ_BLOB_TRIGGERS", (string)null); + }); + + modelBuilder.Entity("AppAny.Quartz.EntityFrameworkCore.Migrations.QuartzCalendar", b => + { + b.Property("SchedulerName") + .HasColumnType("text") + .HasColumnName("SCHED_NAME"); + + b.Property("CalendarName") + .HasColumnType("text") + .HasColumnName("CALENDAR_NAME"); + + b.Property("Calendar") + .IsRequired() + .HasColumnType("bytea") + .HasColumnName("CALENDAR"); + + b.HasKey("SchedulerName", "CalendarName"); + + b.ToTable("QRTZ_CALENDARS", (string)null); + }); + + modelBuilder.Entity("AppAny.Quartz.EntityFrameworkCore.Migrations.QuartzCronTrigger", b => + { + b.Property("SchedulerName") + .HasColumnType("text") + .HasColumnName("SCHED_NAME"); + + b.Property("TriggerName") + .HasColumnType("text") + .HasColumnName("TRIGGER_NAME"); + + b.Property("TriggerGroup") + .HasColumnType("text") + .HasColumnName("TRIGGER_GROUP"); + + b.Property("CronExpression") + .IsRequired() + .HasColumnType("text") + .HasColumnName("CRON_EXPRESSION"); + + b.Property("TimeZoneId") + .HasColumnType("text") + .HasColumnName("TIME_ZONE_ID"); + + b.HasKey("SchedulerName", "TriggerName", "TriggerGroup"); + + b.ToTable("QRTZ_CRON_TRIGGERS", (string)null); + }); + + modelBuilder.Entity("AppAny.Quartz.EntityFrameworkCore.Migrations.QuartzFiredTrigger", b => + { + b.Property("SchedulerName") + .HasColumnType("text") + .HasColumnName("SCHED_NAME"); + + b.Property("EntryId") + .HasColumnType("text") + .HasColumnName("ENTRY_ID"); + + b.Property("FiredTime") + .HasColumnType("bigint") + .HasColumnName("FIRED_TIME"); + + b.Property("InstanceName") + .IsRequired() + .HasColumnType("text") + .HasColumnName("INSTANCE_NAME"); + + b.Property("IsNonConcurrent") + .HasColumnType("bool") + .HasColumnName("IS_NONCONCURRENT"); + + b.Property("JobGroup") + .HasColumnType("text") + .HasColumnName("JOB_GROUP"); + + b.Property("JobName") + .HasColumnType("text") + .HasColumnName("JOB_NAME"); + + b.Property("Priority") + .HasColumnType("integer") + .HasColumnName("PRIORITY"); + + b.Property("RequestsRecovery") + .HasColumnType("bool") + .HasColumnName("REQUESTS_RECOVERY"); + + b.Property("ScheduledTime") + .HasColumnType("bigint") + .HasColumnName("SCHED_TIME"); + + b.Property("State") + .IsRequired() + .HasColumnType("text") + .HasColumnName("STATE"); + + b.Property("TriggerGroup") + .IsRequired() + .HasColumnType("text") + .HasColumnName("TRIGGER_GROUP"); + + b.Property("TriggerName") + .IsRequired() + .HasColumnType("text") + .HasColumnName("TRIGGER_NAME"); + + b.HasKey("SchedulerName", "EntryId"); + + b.HasIndex("InstanceName") + .HasDatabaseName("IDX_QRTZ_FT_TRIG_INST_NAME"); + + b.HasIndex("JobGroup") + .HasDatabaseName("IDX_QRTZ_FT_JOB_GROUP"); + + b.HasIndex("JobName") + .HasDatabaseName("IDX_QRTZ_FT_JOB_NAME"); + + b.HasIndex("RequestsRecovery") + .HasDatabaseName("IDX_QRTZ_FT_JOB_REQ_RECOVERY"); + + b.HasIndex("TriggerGroup") + .HasDatabaseName("IDX_QRTZ_FT_TRIG_GROUP"); + + b.HasIndex("TriggerName") + .HasDatabaseName("IDX_QRTZ_FT_TRIG_NAME"); + + b.HasIndex("SchedulerName", "TriggerName", "TriggerGroup") + .HasDatabaseName("IDX_QRTZ_FT_TRIG_NM_GP"); + + b.ToTable("QRTZ_FIRED_TRIGGERS", (string)null); + }); + + modelBuilder.Entity("AppAny.Quartz.EntityFrameworkCore.Migrations.QuartzJobDetail", b => + { + b.Property("SchedulerName") + .HasColumnType("text") + .HasColumnName("SCHED_NAME"); + + b.Property("JobName") + .HasColumnType("text") + .HasColumnName("JOB_NAME"); + + b.Property("JobGroup") + .HasColumnType("text") + .HasColumnName("JOB_GROUP"); + + b.Property("Description") + .HasColumnType("text") + .HasColumnName("DESCRIPTION"); + + b.Property("IsDurable") + .HasColumnType("bool") + .HasColumnName("IS_DURABLE"); + + b.Property("IsNonConcurrent") + .HasColumnType("bool") + .HasColumnName("IS_NONCONCURRENT"); + + b.Property("IsUpdateData") + .HasColumnType("bool") + .HasColumnName("IS_UPDATE_DATA"); + + b.Property("JobClassName") + .IsRequired() + .HasColumnType("text") + .HasColumnName("JOB_CLASS_NAME"); + + b.Property("JobData") + .HasColumnType("bytea") + .HasColumnName("JOB_DATA"); + + b.Property("RequestsRecovery") + .HasColumnType("bool") + .HasColumnName("REQUESTS_RECOVERY"); + + b.HasKey("SchedulerName", "JobName", "JobGroup"); + + b.HasIndex("RequestsRecovery") + .HasDatabaseName("IDX_QRTZ_J_REQ_RECOVERY"); + + b.ToTable("QRTZ_JOB_DETAILS", (string)null); + }); + + modelBuilder.Entity("AppAny.Quartz.EntityFrameworkCore.Migrations.QuartzLock", b => + { + b.Property("SchedulerName") + .HasColumnType("text") + .HasColumnName("SCHED_NAME"); + + b.Property("LockName") + .HasColumnType("text") + .HasColumnName("LOCK_NAME"); + + b.HasKey("SchedulerName", "LockName"); + + b.ToTable("QRTZ_LOCKS", (string)null); + }); + + modelBuilder.Entity("AppAny.Quartz.EntityFrameworkCore.Migrations.QuartzPausedTriggerGroup", b => + { + b.Property("SchedulerName") + .HasColumnType("text") + .HasColumnName("SCHED_NAME"); + + b.Property("TriggerGroup") + .HasColumnType("text") + .HasColumnName("TRIGGER_GROUP"); + + b.HasKey("SchedulerName", "TriggerGroup"); + + b.ToTable("QRTZ_PAUSED_TRIGGER_GRPS", (string)null); + }); + + modelBuilder.Entity("AppAny.Quartz.EntityFrameworkCore.Migrations.QuartzSchedulerState", b => + { + b.Property("SchedulerName") + .HasColumnType("text") + .HasColumnName("SCHED_NAME"); + + b.Property("InstanceName") + .HasColumnType("text") + .HasColumnName("INSTANCE_NAME"); + + b.Property("CheckInInterval") + .HasColumnType("bigint") + .HasColumnName("CHECKIN_INTERVAL"); + + b.Property("LastCheckInTime") + .HasColumnType("bigint") + .HasColumnName("LAST_CHECKIN_TIME"); + + b.HasKey("SchedulerName", "InstanceName"); + + b.ToTable("QRTZ_SCHEDULER_STATE", (string)null); + }); + + modelBuilder.Entity("AppAny.Quartz.EntityFrameworkCore.Migrations.QuartzSimplePropertyTrigger", b => + { + b.Property("SchedulerName") + .HasColumnType("text") + .HasColumnName("SCHED_NAME"); + + b.Property("TriggerName") + .HasColumnType("text") + .HasColumnName("TRIGGER_NAME"); + + b.Property("TriggerGroup") + .HasColumnType("text") + .HasColumnName("TRIGGER_GROUP"); + + b.Property("BooleanProperty1") + .HasColumnType("bool") + .HasColumnName("BOOL_PROP_1"); + + b.Property("BooleanProperty2") + .HasColumnType("bool") + .HasColumnName("BOOL_PROP_2"); + + b.Property("DecimalProperty1") + .HasColumnType("numeric") + .HasColumnName("DEC_PROP_1"); + + b.Property("DecimalProperty2") + .HasColumnType("numeric") + .HasColumnName("DEC_PROP_2"); + + b.Property("IntegerProperty1") + .HasColumnType("integer") + .HasColumnName("INT_PROP_1"); + + b.Property("IntegerProperty2") + .HasColumnType("integer") + .HasColumnName("INT_PROP_2"); + + b.Property("LongProperty1") + .HasColumnType("bigint") + .HasColumnName("LONG_PROP_1"); + + b.Property("LongProperty2") + .HasColumnType("bigint") + .HasColumnName("LONG_PROP_2"); + + b.Property("StringProperty1") + .HasColumnType("text") + .HasColumnName("STR_PROP_1"); + + b.Property("StringProperty2") + .HasColumnType("text") + .HasColumnName("STR_PROP_2"); + + b.Property("StringProperty3") + .HasColumnType("text") + .HasColumnName("STR_PROP_3"); + + b.Property("TimeZoneId") + .HasColumnType("text") + .HasColumnName("TIME_ZONE_ID"); + + b.HasKey("SchedulerName", "TriggerName", "TriggerGroup"); + + b.ToTable("QRTZ_SIMPROP_TRIGGERS", (string)null); + }); + + modelBuilder.Entity("AppAny.Quartz.EntityFrameworkCore.Migrations.QuartzSimpleTrigger", b => + { + b.Property("SchedulerName") + .HasColumnType("text") + .HasColumnName("SCHED_NAME"); + + b.Property("TriggerName") + .HasColumnType("text") + .HasColumnName("TRIGGER_NAME"); + + b.Property("TriggerGroup") + .HasColumnType("text") + .HasColumnName("TRIGGER_GROUP"); + + b.Property("RepeatCount") + .HasColumnType("bigint") + .HasColumnName("REPEAT_COUNT"); + + b.Property("RepeatInterval") + .HasColumnType("bigint") + .HasColumnName("REPEAT_INTERVAL"); + + b.Property("TimesTriggered") + .HasColumnType("bigint") + .HasColumnName("TIMES_TRIGGERED"); + + b.HasKey("SchedulerName", "TriggerName", "TriggerGroup"); + + b.ToTable("QRTZ_SIMPLE_TRIGGERS", (string)null); + }); + + modelBuilder.Entity("AppAny.Quartz.EntityFrameworkCore.Migrations.QuartzTrigger", b => + { + b.Property("SchedulerName") + .HasColumnType("text") + .HasColumnName("SCHED_NAME"); + + b.Property("TriggerName") + .HasColumnType("text") + .HasColumnName("TRIGGER_NAME"); + + b.Property("TriggerGroup") + .HasColumnType("text") + .HasColumnName("TRIGGER_GROUP"); + + b.Property("CalendarName") + .HasColumnType("text") + .HasColumnName("CALENDAR_NAME"); + + b.Property("Description") + .HasColumnType("text") + .HasColumnName("DESCRIPTION"); + + b.Property("EndTime") + .HasColumnType("bigint") + .HasColumnName("END_TIME"); + + b.Property("JobData") + .HasColumnType("bytea") + .HasColumnName("JOB_DATA"); + + b.Property("JobGroup") + .IsRequired() + .HasColumnType("text") + .HasColumnName("JOB_GROUP"); + + b.Property("JobName") + .IsRequired() + .HasColumnType("text") + .HasColumnName("JOB_NAME"); + + b.Property("MisfireInstruction") + .HasColumnType("smallint") + .HasColumnName("MISFIRE_INSTR"); + + b.Property("NextFireTime") + .HasColumnType("bigint") + .HasColumnName("NEXT_FIRE_TIME"); + + b.Property("PreviousFireTime") + .HasColumnType("bigint") + .HasColumnName("PREV_FIRE_TIME"); + + b.Property("Priority") + .HasColumnType("integer") + .HasColumnName("PRIORITY"); + + b.Property("StartTime") + .HasColumnType("bigint") + .HasColumnName("START_TIME"); + + b.Property("TriggerState") + .IsRequired() + .HasColumnType("text") + .HasColumnName("TRIGGER_STATE"); + + b.Property("TriggerType") + .IsRequired() + .HasColumnType("text") + .HasColumnName("TRIGGER_TYPE"); + + b.HasKey("SchedulerName", "TriggerName", "TriggerGroup"); + + b.HasIndex("NextFireTime") + .HasDatabaseName("IDX_QRTZ_T_NEXT_FIRE_TIME"); + + b.HasIndex("TriggerState") + .HasDatabaseName("IDX_QRTZ_T_STATE"); + + b.HasIndex("NextFireTime", "TriggerState") + .HasDatabaseName("IDX_QRTZ_T_NFT_ST"); + + b.HasIndex("SchedulerName", "JobName", "JobGroup"); + + b.ToTable("QRTZ_TRIGGERS", (string)null); + }); + + modelBuilder.Entity("Cocotte.Modules.Activities.Models.Activity", b => + { + b.Property("GuildId") + .HasColumnType("INTEGER"); + + b.Property("ChannelId") + .HasColumnType("INTEGER"); + + b.Property("MessageId") + .HasColumnType("INTEGER"); + + b.Property("AreRolesEnabled") + .HasColumnType("INTEGER"); + + b.Property("CreationDate") + .HasColumnType("TEXT"); + + b.Property("CreatorDisplayName") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("CreatorUserId") + .HasColumnType("INTEGER"); + + b.Property("Description") + .HasColumnType("TEXT"); + + b.Property("Discriminator") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("DueDateTime") + .HasColumnType("TEXT"); + + b.Property("IsClosed") + .HasColumnType("INTEGER"); + + b.Property("MaxPlayers") + .HasColumnType("INTEGER"); + + b.Property("Name") + .HasColumnType("INTEGER"); + + b.Property("ThreadId") + .HasColumnType("INTEGER"); + + b.Property("Type") + .HasColumnType("INTEGER"); + + b.HasKey("GuildId", "ChannelId", "MessageId"); + + b.HasIndex("ThreadId"); + + b.ToTable("Activities"); + + b.HasDiscriminator("Discriminator").HasValue("Activity"); + + b.UseTphMappingStrategy(); + }); + + modelBuilder.Entity("Cocotte.Modules.Activities.Models.ActivityPlayer", b => + { + b.Property("GuildId") + .HasColumnType("INTEGER"); + + b.Property("ChannelId") + .HasColumnType("INTEGER"); + + b.Property("MessageId") + .HasColumnType("INTEGER"); + + b.Property("UserId") + .HasColumnType("INTEGER"); + + b.Property("Discriminator") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("HasCompleted") + .HasColumnType("INTEGER"); + + b.Property("IsOrganizer") + .HasColumnType("INTEGER"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("GuildId", "ChannelId", "MessageId", "UserId"); + + b.ToTable("ActivityPlayers"); + + b.HasDiscriminator("Discriminator").HasValue("ActivityPlayer"); + + b.UseTphMappingStrategy(); + }); + + modelBuilder.Entity("Cocotte.Modules.Activities.Models.InterstellarActivity", b => + { + b.HasBaseType("Cocotte.Modules.Activities.Models.Activity"); + + b.Property("Color") + .HasColumnType("INTEGER"); + + b.HasDiscriminator().HasValue("InterstellarActivity"); + }); + + modelBuilder.Entity("Cocotte.Modules.Activities.Models.OrganizedActivity", b => + { + b.HasBaseType("Cocotte.Modules.Activities.Models.Activity"); + + b.HasDiscriminator().HasValue("OrganizedActivity"); + }); + + modelBuilder.Entity("Cocotte.Modules.Activities.Models.StagedActivity", b => + { + b.HasBaseType("Cocotte.Modules.Activities.Models.Activity"); + + b.Property("Stage") + .HasColumnType("INTEGER"); + + b.HasDiscriminator().HasValue("StagedActivity"); + }); + + modelBuilder.Entity("Cocotte.Modules.Activities.Models.ActivityRolePlayer", b => + { + b.HasBaseType("Cocotte.Modules.Activities.Models.ActivityPlayer"); + + b.Property("Roles") + .HasColumnType("INTEGER"); + + b.HasDiscriminator().HasValue("ActivityRolePlayer"); + }); + + modelBuilder.Entity("AppAny.Quartz.EntityFrameworkCore.Migrations.QuartzBlobTrigger", b => + { + b.HasOne("AppAny.Quartz.EntityFrameworkCore.Migrations.QuartzTrigger", "Trigger") + .WithMany("BlobTriggers") + .HasForeignKey("SchedulerName", "TriggerName", "TriggerGroup") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Trigger"); + }); + + modelBuilder.Entity("AppAny.Quartz.EntityFrameworkCore.Migrations.QuartzCronTrigger", b => + { + b.HasOne("AppAny.Quartz.EntityFrameworkCore.Migrations.QuartzTrigger", "Trigger") + .WithMany("CronTriggers") + .HasForeignKey("SchedulerName", "TriggerName", "TriggerGroup") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Trigger"); + }); + + modelBuilder.Entity("AppAny.Quartz.EntityFrameworkCore.Migrations.QuartzSimplePropertyTrigger", b => + { + b.HasOne("AppAny.Quartz.EntityFrameworkCore.Migrations.QuartzTrigger", "Trigger") + .WithMany("SimplePropertyTriggers") + .HasForeignKey("SchedulerName", "TriggerName", "TriggerGroup") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Trigger"); + }); + + modelBuilder.Entity("AppAny.Quartz.EntityFrameworkCore.Migrations.QuartzSimpleTrigger", b => + { + b.HasOne("AppAny.Quartz.EntityFrameworkCore.Migrations.QuartzTrigger", "Trigger") + .WithMany("SimpleTriggers") + .HasForeignKey("SchedulerName", "TriggerName", "TriggerGroup") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Trigger"); + }); + + modelBuilder.Entity("AppAny.Quartz.EntityFrameworkCore.Migrations.QuartzTrigger", b => + { + b.HasOne("AppAny.Quartz.EntityFrameworkCore.Migrations.QuartzJobDetail", "JobDetail") + .WithMany("Triggers") + .HasForeignKey("SchedulerName", "JobName", "JobGroup") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("JobDetail"); + }); + + modelBuilder.Entity("Cocotte.Modules.Activities.Models.ActivityPlayer", b => + { + b.HasOne("Cocotte.Modules.Activities.Models.Activity", "Activity") + .WithMany("ActivityPlayers") + .HasForeignKey("GuildId", "ChannelId", "MessageId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Activity"); + }); + + modelBuilder.Entity("AppAny.Quartz.EntityFrameworkCore.Migrations.QuartzJobDetail", b => + { + b.Navigation("Triggers"); + }); + + modelBuilder.Entity("AppAny.Quartz.EntityFrameworkCore.Migrations.QuartzTrigger", b => + { + b.Navigation("BlobTriggers"); + + b.Navigation("CronTriggers"); + + b.Navigation("SimplePropertyTriggers"); + + b.Navigation("SimpleTriggers"); + }); + + modelBuilder.Entity("Cocotte.Modules.Activities.Models.Activity", b => + { + b.Navigation("ActivityPlayers"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Cocotte/Migrations/20230410102447_AddActivityPlayerHasCompleted.cs b/Cocotte/Migrations/20230410102447_AddActivityPlayerHasCompleted.cs new file mode 100644 index 0000000..b071548 --- /dev/null +++ b/Cocotte/Migrations/20230410102447_AddActivityPlayerHasCompleted.cs @@ -0,0 +1,29 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Cocotte.Migrations +{ + /// + public partial class AddActivityPlayerHasCompleted : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "HasCompleted", + table: "ActivityPlayers", + type: "INTEGER", + nullable: false, + defaultValue: false); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "HasCompleted", + table: "ActivityPlayers"); + } + } +} diff --git a/Cocotte/Migrations/CocotteDbContextModelSnapshot.cs b/Cocotte/Migrations/CocotteDbContextModelSnapshot.cs index 5c04b66..a6899e3 100644 --- a/Cocotte/Migrations/CocotteDbContextModelSnapshot.cs +++ b/Cocotte/Migrations/CocotteDbContextModelSnapshot.cs @@ -538,6 +538,9 @@ namespace Cocotte.Migrations .IsRequired() .HasColumnType("TEXT"); + b.Property("HasCompleted") + .HasColumnType("INTEGER"); + b.Property("IsOrganizer") .HasColumnType("INTEGER"); diff --git a/Cocotte/Modules/Activities/ActivityFormatter.cs b/Cocotte/Modules/Activities/ActivityFormatter.cs index 172427a..802ae48 100644 --- a/Cocotte/Modules/Activities/ActivityFormatter.cs +++ b/Cocotte/Modules/Activities/ActivityFormatter.cs @@ -46,7 +46,7 @@ public class ActivityFormatter public EmbedBuilder ActivityEmbed(Activity activity, IReadOnlyCollection players) { // Load activity players and organizers - var participants = activity.Participants.ToArray(); + var participants = activity.Participants.OrderBy(p => p.HasCompleted).ToArray(); var organizers = activity.Organizers.ToArray(); // Activity full @@ -164,7 +164,12 @@ public class ActivityFormatter _ => "NA" }; - public string FormatActivityPlayer(ActivityPlayer player, int namePadding, bool isEvent = false) => player switch + public string FormatActivityPlayer(ActivityPlayer player, int namePadding, bool isEvent = false) => + player.HasCompleted + ? $"~~{FormatActivityPlayerSub(player, namePadding, isEvent)}~~" + : FormatActivityPlayerSub(player, namePadding, isEvent); + + private string FormatActivityPlayerSub(ActivityPlayer player, int namePadding, bool isEvent = false) => player switch { ActivityRolePlayer rolePlayer => $"` {player.Name.PadRight(namePadding)} ` **|** {RolesToEmotes(rolePlayer.Roles)}", _ when isEvent && player.IsOrganizer => $"` {player.Name.PadRight(namePadding)} ` **|** {_options.OrganizerEmote} ", diff --git a/Cocotte/Modules/Activities/ActivityModuleThread.cs b/Cocotte/Modules/Activities/ActivityModuleThread.cs index 7c2d7ab..e9e42dd 100644 --- a/Cocotte/Modules/Activities/ActivityModuleThread.cs +++ b/Cocotte/Modules/Activities/ActivityModuleThread.cs @@ -27,6 +27,7 @@ public partial class ActivityModule - `/activite description` - **Modifie la description** de l'activité - `/activite etage` - Pour l'abîme du néant et l'origine de la guerre, **modifie l'étage** de l'activité + - `/activite completer` - Marquer un joueur comme ayant complété l'activité, le barrant dans la liste des inscrits """; private async Task CreateThread(ActivityName activityName, string creatorName) @@ -239,6 +240,67 @@ public partial class ActivityModule ); } + [SlashCommand("completer", "Marquer un jour comme ayant complété une activité, le barrant dans la liste des inscrits")] + public async Task ThreadPlayerComplete([Summary("joueur", "Le joueur qui a complété l'activité")] IUser user) + { + // Get activity linked to this thread + var activity = _activitiesRepository.FindActivityByThreadId(Context.Channel.Id); + + if (!await CheckCommandInThread(activity, checkCreator: false) || activity is null) + { + return; + } + + // Check if activity is organized activity + if (activity is not OrganizedActivity) + { + await RespondAsync( + ephemeral: true, + embed: EmbedUtils.ErrorEmbed("Cette commande n'est pas supporté dans ce type d'activité").Build() + ); + + return; + } + + // Check if player is in activity + var players = await _activitiesRepository.LoadActivityPlayers(activity); + var player = players.FirstOrDefault(p => p.UserId == user.Id); + + if (player is null) + { + await RespondAsync( + ephemeral: true, + embed: EmbedUtils.ErrorEmbed("Ce joueur n'est pas dans cette activité").Build() + ); + + return; + } + + + // Check if user who used the command is an organizer + var organizer = players.FirstOrDefault(p => p.UserId == User.Id); + + if (organizer is not { IsOrganizer: true }) + { + await RespondAsync( + ephemeral: true, + embed: EmbedUtils.ErrorEmbed("Seul un organisateur de l'activité peut effectuer cette action").Build() + ); + + return; + } + + player.HasCompleted = !player.HasCompleted; + await _activitiesRepository.SaveChanges(); + + await UpdateActivityEmbed(activity, ActivityUpdateReason.Update); + + await RespondAsync( + ephemeral: true, + embed: EmbedUtils.InfoEmbed($"L'inscription du joueur {((IGuildUser)user).DisplayName} a bien été mis à jour").Build() + ); + } + [ModalInteraction("activity description_modal", ignoreGroupNames: true)] public async Task ActivityDescriptionSubmit(ActivityDescriptionModal descriptionModal) { diff --git a/Cocotte/Modules/Activities/Models/ActivityPlayer.cs b/Cocotte/Modules/Activities/Models/ActivityPlayer.cs index 2a1baae..b382590 100644 --- a/Cocotte/Modules/Activities/Models/ActivityPlayer.cs +++ b/Cocotte/Modules/Activities/Models/ActivityPlayer.cs @@ -11,6 +11,7 @@ public class ActivityPlayer public required string Name { get; init; } public bool IsOrganizer { get; init; } + public bool HasCompleted { get; set; } public ulong GuildId { get; set; } public ulong ChannelId { get; set; }