1
0
mirror of synced 2025-01-24 23:13:45 +01:00

ChallengeCompete Init

This commit is contained in:
ptmaster 2024-09-11 05:30:35 +08:00
parent 00988bbc69
commit 583c95071c
20 changed files with 1668 additions and 9 deletions

View File

@ -127,8 +127,10 @@ namespace GameDatabase.Context
});
OnModelCreatingPartial(modelBuilder);
OnModelCreatingChallengeCompete(modelBuilder);
}
partial void OnModelCreatingPartial(ModelBuilder modelBuilder);
partial void OnModelCreatingChallengeCompete(ModelBuilder modelBuilder);
}
}

View File

@ -0,0 +1,78 @@
using GameDatabase.Entities;
using Microsoft.EntityFrameworkCore;
namespace GameDatabase.Context;
public partial class TaikoDbContext
{
public virtual DbSet<ChallengeCompeteDatum> ChallengeCompeteData { get; set; } = null;
public virtual DbSet<ChallengeCompeteParticipantDatum> ChallengeCompeteParticipantData { get; set; } = null;
public virtual DbSet<ChallengeCompeteSongDatum> ChallengeCompeteSongData { get; set; } = null;
public virtual DbSet<ChallengeCompeteBestDatum> ChallengeCompeteBestData { get; set; } = null;
partial void OnModelCreatingChallengeCompete(ModelBuilder modelBuilder)
{
modelBuilder.Entity<ChallengeCompeteDatum>(entity =>
{
entity.HasKey(e => new { e.CompId });
entity.Property(e => e.CompeteMode).HasConversion<uint>();
entity.Property(e => e.Share).HasConversion<uint>();
entity.Property(e => e.CompeteTarget).HasConversion<uint>();
entity.Property(e => e.CreateTime).HasColumnType("datetime");
entity.Property(e => e.ExpireTime).HasColumnType("datetime");
});
modelBuilder.Entity<ChallengeCompeteParticipantDatum>(entity =>
{
entity.HasKey(e => new { e.CompId, e.Baid });
entity.HasOne(e => e.UserData)
.WithMany()
.HasPrincipalKey(p => p.Baid)
.HasForeignKey(d => d.Baid)
.OnDelete(DeleteBehavior.Cascade);
entity.HasOne(e => e.ChallengeCompeteData)
.WithMany(p => p.Participants)
.HasPrincipalKey(p => p.CompId)
.HasForeignKey(d => d.CompId)
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity<ChallengeCompeteSongDatum>(entity =>
{
entity.HasKey(e => new { e.CompId, e.SongId });
entity.HasOne(e => e.ChallengeCompeteData)
.WithMany(p => p.Songs)
.HasPrincipalKey(p => p.CompId)
.HasForeignKey(d => d.CompId)
.OnDelete(DeleteBehavior.Cascade);
entity.Property(e => e.Difficulty).HasConversion<uint>();
});
modelBuilder.Entity<ChallengeCompeteBestDatum>(entity =>
{
entity.HasKey(e => new { e.CompId, e.Baid, e.SongId });
entity.HasOne(e => e.UserData)
.WithMany()
.HasPrincipalKey(p => p.Baid)
.HasForeignKey(d => d.Baid)
.OnDelete(DeleteBehavior.Cascade);
entity.HasOne(e => e.ChallengeCompeteSongData)
.WithMany(p => p.BestScores)
.HasPrincipalKey(p => new { p.CompId, p.SongId })
.HasForeignKey(d => new { d.CompId, d.SongId })
.OnDelete(DeleteBehavior.Cascade);
entity.Property(e => e.Difficulty).HasConversion<uint>();
entity.Property(e => e.Crown).HasConversion<uint>();
entity.Property(e => e.ScoreRank).HasConversion<uint>();
});
}
}

View File

@ -0,0 +1,24 @@
using SharedProject.Enums;
namespace GameDatabase.Entities;
public partial class ChallengeCompeteBestDatum
{
public uint CompId { get; set; }
public uint Baid { get; set; }
public uint SongId { get; set; }
public Difficulty Difficulty { get; set; }
public CrownType Crown { get; set; }
public uint Score { get; set; }
public uint ScoreRate { get; set; }
public ScoreRank ScoreRank { get; set; }
public uint GoodCount { get; set; }
public uint OkCount { get; set; }
public uint MissCount { get; set; }
public uint ComboCount { get; set; }
public uint HitCount { get; set; }
public uint DrumrollCount { get; set; }
public bool Skipped { get; set; }
public virtual ChallengeCompeteSongDatum? ChallengeCompeteSongData { get; set; }
public virtual UserDatum? UserData { get; set; }
}

View File

@ -0,0 +1,21 @@
using SharedProject.Enums;
namespace GameDatabase.Entities;
public partial class ChallengeCompeteDatum
{
public uint CompId { get; set; }
public CompeteModeType CompeteMode { get; set; } = CompeteModeType.None;
public uint Baid { get; set; }
public string CompeteName { get; set; } = String.Empty;
public string CompeteDescribe { get; set; } = String.Empty;
public uint MaxParticipant { get; set; } = 2;
public DateTime CreateTime { get; set; }
public DateTime ExpireTime { get; set; }
public uint RequireTitle { get; set; } = 0;
public ShareType Share { get; set; } = ShareType.EveryOne;
public CompeteTargetType CompeteTarget { get; set; } = CompeteTargetType.EveryOne;
public List<ChallengeCompeteSongDatum> Songs { get; set; } = new();
public List<ChallengeCompeteParticipantDatum> Participants { get; set; } = new();
}

View File

@ -0,0 +1,10 @@
namespace GameDatabase.Entities;
public partial class ChallengeCompeteParticipantDatum
{
public uint CompId { get; set; }
public uint Baid { get; set; }
public bool IsActive { get; set; }
public virtual ChallengeCompeteDatum? ChallengeCompeteData { get; set; }
public virtual UserDatum? UserData { get; set; }
}

View File

@ -0,0 +1,13 @@
using SharedProject.Enums;
namespace GameDatabase.Entities;
public partial class ChallengeCompeteSongDatum
{
public uint CompId { get; set; }
public uint SongId { get; set; }
public Difficulty Difficulty { get; set; }
public short SongOpt { get; set; }
public List<ChallengeCompeteBestDatum> BestScores { get; set; } = new();
public virtual ChallengeCompeteDatum? ChallengeCompeteData { get; set; }
}

View File

@ -0,0 +1,769 @@
// <auto-generated />
using System;
using GameDatabase.Context;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
#nullable disable
namespace GameDatabase.Migrations
{
[DbContext(typeof(TaikoDbContext))]
[Migration("20240910100030_AddChallengeCompete")]
partial class AddChallengeCompete
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder.HasAnnotation("ProductVersion", "8.0.3");
modelBuilder.Entity("GameDatabase.Entities.AiScoreDatum", b =>
{
b.Property<uint>("Baid")
.HasColumnType("INTEGER");
b.Property<uint>("SongId")
.HasColumnType("INTEGER");
b.Property<uint>("Difficulty")
.HasColumnType("INTEGER");
b.Property<bool>("IsWin")
.HasColumnType("INTEGER");
b.HasKey("Baid", "SongId", "Difficulty");
b.ToTable("AiScoreData");
});
modelBuilder.Entity("GameDatabase.Entities.AiSectionScoreDatum", b =>
{
b.Property<uint>("Baid")
.HasColumnType("INTEGER");
b.Property<uint>("SongId")
.HasColumnType("INTEGER");
b.Property<uint>("Difficulty")
.HasColumnType("INTEGER");
b.Property<int>("SectionIndex")
.HasColumnType("INTEGER");
b.Property<int>("Crown")
.HasColumnType("INTEGER");
b.Property<uint>("DrumrollCount")
.HasColumnType("INTEGER");
b.Property<uint>("GoodCount")
.HasColumnType("INTEGER");
b.Property<bool>("IsWin")
.HasColumnType("INTEGER");
b.Property<uint>("MissCount")
.HasColumnType("INTEGER");
b.Property<uint>("OkCount")
.HasColumnType("INTEGER");
b.Property<uint>("Score")
.HasColumnType("INTEGER");
b.HasKey("Baid", "SongId", "Difficulty", "SectionIndex");
b.ToTable("AiSectionScoreData");
});
modelBuilder.Entity("GameDatabase.Entities.Card", b =>
{
b.Property<string>("AccessCode")
.HasColumnType("TEXT");
b.Property<uint>("Baid")
.HasColumnType("INTEGER");
b.HasKey("AccessCode");
b.HasIndex("Baid");
b.ToTable("Card", (string)null);
});
modelBuilder.Entity("GameDatabase.Entities.ChallengeCompeteBestDatum", b =>
{
b.Property<uint>("CompId")
.HasColumnType("INTEGER");
b.Property<uint>("Baid")
.HasColumnType("INTEGER");
b.Property<uint>("SongId")
.HasColumnType("INTEGER");
b.Property<uint>("ComboCount")
.HasColumnType("INTEGER");
b.Property<uint>("Crown")
.HasColumnType("INTEGER");
b.Property<uint>("Difficulty")
.HasColumnType("INTEGER");
b.Property<uint>("DrumrollCount")
.HasColumnType("INTEGER");
b.Property<uint>("GoodCount")
.HasColumnType("INTEGER");
b.Property<uint>("HitCount")
.HasColumnType("INTEGER");
b.Property<uint>("MissCount")
.HasColumnType("INTEGER");
b.Property<uint>("OkCount")
.HasColumnType("INTEGER");
b.Property<uint>("Score")
.HasColumnType("INTEGER");
b.Property<uint>("ScoreRank")
.HasColumnType("INTEGER");
b.Property<uint>("ScoreRate")
.HasColumnType("INTEGER");
b.Property<bool>("Skipped")
.HasColumnType("INTEGER");
b.HasKey("CompId", "Baid", "SongId");
b.HasIndex("Baid");
b.HasIndex("CompId", "SongId");
b.ToTable("ChallengeCompeteBestData");
});
modelBuilder.Entity("GameDatabase.Entities.ChallengeCompeteDatum", b =>
{
b.Property<uint>("CompId")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<uint>("Baid")
.HasColumnType("INTEGER");
b.Property<string>("CompeteDescribe")
.IsRequired()
.HasColumnType("TEXT");
b.Property<uint>("CompeteMode")
.HasColumnType("INTEGER");
b.Property<string>("CompeteName")
.IsRequired()
.HasColumnType("TEXT");
b.Property<uint>("CompeteTarget")
.HasColumnType("INTEGER");
b.Property<DateTime>("CreateTime")
.HasColumnType("datetime");
b.Property<DateTime>("ExpireTime")
.HasColumnType("datetime");
b.Property<uint>("MaxParticipant")
.HasColumnType("INTEGER");
b.Property<uint>("RequireTitle")
.HasColumnType("INTEGER");
b.Property<uint>("Share")
.HasColumnType("INTEGER");
b.HasKey("CompId");
b.ToTable("ChallengeCompeteData");
});
modelBuilder.Entity("GameDatabase.Entities.ChallengeCompeteParticipantDatum", b =>
{
b.Property<uint>("CompId")
.HasColumnType("INTEGER");
b.Property<uint>("Baid")
.HasColumnType("INTEGER");
b.Property<bool>("IsActive")
.HasColumnType("INTEGER");
b.HasKey("CompId", "Baid");
b.HasIndex("Baid");
b.ToTable("ChallengeCompeteParticipantData");
});
modelBuilder.Entity("GameDatabase.Entities.ChallengeCompeteSongDatum", b =>
{
b.Property<uint>("CompId")
.HasColumnType("INTEGER");
b.Property<uint>("SongId")
.HasColumnType("INTEGER");
b.Property<uint>("Difficulty")
.HasColumnType("INTEGER");
b.Property<short>("SongOpt")
.HasColumnType("INTEGER");
b.HasKey("CompId", "SongId");
b.ToTable("ChallengeCompeteSongData");
});
modelBuilder.Entity("GameDatabase.Entities.Credential", b =>
{
b.Property<uint>("Baid")
.HasColumnType("INTEGER");
b.Property<string>("Password")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("Salt")
.IsRequired()
.HasColumnType("TEXT");
b.HasKey("Baid");
b.ToTable("Credential", (string)null);
});
modelBuilder.Entity("GameDatabase.Entities.DanScoreDatum", b =>
{
b.Property<uint>("Baid")
.HasColumnType("INTEGER");
b.Property<uint>("DanId")
.HasColumnType("INTEGER");
b.Property<int>("DanType")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER")
.HasDefaultValue(1);
b.Property<uint>("ArrivalSongCount")
.HasColumnType("INTEGER");
b.Property<uint>("ClearState")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER")
.HasDefaultValue(0u);
b.Property<uint>("ComboCountTotal")
.HasColumnType("INTEGER");
b.Property<uint>("SoulGaugeTotal")
.HasColumnType("INTEGER");
b.HasKey("Baid", "DanId", "DanType");
b.ToTable("DanScoreData");
});
modelBuilder.Entity("GameDatabase.Entities.DanStageScoreDatum", b =>
{
b.Property<uint>("Baid")
.HasColumnType("INTEGER");
b.Property<uint>("DanId")
.HasColumnType("INTEGER");
b.Property<int>("DanType")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER")
.HasDefaultValue(1);
b.Property<uint>("SongNumber")
.HasColumnType("INTEGER");
b.Property<uint>("BadCount")
.HasColumnType("INTEGER");
b.Property<uint>("ComboCount")
.HasColumnType("INTEGER");
b.Property<uint>("DrumrollCount")
.HasColumnType("INTEGER");
b.Property<uint>("GoodCount")
.HasColumnType("INTEGER");
b.Property<uint>("HighScore")
.HasColumnType("INTEGER");
b.Property<uint>("OkCount")
.HasColumnType("INTEGER");
b.Property<uint>("PlayScore")
.HasColumnType("INTEGER");
b.Property<uint>("TotalHitCount")
.HasColumnType("INTEGER");
b.HasKey("Baid", "DanId", "DanType", "SongNumber");
b.ToTable("DanStageScoreData");
});
modelBuilder.Entity("GameDatabase.Entities.SongBestDatum", b =>
{
b.Property<uint>("Baid")
.HasColumnType("INTEGER");
b.Property<uint>("SongId")
.HasColumnType("INTEGER");
b.Property<uint>("Difficulty")
.HasColumnType("INTEGER");
b.Property<uint>("BestCrown")
.HasColumnType("INTEGER");
b.Property<uint>("BestRate")
.HasColumnType("INTEGER");
b.Property<uint>("BestScore")
.HasColumnType("INTEGER");
b.Property<uint>("BestScoreRank")
.HasColumnType("INTEGER");
b.HasKey("Baid", "SongId", "Difficulty");
b.ToTable("SongBestData");
});
modelBuilder.Entity("GameDatabase.Entities.SongPlayDatum", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<uint>("Baid")
.HasColumnType("INTEGER");
b.Property<uint>("ComboCount")
.HasColumnType("INTEGER");
b.Property<uint>("Crown")
.HasColumnType("INTEGER");
b.Property<uint>("Difficulty")
.HasColumnType("INTEGER");
b.Property<uint>("DrumrollCount")
.HasColumnType("INTEGER");
b.Property<uint>("GoodCount")
.HasColumnType("INTEGER");
b.Property<uint>("HitCount")
.HasColumnType("INTEGER");
b.Property<uint>("MissCount")
.HasColumnType("INTEGER");
b.Property<uint>("OkCount")
.HasColumnType("INTEGER");
b.Property<DateTime>("PlayTime")
.HasColumnType("datetime");
b.Property<uint>("Score")
.HasColumnType("INTEGER");
b.Property<uint>("ScoreRank")
.HasColumnType("INTEGER");
b.Property<uint>("ScoreRate")
.HasColumnType("INTEGER");
b.Property<bool>("Skipped")
.HasColumnType("INTEGER");
b.Property<uint>("SongId")
.HasColumnType("INTEGER");
b.Property<uint>("SongNumber")
.HasColumnType("INTEGER");
b.HasKey("Id");
b.HasIndex("Baid");
b.ToTable("SongPlayData");
});
modelBuilder.Entity("GameDatabase.Entities.Token", b =>
{
b.Property<uint>("Baid")
.HasColumnType("INTEGER");
b.Property<int>("Id")
.HasColumnType("INTEGER");
b.Property<int>("Count")
.HasColumnType("INTEGER");
b.HasKey("Baid", "Id");
b.ToTable("Tokens");
});
modelBuilder.Entity("GameDatabase.Entities.UserDatum", b =>
{
b.Property<uint>("Baid")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<uint>("AchievementDisplayDifficulty")
.HasColumnType("INTEGER");
b.Property<int>("AiWinCount")
.HasColumnType("INTEGER");
b.Property<uint>("ColorBody")
.HasColumnType("INTEGER");
b.Property<uint>("ColorFace")
.HasColumnType("INTEGER");
b.Property<uint>("ColorLimb")
.HasColumnType("INTEGER");
b.Property<string>("CostumeData")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("CostumeFlgArray")
.IsRequired()
.HasColumnType("TEXT");
b.Property<uint>("CurrentBody")
.HasColumnType("INTEGER");
b.Property<uint>("CurrentFace")
.HasColumnType("INTEGER");
b.Property<uint>("CurrentHead")
.HasColumnType("INTEGER");
b.Property<uint>("CurrentKigurumi")
.HasColumnType("INTEGER");
b.Property<uint>("CurrentPuchi")
.HasColumnType("INTEGER");
b.Property<string>("DifficultyPlayedArray")
.IsRequired()
.HasColumnType("TEXT");
b.Property<uint>("DifficultyPlayedCourse")
.HasColumnType("INTEGER");
b.Property<uint>("DifficultyPlayedSort")
.HasColumnType("INTEGER");
b.Property<uint>("DifficultyPlayedStar")
.HasColumnType("INTEGER");
b.Property<string>("DifficultySettingArray")
.IsRequired()
.HasColumnType("TEXT");
b.Property<uint>("DifficultySettingCourse")
.HasColumnType("INTEGER");
b.Property<uint>("DifficultySettingSort")
.HasColumnType("INTEGER");
b.Property<uint>("DifficultySettingStar")
.HasColumnType("INTEGER");
b.Property<bool>("DisplayAchievement")
.HasColumnType("INTEGER");
b.Property<bool>("DisplayDan")
.HasColumnType("INTEGER");
b.Property<string>("FavoriteSongsArray")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("GenericInfoFlgArray")
.IsRequired()
.HasColumnType("TEXT");
b.Property<bool>("IsAdmin")
.HasColumnType("INTEGER");
b.Property<bool>("IsSkipOn")
.HasColumnType("INTEGER");
b.Property<bool>("IsVoiceOn")
.HasColumnType("INTEGER");
b.Property<DateTime>("LastPlayDatetime")
.HasColumnType("datetime");
b.Property<uint>("LastPlayMode")
.HasColumnType("INTEGER");
b.Property<string>("MyDonName")
.IsRequired()
.HasColumnType("TEXT");
b.Property<uint>("MyDonNameLanguage")
.HasColumnType("INTEGER");
b.Property<int>("NotesPosition")
.HasColumnType("INTEGER");
b.Property<short>("OptionSetting")
.HasColumnType("INTEGER");
b.Property<uint>("SelectedToneId")
.HasColumnType("INTEGER");
b.Property<string>("Title")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("TitleFlgArray")
.IsRequired()
.HasColumnType("TEXT");
b.Property<uint>("TitlePlateId")
.HasColumnType("INTEGER");
b.Property<string>("ToneFlgArray")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("UnlockedBody")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("UnlockedFace")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("UnlockedHead")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("UnlockedKigurumi")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("UnlockedPuchi")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("UnlockedSongIdList")
.IsRequired()
.HasColumnType("TEXT");
b.HasKey("Baid");
b.ToTable("UserData");
});
modelBuilder.Entity("GameDatabase.Entities.AiScoreDatum", b =>
{
b.HasOne("GameDatabase.Entities.UserDatum", "Ba")
.WithMany()
.HasForeignKey("Baid")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Ba");
});
modelBuilder.Entity("GameDatabase.Entities.AiSectionScoreDatum", b =>
{
b.HasOne("GameDatabase.Entities.AiScoreDatum", "Parent")
.WithMany("AiSectionScoreData")
.HasForeignKey("Baid", "SongId", "Difficulty")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Parent");
});
modelBuilder.Entity("GameDatabase.Entities.Card", b =>
{
b.HasOne("GameDatabase.Entities.UserDatum", "Ba")
.WithMany()
.HasForeignKey("Baid")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Ba");
});
modelBuilder.Entity("GameDatabase.Entities.ChallengeCompeteBestDatum", b =>
{
b.HasOne("GameDatabase.Entities.UserDatum", "UserData")
.WithMany()
.HasForeignKey("Baid")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("GameDatabase.Entities.ChallengeCompeteSongDatum", "ChallengeCompeteSongData")
.WithMany("BestScores")
.HasForeignKey("CompId", "SongId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("ChallengeCompeteSongData");
b.Navigation("UserData");
});
modelBuilder.Entity("GameDatabase.Entities.ChallengeCompeteParticipantDatum", b =>
{
b.HasOne("GameDatabase.Entities.UserDatum", "UserData")
.WithMany()
.HasForeignKey("Baid")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("GameDatabase.Entities.ChallengeCompeteDatum", "ChallengeCompeteData")
.WithMany("Participants")
.HasForeignKey("CompId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("ChallengeCompeteData");
b.Navigation("UserData");
});
modelBuilder.Entity("GameDatabase.Entities.ChallengeCompeteSongDatum", b =>
{
b.HasOne("GameDatabase.Entities.ChallengeCompeteDatum", "ChallengeCompeteData")
.WithMany("Songs")
.HasForeignKey("CompId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("ChallengeCompeteData");
});
modelBuilder.Entity("GameDatabase.Entities.Credential", b =>
{
b.HasOne("GameDatabase.Entities.UserDatum", "Ba")
.WithMany()
.HasForeignKey("Baid")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Ba");
});
modelBuilder.Entity("GameDatabase.Entities.DanScoreDatum", b =>
{
b.HasOne("GameDatabase.Entities.UserDatum", "Ba")
.WithMany()
.HasForeignKey("Baid")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Ba");
});
modelBuilder.Entity("GameDatabase.Entities.DanStageScoreDatum", b =>
{
b.HasOne("GameDatabase.Entities.DanScoreDatum", "Parent")
.WithMany("DanStageScoreData")
.HasForeignKey("Baid", "DanId", "DanType")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Parent");
});
modelBuilder.Entity("GameDatabase.Entities.SongBestDatum", b =>
{
b.HasOne("GameDatabase.Entities.UserDatum", "Ba")
.WithMany()
.HasForeignKey("Baid")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Ba");
});
modelBuilder.Entity("GameDatabase.Entities.SongPlayDatum", b =>
{
b.HasOne("GameDatabase.Entities.UserDatum", "Ba")
.WithMany()
.HasForeignKey("Baid")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Ba");
});
modelBuilder.Entity("GameDatabase.Entities.Token", b =>
{
b.HasOne("GameDatabase.Entities.UserDatum", "Datum")
.WithMany("Tokens")
.HasForeignKey("Baid")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Datum");
});
modelBuilder.Entity("GameDatabase.Entities.AiScoreDatum", b =>
{
b.Navigation("AiSectionScoreData");
});
modelBuilder.Entity("GameDatabase.Entities.ChallengeCompeteDatum", b =>
{
b.Navigation("Participants");
b.Navigation("Songs");
});
modelBuilder.Entity("GameDatabase.Entities.ChallengeCompeteSongDatum", b =>
{
b.Navigation("BestScores");
});
modelBuilder.Entity("GameDatabase.Entities.DanScoreDatum", b =>
{
b.Navigation("DanStageScoreData");
});
modelBuilder.Entity("GameDatabase.Entities.UserDatum", b =>
{
b.Navigation("Tokens");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -0,0 +1,150 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace GameDatabase.Migrations
{
/// <inheritdoc />
public partial class AddChallengeCompete : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "ChallengeCompeteData",
columns: table => new
{
CompId = table.Column<uint>(type: "INTEGER", nullable: false)
.Annotation("Sqlite:Autoincrement", true),
CompeteMode = table.Column<uint>(type: "INTEGER", nullable: false),
Baid = table.Column<uint>(type: "INTEGER", nullable: false),
CompeteName = table.Column<string>(type: "TEXT", nullable: false),
CompeteDescribe = table.Column<string>(type: "TEXT", nullable: false),
MaxParticipant = table.Column<uint>(type: "INTEGER", nullable: false),
CreateTime = table.Column<DateTime>(type: "datetime", nullable: false),
ExpireTime = table.Column<DateTime>(type: "datetime", nullable: false),
RequireTitle = table.Column<uint>(type: "INTEGER", nullable: false),
Share = table.Column<uint>(type: "INTEGER", nullable: false),
CompeteTarget = table.Column<uint>(type: "INTEGER", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_ChallengeCompeteData", x => x.CompId);
});
migrationBuilder.CreateTable(
name: "ChallengeCompeteParticipantData",
columns: table => new
{
CompId = table.Column<uint>(type: "INTEGER", nullable: false),
Baid = table.Column<uint>(type: "INTEGER", nullable: false),
IsActive = table.Column<bool>(type: "INTEGER", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_ChallengeCompeteParticipantData", x => new { x.CompId, x.Baid });
table.ForeignKey(
name: "FK_ChallengeCompeteParticipantData_ChallengeCompeteData_CompId",
column: x => x.CompId,
principalTable: "ChallengeCompeteData",
principalColumn: "CompId",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_ChallengeCompeteParticipantData_UserData_Baid",
column: x => x.Baid,
principalTable: "UserData",
principalColumn: "Baid",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "ChallengeCompeteSongData",
columns: table => new
{
CompId = table.Column<uint>(type: "INTEGER", nullable: false),
SongId = table.Column<uint>(type: "INTEGER", nullable: false),
Difficulty = table.Column<uint>(type: "INTEGER", nullable: false),
SongOpt = table.Column<short>(type: "INTEGER", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_ChallengeCompeteSongData", x => new { x.CompId, x.SongId });
table.ForeignKey(
name: "FK_ChallengeCompeteSongData_ChallengeCompeteData_CompId",
column: x => x.CompId,
principalTable: "ChallengeCompeteData",
principalColumn: "CompId",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "ChallengeCompeteBestData",
columns: table => new
{
CompId = table.Column<uint>(type: "INTEGER", nullable: false),
Baid = table.Column<uint>(type: "INTEGER", nullable: false),
SongId = table.Column<uint>(type: "INTEGER", nullable: false),
Difficulty = table.Column<uint>(type: "INTEGER", nullable: false),
Crown = table.Column<uint>(type: "INTEGER", nullable: false),
Score = table.Column<uint>(type: "INTEGER", nullable: false),
ScoreRate = table.Column<uint>(type: "INTEGER", nullable: false),
ScoreRank = table.Column<uint>(type: "INTEGER", nullable: false),
GoodCount = table.Column<uint>(type: "INTEGER", nullable: false),
OkCount = table.Column<uint>(type: "INTEGER", nullable: false),
MissCount = table.Column<uint>(type: "INTEGER", nullable: false),
ComboCount = table.Column<uint>(type: "INTEGER", nullable: false),
HitCount = table.Column<uint>(type: "INTEGER", nullable: false),
DrumrollCount = table.Column<uint>(type: "INTEGER", nullable: false),
Skipped = table.Column<bool>(type: "INTEGER", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_ChallengeCompeteBestData", x => new { x.CompId, x.Baid, x.SongId });
table.ForeignKey(
name: "FK_ChallengeCompeteBestData_ChallengeCompeteSongData_CompId_SongId",
columns: x => new { x.CompId, x.SongId },
principalTable: "ChallengeCompeteSongData",
principalColumns: new[] { "CompId", "SongId" },
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_ChallengeCompeteBestData_UserData_Baid",
column: x => x.Baid,
principalTable: "UserData",
principalColumn: "Baid",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateIndex(
name: "IX_ChallengeCompeteBestData_Baid",
table: "ChallengeCompeteBestData",
column: "Baid");
migrationBuilder.CreateIndex(
name: "IX_ChallengeCompeteBestData_CompId_SongId",
table: "ChallengeCompeteBestData",
columns: new[] { "CompId", "SongId" });
migrationBuilder.CreateIndex(
name: "IX_ChallengeCompeteParticipantData_Baid",
table: "ChallengeCompeteParticipantData",
column: "Baid");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "ChallengeCompeteBestData");
migrationBuilder.DropTable(
name: "ChallengeCompeteParticipantData");
migrationBuilder.DropTable(
name: "ChallengeCompeteSongData");
migrationBuilder.DropTable(
name: "ChallengeCompeteData");
}
}
}

View File

@ -91,6 +91,142 @@ namespace TaikoLocalServer.Migrations
b.ToTable("Card", (string)null);
});
modelBuilder.Entity("GameDatabase.Entities.ChallengeCompeteBestDatum", b =>
{
b.Property<uint>("CompId")
.HasColumnType("INTEGER");
b.Property<uint>("Baid")
.HasColumnType("INTEGER");
b.Property<uint>("SongId")
.HasColumnType("INTEGER");
b.Property<uint>("ComboCount")
.HasColumnType("INTEGER");
b.Property<uint>("Crown")
.HasColumnType("INTEGER");
b.Property<uint>("Difficulty")
.HasColumnType("INTEGER");
b.Property<uint>("DrumrollCount")
.HasColumnType("INTEGER");
b.Property<uint>("GoodCount")
.HasColumnType("INTEGER");
b.Property<uint>("HitCount")
.HasColumnType("INTEGER");
b.Property<uint>("MissCount")
.HasColumnType("INTEGER");
b.Property<uint>("OkCount")
.HasColumnType("INTEGER");
b.Property<uint>("Score")
.HasColumnType("INTEGER");
b.Property<uint>("ScoreRank")
.HasColumnType("INTEGER");
b.Property<uint>("ScoreRate")
.HasColumnType("INTEGER");
b.Property<bool>("Skipped")
.HasColumnType("INTEGER");
b.HasKey("CompId", "Baid", "SongId");
b.HasIndex("Baid");
b.HasIndex("CompId", "SongId");
b.ToTable("ChallengeCompeteBestData");
});
modelBuilder.Entity("GameDatabase.Entities.ChallengeCompeteDatum", b =>
{
b.Property<uint>("CompId")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<uint>("Baid")
.HasColumnType("INTEGER");
b.Property<string>("CompeteDescribe")
.IsRequired()
.HasColumnType("TEXT");
b.Property<uint>("CompeteMode")
.HasColumnType("INTEGER");
b.Property<string>("CompeteName")
.IsRequired()
.HasColumnType("TEXT");
b.Property<uint>("CompeteTarget")
.HasColumnType("INTEGER");
b.Property<DateTime>("CreateTime")
.HasColumnType("datetime");
b.Property<DateTime>("ExpireTime")
.HasColumnType("datetime");
b.Property<uint>("MaxParticipant")
.HasColumnType("INTEGER");
b.Property<uint>("RequireTitle")
.HasColumnType("INTEGER");
b.Property<uint>("Share")
.HasColumnType("INTEGER");
b.HasKey("CompId");
b.ToTable("ChallengeCompeteData");
});
modelBuilder.Entity("GameDatabase.Entities.ChallengeCompeteParticipantDatum", b =>
{
b.Property<uint>("CompId")
.HasColumnType("INTEGER");
b.Property<uint>("Baid")
.HasColumnType("INTEGER");
b.Property<bool>("IsActive")
.HasColumnType("INTEGER");
b.HasKey("CompId", "Baid");
b.HasIndex("Baid");
b.ToTable("ChallengeCompeteParticipantData");
});
modelBuilder.Entity("GameDatabase.Entities.ChallengeCompeteSongDatum", b =>
{
b.Property<uint>("CompId")
.HasColumnType("INTEGER");
b.Property<uint>("SongId")
.HasColumnType("INTEGER");
b.Property<uint>("Difficulty")
.HasColumnType("INTEGER");
b.Property<short>("SongOpt")
.HasColumnType("INTEGER");
b.HasKey("CompId", "SongId");
b.ToTable("ChallengeCompeteSongData");
});
modelBuilder.Entity("GameDatabase.Entities.Credential", b =>
{
b.Property<uint>("Baid")
@ -483,6 +619,55 @@ namespace TaikoLocalServer.Migrations
b.Navigation("Ba");
});
modelBuilder.Entity("GameDatabase.Entities.ChallengeCompeteBestDatum", b =>
{
b.HasOne("GameDatabase.Entities.UserDatum", "UserData")
.WithMany()
.HasForeignKey("Baid")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("GameDatabase.Entities.ChallengeCompeteSongDatum", "ChallengeCompeteSongData")
.WithMany("BestScores")
.HasForeignKey("CompId", "SongId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("ChallengeCompeteSongData");
b.Navigation("UserData");
});
modelBuilder.Entity("GameDatabase.Entities.ChallengeCompeteParticipantDatum", b =>
{
b.HasOne("GameDatabase.Entities.UserDatum", "UserData")
.WithMany()
.HasForeignKey("Baid")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("GameDatabase.Entities.ChallengeCompeteDatum", "ChallengeCompeteData")
.WithMany("Participants")
.HasForeignKey("CompId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("ChallengeCompeteData");
b.Navigation("UserData");
});
modelBuilder.Entity("GameDatabase.Entities.ChallengeCompeteSongDatum", b =>
{
b.HasOne("GameDatabase.Entities.ChallengeCompeteDatum", "ChallengeCompeteData")
.WithMany("Songs")
.HasForeignKey("CompId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("ChallengeCompeteData");
});
modelBuilder.Entity("GameDatabase.Entities.Credential", b =>
{
b.HasOne("GameDatabase.Entities.UserDatum", "Ba")
@ -554,6 +739,18 @@ namespace TaikoLocalServer.Migrations
b.Navigation("AiSectionScoreData");
});
modelBuilder.Entity("GameDatabase.Entities.ChallengeCompeteDatum", b =>
{
b.Navigation("Participants");
b.Navigation("Songs");
});
modelBuilder.Entity("GameDatabase.Entities.ChallengeCompeteSongDatum", b =>
{
b.Navigation("BestScores");
});
modelBuilder.Entity("GameDatabase.Entities.DanScoreDatum", b =>
{
b.Navigation("DanStageScoreData");

View File

@ -0,0 +1,9 @@
namespace SharedProject.Enums;
public enum CompeteModeType : uint
{
None = 0,
Chanllenge = 1,
Compete = 2,
OfficialCompete = 3
}

View File

@ -0,0 +1,9 @@
namespace SharedProject.Enums;
public enum CompeteTargetType : uint
{
EveryOne = 0,
Beginner = 1,
Superior = 2
}

View File

@ -0,0 +1,7 @@
namespace SharedProject.Enums;
public enum ShareType : uint
{
EveryOne = 0,
FriendOnly = 1,
FriendAndFollower = 2
}

View File

@ -0,0 +1,63 @@
using TaikoLocalServer.Filters;
namespace TaikoLocalServer.Controllers.Api;
[ApiController]
[Route("api/[controller]")]
public class ChallengeCompeteManageController(IChallengeCompeteService challengeCompeteService) : BaseController<ChallengeCompeteManageController>
{
[HttpGet]
[ServiceFilter(typeof(AuthorizeIfRequiredAttribute))]
public ActionResult<List<ChallengeCompeteDatum>> GetAllChallengeCompete()
{
List<ChallengeCompeteDatum> datum = challengeCompeteService.GetAllChallengeCompete();
return Ok(datum);
}
[HttpPost("{baid}/createCompete")]
[ServiceFilter(typeof(AuthorizeIfRequiredAttribute))]
public async Task<IActionResult> CreateCompete(uint baid, ChallengeCompeteInfo challengeCompeteInfo)
{
await challengeCompeteService.CreateCompete(baid, challengeCompeteInfo);
return NoContent();
}
[HttpPost("{baid}/createChallenge/{targetBaid}")]
[ServiceFilter(typeof(AuthorizeIfRequiredAttribute))]
public async Task<IActionResult> CreateChallenge(uint baid, uint targetBaid, ChallengeCompeteInfo challengeCompeteInfo)
{
await challengeCompeteService.CreateChallenge(baid, targetBaid, challengeCompeteInfo);
return NoContent();
}
[HttpGet("{baid}/joinCompete/{compId}")]
[ServiceFilter(typeof(AuthorizeIfRequiredAttribute))]
public async Task<ActionResult<bool>> JoinCompete(uint baid, uint compId)
{
bool result = await challengeCompeteService.ParticipateCompete(compId, baid);
return Ok(result);
}
[HttpGet("{baid}/acceptChallenge/{compId}")]
[ServiceFilter(typeof(AuthorizeIfRequiredAttribute))]
public async Task<ActionResult<bool>> AcceptChallenge(uint baid, uint compId)
{
bool result = await challengeCompeteService.AnswerChallenge(compId, baid, true);
return Ok(result);
}
[HttpGet("{baid}/rejectChallenge/{compId}")]
[ServiceFilter(typeof(AuthorizeIfRequiredAttribute))]
public async Task<ActionResult<bool>> RejectChallenge(uint baid, uint compId)
{
bool result = await challengeCompeteService.AnswerChallenge(compId, baid, false);
return Ok(result);
}
}

View File

@ -3,16 +3,14 @@
[ApiController]
public class ChallengeCompetitionController : BaseController<ChallengeCompetitionController>
{
[HttpPost("/v12r08_ww/chassis/challengecompe.php")]
[HttpPost("/v12r08_ww/chassis/challengecompe_mn4g8uq1.php")]
[Produces("application/protobuf")]
public IActionResult HandleChallenge([FromBody] ChallengeCompeRequest request)
public async Task<IActionResult> HandleChallenge([FromBody] ChallengeCompeRequest request)
{
Logger.LogInformation("ChallengeCompe request : {Request}", request.Stringify());
var response = new ChallengeCompeResponse
{
Result = 1
};
var response = await Mediator.Send(new ChallengeCompeteQuery(request.Baid));
return Ok(response);
}

View File

@ -0,0 +1,65 @@
using GameDatabase.Context;
using System.Buffers.Binary;
namespace TaikoLocalServer.Handlers;
public record ChallengeCompeteQuery(uint Baid) : IRequest<ChallengeCompeResponse>;
public class ChallengeCompeteQueryHandler(TaikoDbContext context, IChallengeCompeteService challengeCompeteService, ILogger<UserDataQueryHandler> logger)
: IRequestHandler<ChallengeCompeteQuery, ChallengeCompeResponse>
{
public async Task<ChallengeCompeResponse> Handle(ChallengeCompeteQuery request, CancellationToken cancellationToken)
{
List<ChallengeCompeteDatum> competes = challengeCompeteService.GetInProgressChallengeCompete(request.Baid);
ChallengeCompeResponse response = new()
{
Result = 1
};
foreach (var compete in competes)
{
ChallengeCompeResponse.CompeData compeData = new()
{
CompeId = compete.CompId
};
foreach (var song in compete.Songs)
{
var songOptions = new byte[2];
BinaryPrimitives.WriteInt16LittleEndian(songOptions, song.SongOpt);
uint myHighScore = 0;
foreach (var bestScore in song.BestScores)
{
if (bestScore.Baid == request.Baid)
{
myHighScore = bestScore.Score;
}
}
ChallengeCompeResponse.CompeData.TracksData tracksData = new()
{
SongNo = song.SongId,
Level = (uint) song.Difficulty,
OptionFlg = songOptions,
HighScore = myHighScore
};
compeData.AryTrackStats.Add(tracksData);
}
switch (compete.CompeteMode)
{
case CompeteModeType.Chanllenge:
response.AryChallengeStats.Add(compeData);
break;
case CompeteModeType.Compete:
response.AryUserCompeStats.Add(compeData);
break;
case CompeteModeType.OfficialCompete:
response.AryBngCompeStats.Add(compeData);
break;
}
}
return response;
}
}

View File

@ -1,12 +1,13 @@
using System.Buffers.Binary;
using GameDatabase.Context;
using TaikoLocalServer.Services;
using Throw;
namespace TaikoLocalServer.Handlers;
public record UserDataQuery(uint Baid) : IRequest<CommonUserDataResponse>;
public class UserDataQueryHandler(TaikoDbContext context, IGameDataService gameDataService, ILogger<UserDataQueryHandler> logger)
public class UserDataQueryHandler(TaikoDbContext context, IGameDataService gameDataService, IChallengeCompeteService challengeCompeteService, ILogger<UserDataQueryHandler> logger)
: IRequestHandler<UserDataQuery, CommonUserDataResponse>
{
@ -71,7 +72,9 @@ public class UserDataQueryHandler(TaikoDbContext context, IGameDataService gameD
difficultySettingArray[i] -= 1;
}
}
bool hasChallengeCompe = challengeCompeteService.HasChallengeCompete(request.Baid);
var response = new CommonUserDataResponse
{
Result = 1,
@ -92,7 +95,7 @@ public class UserDataQueryHandler(TaikoDbContext context, IGameDataService gameD
DifficultyPlayedStar = userData.DifficultyPlayedStar,
DifficultyPlayedSort = userData.DifficultyPlayedSort,
SongRecentCnt = (uint)recentSongs.Length,
IsChallengecompe = false,
IsChallengecompe = hasChallengeCompe,
// TODO: Other fields
};

View File

@ -0,0 +1,33 @@
using System.Text.Json.Serialization;
namespace TaikoLocalServer.Models;
public class ChallengeCompeteInfo
{
[JsonPropertyName("name")]
public string Name { get; set; } = string.Empty;
[JsonPropertyName("desc")]
public string Desc { get; set; } = string.Empty;
[JsonPropertyName("competeMode")]
public CompeteModeType CompeteMode { get; set; }
[JsonPropertyName("maxParticipant")]
public uint MaxParticipant { get; set; }
[JsonPropertyName("lastFor")]
public uint LastFor { get; set; }
[JsonPropertyName("requiredTitle")]
public uint RequiredTitle { get; set; }
[JsonPropertyName("shareType")]
public ShareType ShareType { get; set; }
[JsonPropertyName("competeTargetType")]
public CompeteTargetType CompeteTargetType { get; set; }
[JsonPropertyName("competeTargetType")]
public List<ChallengeCompeteSongInfo> challengeCompeteSongs { get; set; } = new();
}

View File

@ -0,0 +1,16 @@
using SharedProject.Models;
using System.Text.Json.Serialization;
namespace TaikoLocalServer.Models;
public class ChallengeCompeteSongInfo
{
[JsonPropertyName("songId")]
public uint SongId { get; set; }
[JsonPropertyName("difficulty")]
public Difficulty Difficulty { get; set; }
[JsonPropertyName("playSetting")]
public PlaySetting PlaySetting { get; set; } = new();
}

View File

@ -0,0 +1,174 @@

using GameDatabase.Context;
using SharedProject.Utils;
using Throw;
namespace TaikoLocalServer.Services;
public class ChallengeCompeteService : IChallengeCompeteService
{
private readonly TaikoDbContext context;
public ChallengeCompeteService(TaikoDbContext context)
{
this.context = context;
}
public bool HasChallengeCompete(uint baid)
{
return context.ChallengeCompeteData
.Include(c => c.Participants)
.Any(data =>
data.CreateTime < DateTime.Now &&
data.ExpireTime > DateTime.Now &&
data.Participants.Any(participant => participant.Baid == baid && participant.IsActive)
);
}
public List<ChallengeCompeteDatum> GetInProgressChallengeCompete(uint baid)
{
return context.ChallengeCompeteData
.Include(c => c.Participants)
.Where(data =>
data.CreateTime < DateTime.Now &&
data.ExpireTime > DateTime.Now &&
data.Participants.Any(participant => participant.Baid == baid)
).ToList();
}
public List<ChallengeCompeteDatum> GetAllChallengeCompete()
{
return context.ChallengeCompeteData.Where(data => true).ToList();
}
public async Task CreateCompete(uint baid, ChallengeCompeteInfo challengeCompeteInfo)
{
ChallengeCompeteDatum challengeCompeteData = new()
{
CompId = context.ChallengeCompeteData.Any() ? context.ChallengeCompeteData.AsEnumerable().Max(c => c.CompId) + 1 : 1,
CompeteMode = challengeCompeteInfo.CompeteMode,
Baid = baid,
CompeteName = challengeCompeteInfo.Name,
CompeteDescribe = challengeCompeteInfo.Desc,
MaxParticipant = challengeCompeteInfo.MaxParticipant,
CreateTime = DateTime.Now,
ExpireTime = DateTime.Now.AddDays(challengeCompeteInfo.LastFor),
RequireTitle = challengeCompeteInfo.RequiredTitle,
Share = challengeCompeteInfo.ShareType,
CompeteTarget = challengeCompeteInfo.CompeteTargetType
};
await context.AddAsync(challengeCompeteData);
foreach (var song in challengeCompeteInfo.challengeCompeteSongs)
{
ChallengeCompeteSongDatum challengeCompeteSongData = new()
{
CompId = challengeCompeteData.CompId,
SongId = song.SongId,
Difficulty = song.Difficulty,
SongOpt = PlaySettingConverter.PlaySettingToShort(song.PlaySetting)
};
await context.AddAsync(challengeCompeteSongData);
}
ChallengeCompeteParticipantDatum participantDatum = new()
{
CompId = challengeCompeteData.CompId,
Baid = baid,
IsActive = true
};
await context.AddAsync(participantDatum);
}
public async Task<bool> ParticipateCompete(uint compId, uint baid)
{
var challengeCompete = await context.ChallengeCompeteData.FindAsync(compId);
challengeCompete.ThrowIfNull($"Challenge not found for CompId {compId}!");
if (challengeCompete.MaxParticipant <= challengeCompete.Participants.Count()) return false;
foreach (var participant in challengeCompete.Participants)
{
if (participant.Baid == baid) return false;
}
ChallengeCompeteParticipantDatum participantDatum = new()
{
CompId = challengeCompete.CompId,
Baid = baid,
IsActive = true,
};
await context.AddAsync(participantDatum);
return true;
}
public async Task CreateChallenge(uint baid, uint targetBaid, ChallengeCompeteInfo challengeCompeteInfo)
{
ChallengeCompeteDatum challengeCompeteData = new()
{
CompId = context.ChallengeCompeteData.Any() ? context.ChallengeCompeteData.AsEnumerable().Max(c => c.CompId) + 1 : 1,
CompeteMode = challengeCompeteInfo.CompeteMode,
Baid = baid,
CompeteName = challengeCompeteInfo.Name,
CompeteDescribe = challengeCompeteInfo.Desc,
MaxParticipant = challengeCompeteInfo.MaxParticipant,
CreateTime = DateTime.Now,
ExpireTime = DateTime.Now.AddDays(challengeCompeteInfo.LastFor),
RequireTitle = challengeCompeteInfo.RequiredTitle,
Share = challengeCompeteInfo.ShareType,
CompeteTarget = challengeCompeteInfo.CompeteTargetType
};
await context.AddAsync(challengeCompeteData);
foreach (var song in challengeCompeteInfo.challengeCompeteSongs)
{
ChallengeCompeteSongDatum challengeCompeteSongData = new()
{
CompId = challengeCompeteData.CompId,
SongId = song.SongId,
Difficulty = song.Difficulty,
SongOpt = PlaySettingConverter.PlaySettingToShort(song.PlaySetting)
};
await context.AddAsync(challengeCompeteSongData);
}
ChallengeCompeteParticipantDatum participantDatum = new()
{
CompId = challengeCompeteData.CompId,
Baid = baid,
IsActive = false
};
await context.AddAsync(participantDatum);
ChallengeCompeteParticipantDatum targetDatum = new()
{
CompId = challengeCompeteData.CompId,
Baid = targetBaid,
IsActive = false
};
await context.AddAsync(targetDatum);
}
public async Task<bool> AnswerChallenge(uint compId, uint baid, bool accept)
{
var challengeCompete = await context.ChallengeCompeteData.FindAsync(compId);
challengeCompete.ThrowIfNull($"Challenge not found for CompId {compId}!");
if (challengeCompete.Baid == baid) return false;
bool hasTarget = false;
foreach (var participant in challengeCompete.Participants)
{
if (participant.Baid == baid) hasTarget = true;
}
if (!hasTarget) return false;
if (accept)
{
foreach (var participant in challengeCompete.Participants)
{
participant.IsActive = true;
context.Update(participant);
}
}
else
{
context.Remove(challengeCompete);
}
return true;
}
}

View File

@ -0,0 +1,18 @@
namespace TaikoLocalServer.Services.Interfaces;
public interface IChallengeCompeteService
{
public bool HasChallengeCompete(uint baid);
public List<ChallengeCompeteDatum> GetInProgressChallengeCompete(uint baid);
public List<ChallengeCompeteDatum> GetAllChallengeCompete();
public Task CreateCompete(uint baid, ChallengeCompeteInfo challengeCompeteInfo);
public Task<bool> ParticipateCompete(uint compId, uint baid);
public Task CreateChallenge(uint baid, uint targetBaid, ChallengeCompeteInfo challengeCompeteInfo);
public Task<bool> AnswerChallenge(uint compId, uint baid, bool accept);
}