[Activity] Add persistence
This commit is contained in:
@@ -9,6 +9,18 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Discord.Net" Version="3.9.0" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="7.0.4">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="7.0.4" />
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting" Version="7.0.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Remove="cocotte.db" />
|
||||
<Content Include="cocotte.db">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
||||
122
Cocotte/Migrations/20230320145030_InitialCreate.Designer.cs
generated
Normal file
122
Cocotte/Migrations/20230320145030_InitialCreate.Designer.cs
generated
Normal file
@@ -0,0 +1,122 @@
|
||||
// <auto-generated />
|
||||
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(CocotteContext))]
|
||||
[Migration("20230320145030_InitialCreate")]
|
||||
partial class InitialCreate
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder.HasAnnotation("ProductVersion", "7.0.4");
|
||||
|
||||
modelBuilder.Entity("Cocotte.Modules.Activity.Models.Activity", b =>
|
||||
{
|
||||
b.Property<ulong>("ActivityId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("ActivityName")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("ActivityType")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<ulong>("CreatorId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Discriminator")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<uint>("MaxPlayers")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("ActivityId");
|
||||
|
||||
b.ToTable("Activities");
|
||||
|
||||
b.HasDiscriminator<string>("Discriminator").HasValue("Activity");
|
||||
|
||||
b.UseTphMappingStrategy();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Cocotte.Modules.Activity.Models.ActivityPlayer", b =>
|
||||
{
|
||||
b.Property<ulong>("UserId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<ulong>("ActivityId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Discriminator")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("PlayerName")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("UserId");
|
||||
|
||||
b.HasIndex("ActivityId");
|
||||
|
||||
b.ToTable("ActivityPlayers");
|
||||
|
||||
b.HasDiscriminator<string>("Discriminator").HasValue("ActivityPlayer");
|
||||
|
||||
b.UseTphMappingStrategy();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Cocotte.Modules.Activity.Models.StagedActivity", b =>
|
||||
{
|
||||
b.HasBaseType("Cocotte.Modules.Activity.Models.Activity");
|
||||
|
||||
b.Property<uint>("Stage")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasDiscriminator().HasValue("StagedActivity");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Cocotte.Modules.Activity.Models.ActivityRolePlayer", b =>
|
||||
{
|
||||
b.HasBaseType("Cocotte.Modules.Activity.Models.ActivityPlayer");
|
||||
|
||||
b.Property<byte>("Roles")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasDiscriminator().HasValue("ActivityRolePlayer");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Cocotte.Modules.Activity.Models.ActivityPlayer", b =>
|
||||
{
|
||||
b.HasOne("Cocotte.Modules.Activity.Models.Activity", "Activity")
|
||||
.WithMany("ActivityPlayers")
|
||||
.HasForeignKey("ActivityId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Activity");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Cocotte.Modules.Activity.Models.Activity", b =>
|
||||
{
|
||||
b.Navigation("ActivityPlayers");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
||||
70
Cocotte/Migrations/20230320145030_InitialCreate.cs
Normal file
70
Cocotte/Migrations/20230320145030_InitialCreate.cs
Normal file
@@ -0,0 +1,70 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Cocotte.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class InitialCreate : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Activities",
|
||||
columns: table => new
|
||||
{
|
||||
ActivityId = table.Column<ulong>(type: "INTEGER", nullable: false)
|
||||
.Annotation("Sqlite:Autoincrement", true),
|
||||
CreatorId = table.Column<ulong>(type: "INTEGER", nullable: false),
|
||||
Description = table.Column<string>(type: "TEXT", nullable: true),
|
||||
ActivityType = table.Column<int>(type: "INTEGER", nullable: false),
|
||||
ActivityName = table.Column<int>(type: "INTEGER", nullable: false),
|
||||
MaxPlayers = table.Column<uint>(type: "INTEGER", nullable: false),
|
||||
Discriminator = table.Column<string>(type: "TEXT", nullable: false),
|
||||
Stage = table.Column<uint>(type: "INTEGER", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Activities", x => x.ActivityId);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "ActivityPlayers",
|
||||
columns: table => new
|
||||
{
|
||||
UserId = table.Column<ulong>(type: "INTEGER", nullable: false)
|
||||
.Annotation("Sqlite:Autoincrement", true),
|
||||
PlayerName = table.Column<string>(type: "TEXT", nullable: false),
|
||||
ActivityId = table.Column<ulong>(type: "INTEGER", nullable: false),
|
||||
Discriminator = table.Column<string>(type: "TEXT", nullable: false),
|
||||
Roles = table.Column<byte>(type: "INTEGER", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_ActivityPlayers", x => x.UserId);
|
||||
table.ForeignKey(
|
||||
name: "FK_ActivityPlayers_Activities_ActivityId",
|
||||
column: x => x.ActivityId,
|
||||
principalTable: "Activities",
|
||||
principalColumn: "ActivityId",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ActivityPlayers_ActivityId",
|
||||
table: "ActivityPlayers",
|
||||
column: "ActivityId");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(
|
||||
name: "ActivityPlayers");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "Activities");
|
||||
}
|
||||
}
|
||||
}
|
||||
119
Cocotte/Migrations/CocotteContextModelSnapshot.cs
Normal file
119
Cocotte/Migrations/CocotteContextModelSnapshot.cs
Normal file
@@ -0,0 +1,119 @@
|
||||
// <auto-generated />
|
||||
using Cocotte.Services;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Cocotte.Migrations
|
||||
{
|
||||
[DbContext(typeof(CocotteContext))]
|
||||
partial class CocotteContextModelSnapshot : ModelSnapshot
|
||||
{
|
||||
protected override void BuildModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder.HasAnnotation("ProductVersion", "7.0.4");
|
||||
|
||||
modelBuilder.Entity("Cocotte.Modules.Activity.Models.Activity", b =>
|
||||
{
|
||||
b.Property<ulong>("ActivityId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("ActivityName")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("ActivityType")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<ulong>("CreatorId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Discriminator")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<uint>("MaxPlayers")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("ActivityId");
|
||||
|
||||
b.ToTable("Activities");
|
||||
|
||||
b.HasDiscriminator<string>("Discriminator").HasValue("Activity");
|
||||
|
||||
b.UseTphMappingStrategy();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Cocotte.Modules.Activity.Models.ActivityPlayer", b =>
|
||||
{
|
||||
b.Property<ulong>("UserId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<ulong>("ActivityId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Discriminator")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("PlayerName")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("UserId");
|
||||
|
||||
b.HasIndex("ActivityId");
|
||||
|
||||
b.ToTable("ActivityPlayers");
|
||||
|
||||
b.HasDiscriminator<string>("Discriminator").HasValue("ActivityPlayer");
|
||||
|
||||
b.UseTphMappingStrategy();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Cocotte.Modules.Activity.Models.StagedActivity", b =>
|
||||
{
|
||||
b.HasBaseType("Cocotte.Modules.Activity.Models.Activity");
|
||||
|
||||
b.Property<uint>("Stage")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasDiscriminator().HasValue("StagedActivity");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Cocotte.Modules.Activity.Models.ActivityRolePlayer", b =>
|
||||
{
|
||||
b.HasBaseType("Cocotte.Modules.Activity.Models.ActivityPlayer");
|
||||
|
||||
b.Property<byte>("Roles")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasDiscriminator().HasValue("ActivityRolePlayer");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Cocotte.Modules.Activity.Models.ActivityPlayer", b =>
|
||||
{
|
||||
b.HasOne("Cocotte.Modules.Activity.Models.Activity", "Activity")
|
||||
.WithMany("ActivityPlayers")
|
||||
.HasForeignKey("ActivityId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Activity");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Cocotte.Modules.Activity.Models.Activity", b =>
|
||||
{
|
||||
b.Navigation("ActivityPlayers");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
namespace Cocotte.Modules.Activity;
|
||||
|
||||
public abstract record Activity(ulong Owner, string Description, ActivityType ActivityType, ActivityName ActivityName, uint MaxPlayers);
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Cocotte.Modules.Activity.Models;
|
||||
using Cocotte.Options;
|
||||
using Cocotte.Utils;
|
||||
using Discord;
|
||||
@@ -18,11 +19,13 @@ public class ActivityModule : InteractionModuleBase<SocketInteractionContext>
|
||||
private readonly ILogger<ActivityModule> _logger;
|
||||
private readonly ActivityOptions _options;
|
||||
private readonly ActivityHelper _activityHelper;
|
||||
private readonly ActivitiesRepository _activitiesRepository;
|
||||
|
||||
public ActivityModule(ILogger<ActivityModule> logger, IOptions<ActivityOptions> options, ActivityHelper activityHelper)
|
||||
public ActivityModule(ILogger<ActivityModule> logger, IOptions<ActivityOptions> options, ActivityHelper activityHelper, ActivitiesRepository activitiesRepository)
|
||||
{
|
||||
_logger = logger;
|
||||
_activityHelper = activityHelper;
|
||||
_activitiesRepository = activitiesRepository;
|
||||
_options = options.Value;
|
||||
}
|
||||
|
||||
@@ -39,19 +42,28 @@ public class ActivityModule : InteractionModuleBase<SocketInteractionContext>
|
||||
}
|
||||
|
||||
[SlashCommand("abyss", "Créer un groupe pour l'Abîme du Néant")]
|
||||
public async Task GroupAbyss([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")] uint stage, [Summary("description", "Message accompagnant la demande de groupe")] string description = "")
|
||||
{
|
||||
const ActivityName activityName = ActivityName.Abyss;
|
||||
var activityType = ActivityHelper.ActivityNameToType(activityName);
|
||||
var maxPlayers = ActivityHelper.ActivityTypeToMaxPlayers(activityType);
|
||||
var activityId = Context.Interaction.Id;
|
||||
|
||||
var activity = new StagedActivity(Context.User.Id, description, activityType, activityName, maxPlayers, stage);
|
||||
var activity = new StagedActivity
|
||||
{
|
||||
ActivityId = 0,
|
||||
CreatorId = Context.User.Id,
|
||||
Description = description,
|
||||
ActivityType = activityType,
|
||||
ActivityName = activityName,
|
||||
MaxPlayers = maxPlayers,
|
||||
Stage = stage,
|
||||
ActivityPlayers = new()
|
||||
};
|
||||
|
||||
await CreateActivity(activity);
|
||||
await CreateRoleActivity(activity);
|
||||
}
|
||||
|
||||
private async Task CreateActivity(Activity activity)
|
||||
private async Task CreateRoleActivity(Models.Activity activity)
|
||||
{
|
||||
_logger.LogTrace("Creating activity {Activity}", activity);
|
||||
|
||||
@@ -59,10 +71,13 @@ public class ActivityModule : InteractionModuleBase<SocketInteractionContext>
|
||||
await RespondAsync("`Création de l'activité en cours...`");
|
||||
|
||||
var response = await GetOriginalResponseAsync();
|
||||
var activityId = response.Id;
|
||||
activity.ActivityId = response.Id;
|
||||
|
||||
// Add activity to db
|
||||
await _activitiesRepository.AddActivity(activity);
|
||||
|
||||
// Add components
|
||||
var components = ActivityComponent(activityId);
|
||||
var components = ActivityRoleComponent(activity.ActivityId);
|
||||
|
||||
await ModifyOriginalResponseAsync(m =>
|
||||
{
|
||||
@@ -72,15 +87,41 @@ public class ActivityModule : InteractionModuleBase<SocketInteractionContext>
|
||||
});
|
||||
}
|
||||
|
||||
[ComponentInteraction("activity join:*", ignoreGroupNames: true)]
|
||||
private async Task JoinActivity(ulong activityId)
|
||||
[ComponentInteraction("activity join_role:*", ignoreGroupNames: true)]
|
||||
private async Task JoinActivityRole(ulong activityId)
|
||||
{
|
||||
var user = (SocketGuildUser)Context.User;
|
||||
|
||||
// Check if activity exists
|
||||
if (await _activitiesRepository.FindActivity(activityId) is not { } activity)
|
||||
{
|
||||
await RespondAsync(
|
||||
ephemeral: true,
|
||||
embed: EmbedUtils.ErrorEmbed("Cette activité n'existe plus").Build()
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// If player is already registered
|
||||
if (await _activitiesRepository.FindActivityRolePlayer(activityId, user.Id) is not null)
|
||||
{
|
||||
await RespondAsync(
|
||||
ephemeral: true,
|
||||
embed: EmbedUtils.ErrorEmbed("Vous êtes déjà inscrit à cette activité").Build()
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
_logger.LogTrace("Player {Player} joined activity {Id}", user.DisplayName, activityId);
|
||||
|
||||
var roles = _activityHelper.GetPlayerRoles(user.Roles);
|
||||
var activityPlayer = new ActivityRolePlayer(user.Id, user.DisplayName, roles);
|
||||
var activityRolePlayer = new ActivityRolePlayer { UserId = user.Id, PlayerName = user.DisplayName, Roles = roles, ActivityId = activityId, Activity = activity };
|
||||
|
||||
// Add player to activity
|
||||
activity.ActivityPlayers.Add(activityRolePlayer);
|
||||
await _activitiesRepository.SaveChanges();
|
||||
|
||||
await RespondAsync(
|
||||
ephemeral: true,
|
||||
@@ -88,14 +129,37 @@ public class ActivityModule : InteractionModuleBase<SocketInteractionContext>
|
||||
);
|
||||
}
|
||||
|
||||
[ComponentInteraction("activity leave:*", ignoreGroupNames: true)]
|
||||
private async Task LeaveActivity(ulong activityId)
|
||||
[ComponentInteraction("activity leave_role:*", ignoreGroupNames: true)]
|
||||
private async Task LeaveActivityRole(ulong activityId)
|
||||
{
|
||||
var user = (SocketGuildUser)Context.User;
|
||||
var user = (IGuildUser)Context.User;
|
||||
|
||||
// Check if activity exists
|
||||
if (await _activitiesRepository.FindActivity(activityId) is not { } activity)
|
||||
{
|
||||
await RespondAsync(
|
||||
ephemeral: true,
|
||||
embed: EmbedUtils.ErrorEmbed("Cette activité n'existe plus").Build()
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if player is in activity
|
||||
if (await _activitiesRepository.FindActivityPlayer(activityId, user.Id) is not { } activityPlayer)
|
||||
{
|
||||
await RespondAsync(
|
||||
ephemeral: true,
|
||||
embed: EmbedUtils.ErrorEmbed("Vous n'êtes pas inscrit à cette activité").Build()
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
_logger.LogTrace("Player {Player} left activity {Id}", user.DisplayName, activityId);
|
||||
|
||||
// TODO: remove the user from the activity
|
||||
activity.ActivityPlayers.Remove(activityPlayer);
|
||||
await _activitiesRepository.SaveChanges();
|
||||
|
||||
await RespondAsync(
|
||||
ephemeral: true,
|
||||
@@ -106,23 +170,23 @@ public class ActivityModule : InteractionModuleBase<SocketInteractionContext>
|
||||
[ComponentInteraction("activity event_join:*", ignoreGroupNames: true)]
|
||||
private async Task JoinEventActivity(ulong activityId)
|
||||
{
|
||||
_logger.LogTrace("Player {Player} joined activity {Id}", ((SocketGuildUser)Context.User).DisplayName, activityId);
|
||||
_logger.LogTrace("Player {Player} joined activity {Id}", ((IGuildUser)Context.User).DisplayName, activityId);
|
||||
|
||||
await RespondAsync(activityId.ToString());
|
||||
}
|
||||
|
||||
private static ComponentBuilder ActivityComponent(ulong activityId)
|
||||
private static ComponentBuilder ActivityRoleComponent(ulong activityId)
|
||||
{
|
||||
return new ComponentBuilder()
|
||||
.AddRow(new ActionRowBuilder()
|
||||
.WithButton(new ButtonBuilder()
|
||||
.WithLabel("Rejoindre l'activité")
|
||||
.WithCustomId($"activity join:{activityId}")
|
||||
.WithCustomId($"activity join_role:{activityId}")
|
||||
.WithStyle(ButtonStyle.Primary)
|
||||
)
|
||||
.WithButton(new ButtonBuilder()
|
||||
.WithLabel("Se désinscrire de l'activité")
|
||||
.WithCustomId($"activity leave:{activityId}")
|
||||
.WithCustomId($"activity leave_role:{activityId}")
|
||||
.WithStyle(ButtonStyle.Danger)
|
||||
)
|
||||
);
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
namespace Cocotte.Modules.Activity;
|
||||
|
||||
public record ActivityPlayer(ulong UserId, string PlayerName);
|
||||
@@ -1,3 +0,0 @@
|
||||
namespace Cocotte.Modules.Activity;
|
||||
|
||||
public record ActivityRolePlayer(ulong UserId, string PlayerName, ActivityRoles Roles) : ActivityPlayer(UserId, PlayerName);
|
||||
45
Cocotte/Modules/Activity/Models/ActivitiesRepository.cs
Normal file
45
Cocotte/Modules/Activity/Models/ActivitiesRepository.cs
Normal file
@@ -0,0 +1,45 @@
|
||||
using Cocotte.Services;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace Cocotte.Modules.Activity.Models;
|
||||
|
||||
public class ActivitiesRepository
|
||||
{
|
||||
private readonly CocotteContext _cocotteContext;
|
||||
|
||||
public ActivitiesRepository(CocotteContext cocotteContext)
|
||||
{
|
||||
_cocotteContext = cocotteContext;
|
||||
}
|
||||
|
||||
public async Task<Activity?> FindActivity(ulong activityId)
|
||||
{
|
||||
return await _cocotteContext.Activities.FindAsync(activityId);
|
||||
}
|
||||
|
||||
public async Task<StagedActivity?> FindStagedActivity(ulong activityId)
|
||||
{
|
||||
return await _cocotteContext.StagedActivities.FindAsync(activityId);
|
||||
}
|
||||
|
||||
public async Task<ActivityPlayer?> FindActivityPlayer(ulong activityId, ulong playerId)
|
||||
{
|
||||
return await _cocotteContext.ActivityPlayers.FindAsync(activityId, playerId);
|
||||
}
|
||||
|
||||
public async Task<ActivityRolePlayer?> FindActivityRolePlayer(ulong activityId, ulong playerId)
|
||||
{
|
||||
return await _cocotteContext.ActivityRolePlayers.FindAsync(activityId, playerId);
|
||||
}
|
||||
|
||||
public async Task AddActivity(Activity activity)
|
||||
{
|
||||
await _cocotteContext.AddAsync(activity);
|
||||
await _cocotteContext.SaveChangesAsync();
|
||||
}
|
||||
|
||||
public async Task SaveChanges()
|
||||
{
|
||||
await _cocotteContext.SaveChangesAsync();
|
||||
}
|
||||
}
|
||||
23
Cocotte/Modules/Activity/Models/Activity.cs
Normal file
23
Cocotte/Modules/Activity/Models/Activity.cs
Normal file
@@ -0,0 +1,23 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace Cocotte.Modules.Activity.Models;
|
||||
|
||||
public abstract class Activity
|
||||
{
|
||||
[Key]
|
||||
public ulong ActivityId { get; set; }
|
||||
|
||||
public ulong CreatorId { get; init; }
|
||||
public string? Description { get; init; }
|
||||
public ActivityType ActivityType { get; init; }
|
||||
public ActivityName ActivityName { get; init; }
|
||||
public uint MaxPlayers { get; set; }
|
||||
|
||||
public List<ActivityPlayer> ActivityPlayers { get; init; } = new();
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{nameof(ActivityId)}: {ActivityId}, {nameof(CreatorId)}: {CreatorId}, {nameof(Description)}: {Description}, {nameof(ActivityType)}: {ActivityType}, {nameof(ActivityName)}: {ActivityName}, {nameof(MaxPlayers)}: {MaxPlayers}";
|
||||
}
|
||||
}
|
||||
20
Cocotte/Modules/Activity/Models/ActivityPlayer.cs
Normal file
20
Cocotte/Modules/Activity/Models/ActivityPlayer.cs
Normal file
@@ -0,0 +1,20 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace Cocotte.Modules.Activity.Models;
|
||||
|
||||
[PrimaryKey(nameof(ActivityId), nameof(UserId))]
|
||||
public class ActivityPlayer
|
||||
{
|
||||
public ulong UserId { get; init; }
|
||||
|
||||
public required string PlayerName { get; init; }
|
||||
|
||||
public ulong ActivityId { get; init; }
|
||||
public required Activity Activity { get; init; }
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{nameof(UserId)}: {UserId}, {nameof(PlayerName)}: {PlayerName}";
|
||||
}
|
||||
}
|
||||
6
Cocotte/Modules/Activity/Models/ActivityRolePlayer.cs
Normal file
6
Cocotte/Modules/Activity/Models/ActivityRolePlayer.cs
Normal file
@@ -0,0 +1,6 @@
|
||||
namespace Cocotte.Modules.Activity.Models;
|
||||
|
||||
public class ActivityRolePlayer : ActivityPlayer
|
||||
{
|
||||
public required ActivityRoles Roles { get; init; }
|
||||
}
|
||||
11
Cocotte/Modules/Activity/Models/StagedActivity.cs
Normal file
11
Cocotte/Modules/Activity/Models/StagedActivity.cs
Normal file
@@ -0,0 +1,11 @@
|
||||
namespace Cocotte.Modules.Activity.Models;
|
||||
|
||||
public class StagedActivity : Activity
|
||||
{
|
||||
public uint Stage { get; set; }
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{base.ToString()}, {nameof(Stage)}: {Stage}";
|
||||
}
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
namespace Cocotte.Modules.Activity;
|
||||
|
||||
public record StagedActivity(ulong Owner, string Description, ActivityType ActivityType, ActivityName ActivityName, uint MaxPlayers, uint Stage)
|
||||
: Activity(Owner, Description, ActivityType, ActivityName, MaxPlayers);
|
||||
@@ -1,4 +1,5 @@
|
||||
using Cocotte.Modules.Activity;
|
||||
using Cocotte.Modules.Activity.Models;
|
||||
using Cocotte.Modules.Raids;
|
||||
using Cocotte.Options;
|
||||
using Cocotte.Services;
|
||||
@@ -6,6 +7,7 @@ using Discord;
|
||||
using Discord.Commands;
|
||||
using Discord.Interactions;
|
||||
using Discord.WebSocket;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
DiscordSocketConfig discordSocketConfig = new()
|
||||
{
|
||||
@@ -26,6 +28,11 @@ IHost host = Host.CreateDefaultBuilder(args)
|
||||
services.Configure<DiscordOptions>(context.Configuration.GetSection(DiscordOptions.SectionName));
|
||||
services.Configure<ActivityOptions>(context.Configuration.GetSection(ActivityOptions.SectionName));
|
||||
|
||||
// Database
|
||||
services.AddDbContext<CocotteContext>(options =>
|
||||
options.UseSqlite(context.Configuration.GetConnectionString("CocotteContext")), ServiceLifetime.Transient, ServiceLifetime.Transient);
|
||||
services.AddTransient<ActivitiesRepository>();
|
||||
|
||||
// Discord.Net
|
||||
services.AddHostedService<DiscordLoggingService>();
|
||||
|
||||
|
||||
18
Cocotte/Services/CocotteContext.cs
Normal file
18
Cocotte/Services/CocotteContext.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
using Cocotte.Modules.Activity.Models;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace Cocotte.Services;
|
||||
|
||||
public class CocotteContext : DbContext
|
||||
{
|
||||
public DbSet<Activity> Activities => Set<Activity>();
|
||||
public DbSet<StagedActivity> StagedActivities => Set<StagedActivity>();
|
||||
|
||||
public DbSet<ActivityPlayer> ActivityPlayers => Set<ActivityPlayer>();
|
||||
public DbSet<ActivityRolePlayer> ActivityRolePlayers => Set<ActivityRolePlayer>();
|
||||
|
||||
public CocotteContext(DbContextOptions<CocotteContext> options) : base(options)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -4,5 +4,8 @@
|
||||
"Default": "Information",
|
||||
"Microsoft.Hosting.Lifetime": "Information"
|
||||
}
|
||||
},
|
||||
"ConnectionStrings": {
|
||||
"CocotteContext": "Data Source=cocotte.db"
|
||||
}
|
||||
}
|
||||
|
||||
BIN
Cocotte/cocotte.db
Normal file
BIN
Cocotte/cocotte.db
Normal file
Binary file not shown.
Reference in New Issue
Block a user