diff --git a/GameDatabase/Context/TaikoDbContext.cs b/GameDatabase/Context/TaikoDbContext.cs index 7e95b796..0e0458cc 100644 --- a/GameDatabase/Context/TaikoDbContext.cs +++ b/GameDatabase/Context/TaikoDbContext.cs @@ -127,8 +127,10 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) }); OnModelCreatingPartial(modelBuilder); + OnModelCreatingChallengeCompete(modelBuilder); } partial void OnModelCreatingPartial(ModelBuilder modelBuilder); + partial void OnModelCreatingChallengeCompete(ModelBuilder modelBuilder); } } \ No newline at end of file diff --git a/GameDatabase/Context/TaikoDbContextChallengeCompete.cs b/GameDatabase/Context/TaikoDbContextChallengeCompete.cs new file mode 100644 index 00000000..992c3ae6 --- /dev/null +++ b/GameDatabase/Context/TaikoDbContextChallengeCompete.cs @@ -0,0 +1,78 @@ +using GameDatabase.Entities; +using Microsoft.EntityFrameworkCore; + +namespace GameDatabase.Context; + +public partial class TaikoDbContext +{ + public virtual DbSet ChallengeCompeteData { get; set; } = null; + public virtual DbSet ChallengeCompeteParticipantData { get; set; } = null; + public virtual DbSet ChallengeCompeteSongData { get; set; } = null; + public virtual DbSet ChallengeCompeteBestData { get; set; } = null; + + partial void OnModelCreatingChallengeCompete(ModelBuilder modelBuilder) + { + modelBuilder.Entity(entity => + { + entity.HasKey(e => new { e.CompId }); + + entity.Property(e => e.CompeteMode).HasConversion(); + entity.Property(e => e.Share).HasConversion(); + entity.Property(e => e.CompeteTarget).HasConversion(); + + entity.Property(e => e.CreateTime).HasColumnType("datetime"); + entity.Property(e => e.ExpireTime).HasColumnType("datetime"); + }); + + modelBuilder.Entity(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(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(); + }); + + modelBuilder.Entity(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(); + entity.Property(e => e.Crown).HasConversion(); + entity.Property(e => e.ScoreRank).HasConversion(); + }); + } +} diff --git a/GameDatabase/Entities/ChallengeCompeteBestDatum.cs b/GameDatabase/Entities/ChallengeCompeteBestDatum.cs new file mode 100644 index 00000000..13130b7a --- /dev/null +++ b/GameDatabase/Entities/ChallengeCompeteBestDatum.cs @@ -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; } +} diff --git a/GameDatabase/Entities/ChallengeCompeteDatum.cs b/GameDatabase/Entities/ChallengeCompeteDatum.cs new file mode 100644 index 00000000..a5f8aac1 --- /dev/null +++ b/GameDatabase/Entities/ChallengeCompeteDatum.cs @@ -0,0 +1,23 @@ +using SharedProject.Enums; + +namespace GameDatabase.Entities; + +public partial class ChallengeCompeteDatum +{ + public uint CompId { get; set; } + public CompeteModeType CompeteMode { get; set; } = CompeteModeType.None; + public CompeteState State { get; set; } = CompeteState.Normal; + 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 bool OnlyPlayOnce { get; set; } = false; + public ShareType Share { get; set; } = ShareType.EveryOne; + public CompeteTargetType CompeteTarget { get; set; } = CompeteTargetType.EveryOne; + public List Songs { get; set; } = new(); + public List Participants { get; set; } = new(); +} + diff --git a/GameDatabase/Entities/ChallengeCompeteParticipantDatum.cs b/GameDatabase/Entities/ChallengeCompeteParticipantDatum.cs new file mode 100644 index 00000000..08fc057f --- /dev/null +++ b/GameDatabase/Entities/ChallengeCompeteParticipantDatum.cs @@ -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; } +} diff --git a/GameDatabase/Entities/ChallengeCompeteSongDatum.cs b/GameDatabase/Entities/ChallengeCompeteSongDatum.cs new file mode 100644 index 00000000..3a9310ec --- /dev/null +++ b/GameDatabase/Entities/ChallengeCompeteSongDatum.cs @@ -0,0 +1,16 @@ +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 uint? Speed { get; set; } = null; + public bool? IsVanishOn { get; set; } = null; + public bool? IsInverseOn { get; set; } = null; + public RandomType? RandomType { get; set; } = null; + public List BestScores { get; set; } = new(); + public virtual ChallengeCompeteDatum? ChallengeCompeteData { get; set; } +} diff --git a/GameDatabase/Migrations/20240915182025_Add ChallengeCompetition.Designer.cs b/GameDatabase/Migrations/20240915182025_Add ChallengeCompetition.Designer.cs new file mode 100644 index 00000000..9010989e --- /dev/null +++ b/GameDatabase/Migrations/20240915182025_Add ChallengeCompetition.Designer.cs @@ -0,0 +1,798 @@ +// +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("20240915182025_Add ChallengeCompetition")] + partial class AddChallengeCompetition + { + /// + 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("Baid") + .HasColumnType("INTEGER"); + + b.Property("SongId") + .HasColumnType("INTEGER"); + + b.Property("Difficulty") + .HasColumnType("INTEGER"); + + b.Property("IsWin") + .HasColumnType("INTEGER"); + + b.HasKey("Baid", "SongId", "Difficulty"); + + b.ToTable("AiScoreData"); + }); + + modelBuilder.Entity("GameDatabase.Entities.AiSectionScoreDatum", b => + { + b.Property("Baid") + .HasColumnType("INTEGER"); + + b.Property("SongId") + .HasColumnType("INTEGER"); + + b.Property("Difficulty") + .HasColumnType("INTEGER"); + + b.Property("SectionIndex") + .HasColumnType("INTEGER"); + + b.Property("Crown") + .HasColumnType("INTEGER"); + + b.Property("DrumrollCount") + .HasColumnType("INTEGER"); + + b.Property("GoodCount") + .HasColumnType("INTEGER"); + + b.Property("IsWin") + .HasColumnType("INTEGER"); + + b.Property("MissCount") + .HasColumnType("INTEGER"); + + b.Property("OkCount") + .HasColumnType("INTEGER"); + + b.Property("Score") + .HasColumnType("INTEGER"); + + b.HasKey("Baid", "SongId", "Difficulty", "SectionIndex"); + + b.ToTable("AiSectionScoreData"); + }); + + modelBuilder.Entity("GameDatabase.Entities.Card", b => + { + b.Property("AccessCode") + .HasColumnType("TEXT"); + + b.Property("Baid") + .HasColumnType("INTEGER"); + + b.HasKey("AccessCode"); + + b.HasIndex("Baid"); + + b.ToTable("Card", (string)null); + }); + + modelBuilder.Entity("GameDatabase.Entities.ChallengeCompeteBestDatum", b => + { + b.Property("CompId") + .HasColumnType("INTEGER"); + + b.Property("Baid") + .HasColumnType("INTEGER"); + + b.Property("SongId") + .HasColumnType("INTEGER"); + + b.Property("ComboCount") + .HasColumnType("INTEGER"); + + b.Property("Crown") + .HasColumnType("INTEGER"); + + b.Property("Difficulty") + .HasColumnType("INTEGER"); + + b.Property("DrumrollCount") + .HasColumnType("INTEGER"); + + b.Property("GoodCount") + .HasColumnType("INTEGER"); + + b.Property("HitCount") + .HasColumnType("INTEGER"); + + b.Property("MissCount") + .HasColumnType("INTEGER"); + + b.Property("OkCount") + .HasColumnType("INTEGER"); + + b.Property("Score") + .HasColumnType("INTEGER"); + + b.Property("ScoreRank") + .HasColumnType("INTEGER"); + + b.Property("ScoreRate") + .HasColumnType("INTEGER"); + + b.Property("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("CompId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Baid") + .HasColumnType("INTEGER"); + + b.Property("CompeteDescribe") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("CompeteMode") + .HasColumnType("INTEGER"); + + b.Property("CompeteName") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("CompeteTarget") + .HasColumnType("INTEGER"); + + b.Property("CreateTime") + .HasColumnType("datetime"); + + b.Property("ExpireTime") + .HasColumnType("datetime"); + + b.Property("MaxParticipant") + .HasColumnType("INTEGER"); + + b.Property("OnlyPlayOnce") + .HasColumnType("INTEGER"); + + b.Property("RequireTitle") + .HasColumnType("INTEGER"); + + b.Property("Share") + .HasColumnType("INTEGER"); + + b.Property("State") + .HasColumnType("INTEGER"); + + b.HasKey("CompId"); + + b.HasIndex("Baid") + .IsUnique(); + + b.ToTable("ChallengeCompeteData"); + }); + + modelBuilder.Entity("GameDatabase.Entities.ChallengeCompeteParticipantDatum", b => + { + b.Property("CompId") + .HasColumnType("INTEGER"); + + b.Property("Baid") + .HasColumnType("INTEGER"); + + b.Property("IsActive") + .HasColumnType("INTEGER"); + + b.HasKey("CompId", "Baid"); + + b.HasIndex("Baid"); + + b.ToTable("ChallengeCompeteParticipantData"); + }); + + modelBuilder.Entity("GameDatabase.Entities.ChallengeCompeteSongDatum", b => + { + b.Property("CompId") + .HasColumnType("INTEGER"); + + b.Property("SongId") + .HasColumnType("INTEGER"); + + b.Property("Difficulty") + .HasColumnType("INTEGER"); + + b.Property("IsInverseOn") + .HasColumnType("INTEGER"); + + b.Property("IsVanishOn") + .HasColumnType("INTEGER"); + + b.Property("RandomType") + .HasColumnType("INTEGER"); + + b.Property("Speed") + .HasColumnType("INTEGER"); + + b.HasKey("CompId", "SongId"); + + b.ToTable("ChallengeCompeteSongData"); + }); + + modelBuilder.Entity("GameDatabase.Entities.Credential", b => + { + b.Property("Baid") + .HasColumnType("INTEGER"); + + b.Property("Password") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Salt") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Baid"); + + b.ToTable("Credential", (string)null); + }); + + modelBuilder.Entity("GameDatabase.Entities.DanScoreDatum", b => + { + b.Property("Baid") + .HasColumnType("INTEGER"); + + b.Property("DanId") + .HasColumnType("INTEGER"); + + b.Property("DanType") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasDefaultValue(1); + + b.Property("ArrivalSongCount") + .HasColumnType("INTEGER"); + + b.Property("ClearState") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasDefaultValue(0u); + + b.Property("ComboCountTotal") + .HasColumnType("INTEGER"); + + b.Property("SoulGaugeTotal") + .HasColumnType("INTEGER"); + + b.HasKey("Baid", "DanId", "DanType"); + + b.ToTable("DanScoreData"); + }); + + modelBuilder.Entity("GameDatabase.Entities.DanStageScoreDatum", b => + { + b.Property("Baid") + .HasColumnType("INTEGER"); + + b.Property("DanId") + .HasColumnType("INTEGER"); + + b.Property("DanType") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasDefaultValue(1); + + b.Property("SongNumber") + .HasColumnType("INTEGER"); + + b.Property("BadCount") + .HasColumnType("INTEGER"); + + b.Property("ComboCount") + .HasColumnType("INTEGER"); + + b.Property("DrumrollCount") + .HasColumnType("INTEGER"); + + b.Property("GoodCount") + .HasColumnType("INTEGER"); + + b.Property("HighScore") + .HasColumnType("INTEGER"); + + b.Property("OkCount") + .HasColumnType("INTEGER"); + + b.Property("PlayScore") + .HasColumnType("INTEGER"); + + b.Property("TotalHitCount") + .HasColumnType("INTEGER"); + + b.HasKey("Baid", "DanId", "DanType", "SongNumber"); + + b.ToTable("DanStageScoreData"); + }); + + modelBuilder.Entity("GameDatabase.Entities.SongBestDatum", b => + { + b.Property("Baid") + .HasColumnType("INTEGER"); + + b.Property("SongId") + .HasColumnType("INTEGER"); + + b.Property("Difficulty") + .HasColumnType("INTEGER"); + + b.Property("BestCrown") + .HasColumnType("INTEGER"); + + b.Property("BestRate") + .HasColumnType("INTEGER"); + + b.Property("BestScore") + .HasColumnType("INTEGER"); + + b.Property("BestScoreRank") + .HasColumnType("INTEGER"); + + b.HasKey("Baid", "SongId", "Difficulty"); + + b.ToTable("SongBestData"); + }); + + modelBuilder.Entity("GameDatabase.Entities.SongPlayDatum", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Baid") + .HasColumnType("INTEGER"); + + b.Property("ComboCount") + .HasColumnType("INTEGER"); + + b.Property("Crown") + .HasColumnType("INTEGER"); + + b.Property("Difficulty") + .HasColumnType("INTEGER"); + + b.Property("DrumrollCount") + .HasColumnType("INTEGER"); + + b.Property("GoodCount") + .HasColumnType("INTEGER"); + + b.Property("HitCount") + .HasColumnType("INTEGER"); + + b.Property("MissCount") + .HasColumnType("INTEGER"); + + b.Property("OkCount") + .HasColumnType("INTEGER"); + + b.Property("PlayTime") + .HasColumnType("datetime"); + + b.Property("Score") + .HasColumnType("INTEGER"); + + b.Property("ScoreRank") + .HasColumnType("INTEGER"); + + b.Property("ScoreRate") + .HasColumnType("INTEGER"); + + b.Property("Skipped") + .HasColumnType("INTEGER"); + + b.Property("SongId") + .HasColumnType("INTEGER"); + + b.Property("SongNumber") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("Baid"); + + b.ToTable("SongPlayData"); + }); + + modelBuilder.Entity("GameDatabase.Entities.Token", b => + { + b.Property("Baid") + .HasColumnType("INTEGER"); + + b.Property("Id") + .HasColumnType("INTEGER"); + + b.Property("Count") + .HasColumnType("INTEGER"); + + b.HasKey("Baid", "Id"); + + b.ToTable("Tokens"); + }); + + modelBuilder.Entity("GameDatabase.Entities.UserDatum", b => + { + b.Property("Baid") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AchievementDisplayDifficulty") + .HasColumnType("INTEGER"); + + b.Property("AiWinCount") + .HasColumnType("INTEGER"); + + b.Property("ColorBody") + .HasColumnType("INTEGER"); + + b.Property("ColorFace") + .HasColumnType("INTEGER"); + + b.Property("ColorLimb") + .HasColumnType("INTEGER"); + + b.Property("CostumeData") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("CostumeFlgArray") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("CurrentBody") + .HasColumnType("INTEGER"); + + b.Property("CurrentFace") + .HasColumnType("INTEGER"); + + b.Property("CurrentHead") + .HasColumnType("INTEGER"); + + b.Property("CurrentKigurumi") + .HasColumnType("INTEGER"); + + b.Property("CurrentPuchi") + .HasColumnType("INTEGER"); + + b.Property("DifficultyPlayedArray") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("DifficultyPlayedCourse") + .HasColumnType("INTEGER"); + + b.Property("DifficultyPlayedSort") + .HasColumnType("INTEGER"); + + b.Property("DifficultyPlayedStar") + .HasColumnType("INTEGER"); + + b.Property("DifficultySettingArray") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("DifficultySettingCourse") + .HasColumnType("INTEGER"); + + b.Property("DifficultySettingSort") + .HasColumnType("INTEGER"); + + b.Property("DifficultySettingStar") + .HasColumnType("INTEGER"); + + b.Property("DisplayAchievement") + .HasColumnType("INTEGER"); + + b.Property("DisplayDan") + .HasColumnType("INTEGER"); + + b.Property("FavoriteSongsArray") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("GenericInfoFlgArray") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("IsAdmin") + .HasColumnType("INTEGER"); + + b.Property("IsSkipOn") + .HasColumnType("INTEGER"); + + b.Property("IsVoiceOn") + .HasColumnType("INTEGER"); + + b.Property("LastPlayDatetime") + .HasColumnType("datetime"); + + b.Property("LastPlayMode") + .HasColumnType("INTEGER"); + + b.Property("MyDonName") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("MyDonNameLanguage") + .HasColumnType("INTEGER"); + + b.Property("NotesPosition") + .HasColumnType("INTEGER"); + + b.Property("OptionSetting") + .HasColumnType("INTEGER"); + + b.Property("SelectedToneId") + .HasColumnType("INTEGER"); + + b.Property("Title") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("TitleFlgArray") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("TitlePlateId") + .HasColumnType("INTEGER"); + + b.Property("ToneFlgArray") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("UnlockedBody") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("UnlockedFace") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("UnlockedHead") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("UnlockedKigurumi") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("UnlockedPuchi") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("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.ChallengeCompeteDatum", b => + { + b.HasOne("GameDatabase.Entities.UserDatum", "Holder") + .WithOne() + .HasForeignKey("GameDatabase.Entities.ChallengeCompeteDatum", "Baid") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Holder"); + }); + + 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 + } + } +} diff --git a/GameDatabase/Migrations/20240915182025_Add ChallengeCompetition.cs b/GameDatabase/Migrations/20240915182025_Add ChallengeCompetition.cs new file mode 100644 index 00000000..6c3540d3 --- /dev/null +++ b/GameDatabase/Migrations/20240915182025_Add ChallengeCompetition.cs @@ -0,0 +1,167 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace GameDatabase.Migrations +{ + /// + public partial class AddChallengeCompetition : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "ChallengeCompeteData", + columns: table => new + { + CompId = table.Column(type: "INTEGER", nullable: false) + .Annotation("Sqlite:Autoincrement", true), + CompeteMode = table.Column(type: "INTEGER", nullable: false), + State = table.Column(type: "INTEGER", nullable: false), + Baid = table.Column(type: "INTEGER", nullable: false), + CompeteName = table.Column(type: "TEXT", nullable: false), + CompeteDescribe = table.Column(type: "TEXT", nullable: false), + MaxParticipant = table.Column(type: "INTEGER", nullable: false), + CreateTime = table.Column(type: "datetime", nullable: false), + ExpireTime = table.Column(type: "datetime", nullable: false), + RequireTitle = table.Column(type: "INTEGER", nullable: false), + OnlyPlayOnce = table.Column(type: "INTEGER", nullable: false), + Share = table.Column(type: "INTEGER", nullable: false), + CompeteTarget = table.Column(type: "INTEGER", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ChallengeCompeteData", x => x.CompId); + table.ForeignKey( + name: "FK_ChallengeCompeteData_UserData_Baid", + column: x => x.Baid, + principalTable: "UserData", + principalColumn: "Baid", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "ChallengeCompeteParticipantData", + columns: table => new + { + CompId = table.Column(type: "INTEGER", nullable: false), + Baid = table.Column(type: "INTEGER", nullable: false), + IsActive = table.Column(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(type: "INTEGER", nullable: false), + SongId = table.Column(type: "INTEGER", nullable: false), + Difficulty = table.Column(type: "INTEGER", nullable: false), + Speed = table.Column(type: "INTEGER", nullable: true), + IsVanishOn = table.Column(type: "INTEGER", nullable: true), + IsInverseOn = table.Column(type: "INTEGER", nullable: true), + RandomType = table.Column(type: "INTEGER", nullable: true) + }, + 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(type: "INTEGER", nullable: false), + Baid = table.Column(type: "INTEGER", nullable: false), + SongId = table.Column(type: "INTEGER", nullable: false), + Difficulty = table.Column(type: "INTEGER", nullable: false), + Crown = table.Column(type: "INTEGER", nullable: false), + Score = table.Column(type: "INTEGER", nullable: false), + ScoreRate = table.Column(type: "INTEGER", nullable: false), + ScoreRank = table.Column(type: "INTEGER", nullable: false), + GoodCount = table.Column(type: "INTEGER", nullable: false), + OkCount = table.Column(type: "INTEGER", nullable: false), + MissCount = table.Column(type: "INTEGER", nullable: false), + ComboCount = table.Column(type: "INTEGER", nullable: false), + HitCount = table.Column(type: "INTEGER", nullable: false), + DrumrollCount = table.Column(type: "INTEGER", nullable: false), + Skipped = table.Column(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_ChallengeCompeteData_Baid", + table: "ChallengeCompeteData", + column: "Baid", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_ChallengeCompeteParticipantData_Baid", + table: "ChallengeCompeteParticipantData", + column: "Baid"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "ChallengeCompeteBestData"); + + migrationBuilder.DropTable( + name: "ChallengeCompeteParticipantData"); + + migrationBuilder.DropTable( + name: "ChallengeCompeteSongData"); + + migrationBuilder.DropTable( + name: "ChallengeCompeteData"); + } + } +} diff --git a/GameDatabase/Migrations/20240915191732_Update ChallengeCompetition.Designer.cs b/GameDatabase/Migrations/20240915191732_Update ChallengeCompetition.Designer.cs new file mode 100644 index 00000000..7b0a3a74 --- /dev/null +++ b/GameDatabase/Migrations/20240915191732_Update ChallengeCompetition.Designer.cs @@ -0,0 +1,784 @@ +// +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("20240915191732_Update ChallengeCompetition")] + partial class UpdateChallengeCompetition + { + /// + 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("Baid") + .HasColumnType("INTEGER"); + + b.Property("SongId") + .HasColumnType("INTEGER"); + + b.Property("Difficulty") + .HasColumnType("INTEGER"); + + b.Property("IsWin") + .HasColumnType("INTEGER"); + + b.HasKey("Baid", "SongId", "Difficulty"); + + b.ToTable("AiScoreData"); + }); + + modelBuilder.Entity("GameDatabase.Entities.AiSectionScoreDatum", b => + { + b.Property("Baid") + .HasColumnType("INTEGER"); + + b.Property("SongId") + .HasColumnType("INTEGER"); + + b.Property("Difficulty") + .HasColumnType("INTEGER"); + + b.Property("SectionIndex") + .HasColumnType("INTEGER"); + + b.Property("Crown") + .HasColumnType("INTEGER"); + + b.Property("DrumrollCount") + .HasColumnType("INTEGER"); + + b.Property("GoodCount") + .HasColumnType("INTEGER"); + + b.Property("IsWin") + .HasColumnType("INTEGER"); + + b.Property("MissCount") + .HasColumnType("INTEGER"); + + b.Property("OkCount") + .HasColumnType("INTEGER"); + + b.Property("Score") + .HasColumnType("INTEGER"); + + b.HasKey("Baid", "SongId", "Difficulty", "SectionIndex"); + + b.ToTable("AiSectionScoreData"); + }); + + modelBuilder.Entity("GameDatabase.Entities.Card", b => + { + b.Property("AccessCode") + .HasColumnType("TEXT"); + + b.Property("Baid") + .HasColumnType("INTEGER"); + + b.HasKey("AccessCode"); + + b.HasIndex("Baid"); + + b.ToTable("Card", (string)null); + }); + + modelBuilder.Entity("GameDatabase.Entities.ChallengeCompeteBestDatum", b => + { + b.Property("CompId") + .HasColumnType("INTEGER"); + + b.Property("Baid") + .HasColumnType("INTEGER"); + + b.Property("SongId") + .HasColumnType("INTEGER"); + + b.Property("ComboCount") + .HasColumnType("INTEGER"); + + b.Property("Crown") + .HasColumnType("INTEGER"); + + b.Property("Difficulty") + .HasColumnType("INTEGER"); + + b.Property("DrumrollCount") + .HasColumnType("INTEGER"); + + b.Property("GoodCount") + .HasColumnType("INTEGER"); + + b.Property("HitCount") + .HasColumnType("INTEGER"); + + b.Property("MissCount") + .HasColumnType("INTEGER"); + + b.Property("OkCount") + .HasColumnType("INTEGER"); + + b.Property("Score") + .HasColumnType("INTEGER"); + + b.Property("ScoreRank") + .HasColumnType("INTEGER"); + + b.Property("ScoreRate") + .HasColumnType("INTEGER"); + + b.Property("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("CompId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Baid") + .HasColumnType("INTEGER"); + + b.Property("CompeteDescribe") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("CompeteMode") + .HasColumnType("INTEGER"); + + b.Property("CompeteName") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("CompeteTarget") + .HasColumnType("INTEGER"); + + b.Property("CreateTime") + .HasColumnType("datetime"); + + b.Property("ExpireTime") + .HasColumnType("datetime"); + + b.Property("MaxParticipant") + .HasColumnType("INTEGER"); + + b.Property("OnlyPlayOnce") + .HasColumnType("INTEGER"); + + b.Property("RequireTitle") + .HasColumnType("INTEGER"); + + b.Property("Share") + .HasColumnType("INTEGER"); + + b.Property("State") + .HasColumnType("INTEGER"); + + b.HasKey("CompId"); + + b.ToTable("ChallengeCompeteData"); + }); + + modelBuilder.Entity("GameDatabase.Entities.ChallengeCompeteParticipantDatum", b => + { + b.Property("CompId") + .HasColumnType("INTEGER"); + + b.Property("Baid") + .HasColumnType("INTEGER"); + + b.Property("IsActive") + .HasColumnType("INTEGER"); + + b.HasKey("CompId", "Baid"); + + b.HasIndex("Baid"); + + b.ToTable("ChallengeCompeteParticipantData"); + }); + + modelBuilder.Entity("GameDatabase.Entities.ChallengeCompeteSongDatum", b => + { + b.Property("CompId") + .HasColumnType("INTEGER"); + + b.Property("SongId") + .HasColumnType("INTEGER"); + + b.Property("Difficulty") + .HasColumnType("INTEGER"); + + b.Property("IsInverseOn") + .HasColumnType("INTEGER"); + + b.Property("IsVanishOn") + .HasColumnType("INTEGER"); + + b.Property("RandomType") + .HasColumnType("INTEGER"); + + b.Property("Speed") + .HasColumnType("INTEGER"); + + b.HasKey("CompId", "SongId"); + + b.ToTable("ChallengeCompeteSongData"); + }); + + modelBuilder.Entity("GameDatabase.Entities.Credential", b => + { + b.Property("Baid") + .HasColumnType("INTEGER"); + + b.Property("Password") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Salt") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Baid"); + + b.ToTable("Credential", (string)null); + }); + + modelBuilder.Entity("GameDatabase.Entities.DanScoreDatum", b => + { + b.Property("Baid") + .HasColumnType("INTEGER"); + + b.Property("DanId") + .HasColumnType("INTEGER"); + + b.Property("DanType") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasDefaultValue(1); + + b.Property("ArrivalSongCount") + .HasColumnType("INTEGER"); + + b.Property("ClearState") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasDefaultValue(0u); + + b.Property("ComboCountTotal") + .HasColumnType("INTEGER"); + + b.Property("SoulGaugeTotal") + .HasColumnType("INTEGER"); + + b.HasKey("Baid", "DanId", "DanType"); + + b.ToTable("DanScoreData"); + }); + + modelBuilder.Entity("GameDatabase.Entities.DanStageScoreDatum", b => + { + b.Property("Baid") + .HasColumnType("INTEGER"); + + b.Property("DanId") + .HasColumnType("INTEGER"); + + b.Property("DanType") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasDefaultValue(1); + + b.Property("SongNumber") + .HasColumnType("INTEGER"); + + b.Property("BadCount") + .HasColumnType("INTEGER"); + + b.Property("ComboCount") + .HasColumnType("INTEGER"); + + b.Property("DrumrollCount") + .HasColumnType("INTEGER"); + + b.Property("GoodCount") + .HasColumnType("INTEGER"); + + b.Property("HighScore") + .HasColumnType("INTEGER"); + + b.Property("OkCount") + .HasColumnType("INTEGER"); + + b.Property("PlayScore") + .HasColumnType("INTEGER"); + + b.Property("TotalHitCount") + .HasColumnType("INTEGER"); + + b.HasKey("Baid", "DanId", "DanType", "SongNumber"); + + b.ToTable("DanStageScoreData"); + }); + + modelBuilder.Entity("GameDatabase.Entities.SongBestDatum", b => + { + b.Property("Baid") + .HasColumnType("INTEGER"); + + b.Property("SongId") + .HasColumnType("INTEGER"); + + b.Property("Difficulty") + .HasColumnType("INTEGER"); + + b.Property("BestCrown") + .HasColumnType("INTEGER"); + + b.Property("BestRate") + .HasColumnType("INTEGER"); + + b.Property("BestScore") + .HasColumnType("INTEGER"); + + b.Property("BestScoreRank") + .HasColumnType("INTEGER"); + + b.HasKey("Baid", "SongId", "Difficulty"); + + b.ToTable("SongBestData"); + }); + + modelBuilder.Entity("GameDatabase.Entities.SongPlayDatum", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Baid") + .HasColumnType("INTEGER"); + + b.Property("ComboCount") + .HasColumnType("INTEGER"); + + b.Property("Crown") + .HasColumnType("INTEGER"); + + b.Property("Difficulty") + .HasColumnType("INTEGER"); + + b.Property("DrumrollCount") + .HasColumnType("INTEGER"); + + b.Property("GoodCount") + .HasColumnType("INTEGER"); + + b.Property("HitCount") + .HasColumnType("INTEGER"); + + b.Property("MissCount") + .HasColumnType("INTEGER"); + + b.Property("OkCount") + .HasColumnType("INTEGER"); + + b.Property("PlayTime") + .HasColumnType("datetime"); + + b.Property("Score") + .HasColumnType("INTEGER"); + + b.Property("ScoreRank") + .HasColumnType("INTEGER"); + + b.Property("ScoreRate") + .HasColumnType("INTEGER"); + + b.Property("Skipped") + .HasColumnType("INTEGER"); + + b.Property("SongId") + .HasColumnType("INTEGER"); + + b.Property("SongNumber") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("Baid"); + + b.ToTable("SongPlayData"); + }); + + modelBuilder.Entity("GameDatabase.Entities.Token", b => + { + b.Property("Baid") + .HasColumnType("INTEGER"); + + b.Property("Id") + .HasColumnType("INTEGER"); + + b.Property("Count") + .HasColumnType("INTEGER"); + + b.HasKey("Baid", "Id"); + + b.ToTable("Tokens"); + }); + + modelBuilder.Entity("GameDatabase.Entities.UserDatum", b => + { + b.Property("Baid") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AchievementDisplayDifficulty") + .HasColumnType("INTEGER"); + + b.Property("AiWinCount") + .HasColumnType("INTEGER"); + + b.Property("ColorBody") + .HasColumnType("INTEGER"); + + b.Property("ColorFace") + .HasColumnType("INTEGER"); + + b.Property("ColorLimb") + .HasColumnType("INTEGER"); + + b.Property("CostumeData") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("CostumeFlgArray") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("CurrentBody") + .HasColumnType("INTEGER"); + + b.Property("CurrentFace") + .HasColumnType("INTEGER"); + + b.Property("CurrentHead") + .HasColumnType("INTEGER"); + + b.Property("CurrentKigurumi") + .HasColumnType("INTEGER"); + + b.Property("CurrentPuchi") + .HasColumnType("INTEGER"); + + b.Property("DifficultyPlayedArray") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("DifficultyPlayedCourse") + .HasColumnType("INTEGER"); + + b.Property("DifficultyPlayedSort") + .HasColumnType("INTEGER"); + + b.Property("DifficultyPlayedStar") + .HasColumnType("INTEGER"); + + b.Property("DifficultySettingArray") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("DifficultySettingCourse") + .HasColumnType("INTEGER"); + + b.Property("DifficultySettingSort") + .HasColumnType("INTEGER"); + + b.Property("DifficultySettingStar") + .HasColumnType("INTEGER"); + + b.Property("DisplayAchievement") + .HasColumnType("INTEGER"); + + b.Property("DisplayDan") + .HasColumnType("INTEGER"); + + b.Property("FavoriteSongsArray") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("GenericInfoFlgArray") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("IsAdmin") + .HasColumnType("INTEGER"); + + b.Property("IsSkipOn") + .HasColumnType("INTEGER"); + + b.Property("IsVoiceOn") + .HasColumnType("INTEGER"); + + b.Property("LastPlayDatetime") + .HasColumnType("datetime"); + + b.Property("LastPlayMode") + .HasColumnType("INTEGER"); + + b.Property("MyDonName") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("MyDonNameLanguage") + .HasColumnType("INTEGER"); + + b.Property("NotesPosition") + .HasColumnType("INTEGER"); + + b.Property("OptionSetting") + .HasColumnType("INTEGER"); + + b.Property("SelectedToneId") + .HasColumnType("INTEGER"); + + b.Property("Title") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("TitleFlgArray") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("TitlePlateId") + .HasColumnType("INTEGER"); + + b.Property("ToneFlgArray") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("UnlockedBody") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("UnlockedFace") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("UnlockedHead") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("UnlockedKigurumi") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("UnlockedPuchi") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("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 + } + } +} diff --git a/GameDatabase/Migrations/20240915191732_Update ChallengeCompetition.cs b/GameDatabase/Migrations/20240915191732_Update ChallengeCompetition.cs new file mode 100644 index 00000000..ed6bff60 --- /dev/null +++ b/GameDatabase/Migrations/20240915191732_Update ChallengeCompetition.cs @@ -0,0 +1,40 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace GameDatabase.Migrations +{ + /// + public partial class UpdateChallengeCompetition : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_ChallengeCompeteData_UserData_Baid", + table: "ChallengeCompeteData"); + + migrationBuilder.DropIndex( + name: "IX_ChallengeCompeteData_Baid", + table: "ChallengeCompeteData"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateIndex( + name: "IX_ChallengeCompeteData_Baid", + table: "ChallengeCompeteData", + column: "Baid", + unique: true); + + migrationBuilder.AddForeignKey( + name: "FK_ChallengeCompeteData_UserData_Baid", + table: "ChallengeCompeteData", + column: "Baid", + principalTable: "UserData", + principalColumn: "Baid", + onDelete: ReferentialAction.Cascade); + } + } +} diff --git a/GameDatabase/Migrations/TaikoDbContextModelSnapshot.cs b/GameDatabase/Migrations/TaikoDbContextModelSnapshot.cs index 8fa0e9fa..468c03f2 100644 --- a/GameDatabase/Migrations/TaikoDbContextModelSnapshot.cs +++ b/GameDatabase/Migrations/TaikoDbContextModelSnapshot.cs @@ -91,6 +91,157 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.ToTable("Card", (string)null); }); + modelBuilder.Entity("GameDatabase.Entities.ChallengeCompeteBestDatum", b => + { + b.Property("CompId") + .HasColumnType("INTEGER"); + + b.Property("Baid") + .HasColumnType("INTEGER"); + + b.Property("SongId") + .HasColumnType("INTEGER"); + + b.Property("ComboCount") + .HasColumnType("INTEGER"); + + b.Property("Crown") + .HasColumnType("INTEGER"); + + b.Property("Difficulty") + .HasColumnType("INTEGER"); + + b.Property("DrumrollCount") + .HasColumnType("INTEGER"); + + b.Property("GoodCount") + .HasColumnType("INTEGER"); + + b.Property("HitCount") + .HasColumnType("INTEGER"); + + b.Property("MissCount") + .HasColumnType("INTEGER"); + + b.Property("OkCount") + .HasColumnType("INTEGER"); + + b.Property("Score") + .HasColumnType("INTEGER"); + + b.Property("ScoreRank") + .HasColumnType("INTEGER"); + + b.Property("ScoreRate") + .HasColumnType("INTEGER"); + + b.Property("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("CompId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Baid") + .HasColumnType("INTEGER"); + + b.Property("CompeteDescribe") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("CompeteMode") + .HasColumnType("INTEGER"); + + b.Property("CompeteName") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("CompeteTarget") + .HasColumnType("INTEGER"); + + b.Property("CreateTime") + .HasColumnType("datetime"); + + b.Property("ExpireTime") + .HasColumnType("datetime"); + + b.Property("MaxParticipant") + .HasColumnType("INTEGER"); + + b.Property("OnlyPlayOnce") + .HasColumnType("INTEGER"); + + b.Property("RequireTitle") + .HasColumnType("INTEGER"); + + b.Property("Share") + .HasColumnType("INTEGER"); + + b.Property("State") + .HasColumnType("INTEGER"); + + b.HasKey("CompId"); + + b.ToTable("ChallengeCompeteData"); + }); + + modelBuilder.Entity("GameDatabase.Entities.ChallengeCompeteParticipantDatum", b => + { + b.Property("CompId") + .HasColumnType("INTEGER"); + + b.Property("Baid") + .HasColumnType("INTEGER"); + + b.Property("IsActive") + .HasColumnType("INTEGER"); + + b.HasKey("CompId", "Baid"); + + b.HasIndex("Baid"); + + b.ToTable("ChallengeCompeteParticipantData"); + }); + + modelBuilder.Entity("GameDatabase.Entities.ChallengeCompeteSongDatum", b => + { + b.Property("CompId") + .HasColumnType("INTEGER"); + + b.Property("SongId") + .HasColumnType("INTEGER"); + + b.Property("Difficulty") + .HasColumnType("INTEGER"); + + b.Property("IsInverseOn") + .HasColumnType("INTEGER"); + + b.Property("IsVanishOn") + .HasColumnType("INTEGER"); + + b.Property("RandomType") + .HasColumnType("INTEGER"); + + b.Property("Speed") + .HasColumnType("INTEGER"); + + b.HasKey("CompId", "SongId"); + + b.ToTable("ChallengeCompeteSongData"); + }); + modelBuilder.Entity("GameDatabase.Entities.Credential", b => { b.Property("Baid") @@ -483,6 +634,55 @@ protected override void BuildModel(ModelBuilder modelBuilder) 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 +754,18 @@ protected override void BuildModel(ModelBuilder modelBuilder) 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"); diff --git a/SharedProject/Enums/CompeteModeType.cs b/SharedProject/Enums/CompeteModeType.cs new file mode 100644 index 00000000..fd286cb6 --- /dev/null +++ b/SharedProject/Enums/CompeteModeType.cs @@ -0,0 +1,9 @@ +namespace SharedProject.Enums; +public enum CompeteModeType : uint +{ + None = 0, + Chanllenge = 1, + Compete = 2, + OfficialCompete = 3 +} + diff --git a/SharedProject/Enums/CompeteState.cs b/SharedProject/Enums/CompeteState.cs new file mode 100644 index 00000000..e70bdd8a --- /dev/null +++ b/SharedProject/Enums/CompeteState.cs @@ -0,0 +1,10 @@ +namespace SharedProject.Enums; + +public enum CompeteState : uint +{ + Disabled = 0, + Normal = 1, // In Progress + Waiting = 2, // Waiting for Answer + Finished = 3, // Finished Once Compete + Rejected = 4 // Rejected Challenge +} diff --git a/SharedProject/Enums/CompeteTargetType.cs b/SharedProject/Enums/CompeteTargetType.cs new file mode 100644 index 00000000..1f9dc952 --- /dev/null +++ b/SharedProject/Enums/CompeteTargetType.cs @@ -0,0 +1,9 @@ +namespace SharedProject.Enums; + +public enum CompeteTargetType : uint +{ + EveryOne = 0, + Beginner = 1, + Superior = 2 +} + diff --git a/SharedProject/Enums/ShareType.cs b/SharedProject/Enums/ShareType.cs new file mode 100644 index 00000000..281a1764 --- /dev/null +++ b/SharedProject/Enums/ShareType.cs @@ -0,0 +1,7 @@ +namespace SharedProject.Enums; +public enum ShareType : uint +{ + EveryOne = 0, + FriendOnly = 1, + FriendAndFollower = 2 +} diff --git a/SharedProject/Models/ChallengeCompeteCreateInfo.cs b/SharedProject/Models/ChallengeCompeteCreateInfo.cs new file mode 100644 index 00000000..e20158c4 --- /dev/null +++ b/SharedProject/Models/ChallengeCompeteCreateInfo.cs @@ -0,0 +1,37 @@ +using SharedProject.Enums; +using System.Text.Json.Serialization; + +namespace SharedProject.Models; + +public class ChallengeCompeteCreateInfo +{ + [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("onlyPlayOnce")] + public bool OnlyPlayOnce { get; set; } + + [JsonPropertyName("lastFor")] + public uint LastFor { get; set; } + + [JsonPropertyName("requiredTitle")] + public uint RequiredTitle { get; set; } = 0; + + [JsonPropertyName("shareType")] + public ShareType ShareType { get; set; } = ShareType.EveryOne; + + [JsonPropertyName("competeTargetType")] + public CompeteTargetType CompeteTargetType { get; set; } = CompeteTargetType.EveryOne; + + [JsonPropertyName("challengeCompeteSongs")] + public List challengeCompeteSongs { get; set; } = new(); +} diff --git a/SharedProject/Models/ChallengeCompeteCreateSongInfo.cs b/SharedProject/Models/ChallengeCompeteCreateSongInfo.cs new file mode 100644 index 00000000..6ca70270 --- /dev/null +++ b/SharedProject/Models/ChallengeCompeteCreateSongInfo.cs @@ -0,0 +1,24 @@ +using SharedProject.Enums; +using System.Text.Json.Serialization; + +namespace SharedProject.Models; +public class ChallengeCompeteCreateSongInfo +{ + [JsonPropertyName("songId")] + public uint SongId { get; set; } + + [JsonPropertyName("difficulty")] + public Difficulty Difficulty { get; set; } + + [JsonPropertyName("speed")] + public int Speed { get; set; } = -1; + + [JsonPropertyName("isVanishOn")] + public int IsVanishOn { get; set; } = -1; + + [JsonPropertyName("isInverseOn")] + public int IsInverseOn { get; set; } = -1; + + [JsonPropertyName("randomType")] + public int RandomType { get; set; } = -1; +} \ No newline at end of file diff --git a/SharedProject/Models/ChallengeCompetition.cs b/SharedProject/Models/ChallengeCompetition.cs new file mode 100644 index 00000000..08c0b492 --- /dev/null +++ b/SharedProject/Models/ChallengeCompetition.cs @@ -0,0 +1,23 @@ +using SharedProject.Enums; + +namespace SharedProject.Models; + +public class ChallengeCompetition +{ + public uint CompId { get; set; } + public CompeteModeType CompeteMode { get; set; } = CompeteModeType.None; + public CompeteState State { get; set; } = CompeteState.Normal; + 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 bool OnlyPlayOnce { get; set; } = false; + public ShareType Share { get; set; } = ShareType.EveryOne; + public CompeteTargetType CompeteTarget { get; set; } = CompeteTargetType.EveryOne; + public UserAppearance? Holder { get; set; } = new(); + public List Songs { get; set; } = new(); + public List Participants { get; set; } = new(); +} diff --git a/SharedProject/Models/ChallengeCompetitionBestScore.cs b/SharedProject/Models/ChallengeCompetitionBestScore.cs new file mode 100644 index 00000000..3c02a7a3 --- /dev/null +++ b/SharedProject/Models/ChallengeCompetitionBestScore.cs @@ -0,0 +1,23 @@ +using SharedProject.Enums; + +namespace SharedProject.Models; + +public class ChallengeCompetitionBestScore +{ + public uint CompId { get; set; } + public uint Baid { get; set; } + public uint SongId { get; set; } + public UserAppearance? UserAppearance { get; set; } = null; + 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; } +} diff --git a/SharedProject/Models/ChallengeCompetitionHolderInfo.cs b/SharedProject/Models/ChallengeCompetitionHolderInfo.cs new file mode 100644 index 00000000..d2300582 --- /dev/null +++ b/SharedProject/Models/ChallengeCompetitionHolderInfo.cs @@ -0,0 +1,18 @@ +namespace SharedProject.Models; + +public class ChallengeCompetitionHolderInfo +{ + public uint Baid { get; set; } + public string MyDonName { get; set; } = string.Empty; + public uint MyDonNameLanguage { get; set; } + public string Title { get; set; } = string.Empty; + public uint TitlePlateId { get; set; } + public uint ColorBody { get; set; } + public uint ColorFace { get; set; } + public uint ColorLimb { get; set; } + public uint CurrentKigurumi { get; set; } + public uint CurrentHead { get; set; } + public uint CurrentBody { get; set; } + public uint CurrentFace { get; set; } + public uint CurrentPuchi { get; set; } +} diff --git a/SharedProject/Models/ChallengeCompetitionParticipant.cs b/SharedProject/Models/ChallengeCompetitionParticipant.cs new file mode 100644 index 00000000..c308667e --- /dev/null +++ b/SharedProject/Models/ChallengeCompetitionParticipant.cs @@ -0,0 +1,9 @@ +namespace SharedProject.Models; + +public class ChallengeCompetitionParticipant +{ + public uint CompId { get; set; } + public uint Baid { get; set; } + public bool IsActive { get; set; } + public UserAppearance? UserInfo { get; set; } = new(); +} diff --git a/SharedProject/Models/ChallengeCompetitionSong.cs b/SharedProject/Models/ChallengeCompetitionSong.cs new file mode 100644 index 00000000..a6104f80 --- /dev/null +++ b/SharedProject/Models/ChallengeCompetitionSong.cs @@ -0,0 +1,16 @@ +using SharedProject.Enums; + +namespace SharedProject.Models; + +public class ChallengeCompetitionSong +{ + public uint CompId { get; set; } + public uint SongId { get; set; } + public MusicDetail? MusicDetail { get; set; } = null; + public Difficulty Difficulty { get; set; } + public uint? Speed { get; set; } = null; + public bool? IsVanishOn { get; set; } = null; + public bool? IsInverseOn { get; set; } = null; + public RandomType? RandomType { get; set; } = null; + public List BestScores { get; set; } = new(); +} diff --git a/SharedProject/Models/PlaySetting.cs b/SharedProject/Models/PlaySetting.cs index c554bf4b..f34301af 100644 --- a/SharedProject/Models/PlaySetting.cs +++ b/SharedProject/Models/PlaySetting.cs @@ -1,14 +1,19 @@ using SharedProject.Enums; +using System.Text.Json.Serialization; namespace SharedProject.Models; public class PlaySetting { + [JsonPropertyName("speed")] public uint Speed { get; set; } + [JsonPropertyName("isVanishOn")] public bool IsVanishOn { get; set; } - + + [JsonPropertyName("isInverseOn")] public bool IsInverseOn { get; set; } - + + [JsonPropertyName("randomType")] public RandomType RandomType { get; set; } } \ No newline at end of file diff --git a/SharedProject/Models/Requests/AnswerChallengeRequest.cs b/SharedProject/Models/Requests/AnswerChallengeRequest.cs new file mode 100644 index 00000000..e5d50346 --- /dev/null +++ b/SharedProject/Models/Requests/AnswerChallengeRequest.cs @@ -0,0 +1,8 @@ +namespace SharedProject.Models.Requests; + +public class AnswerChallengeRequest +{ + public uint CompId { get; set; } + public uint Baid { get; set; } + public bool Accept { get; set; } +} diff --git a/SharedProject/Models/Responses/ChallengeCompetitionResponse.cs b/SharedProject/Models/Responses/ChallengeCompetitionResponse.cs new file mode 100644 index 00000000..f9371869 --- /dev/null +++ b/SharedProject/Models/Responses/ChallengeCompetitionResponse.cs @@ -0,0 +1,10 @@ +namespace SharedProject.Models.Responses; + +public class ChallengeCompetitionResponse +{ + public List List { get; set; } = new(); + public int Page { get; set; } = 1; + public int TotalPages { get; set; } = 0; + public int Total { get; set; } = 0; + +} diff --git a/SharedProject/Models/SongInfo.cs b/SharedProject/Models/SongInfo.cs new file mode 100644 index 00000000..b85e4111 --- /dev/null +++ b/SharedProject/Models/SongInfo.cs @@ -0,0 +1,13 @@ +using SharedProject.Enums; + +namespace SharedProject.Models; + +public class SongInfo +{ + public MusicDetail MusicDetail { get; set; } = new(); + + public Difficulty Difficulty { get; set; } = new(); + + public int Level { get; set; } = 0; + +} diff --git a/SharedProject/Models/User.cs b/SharedProject/Models/User.cs index ad50e18e..d16c2ce0 100644 --- a/SharedProject/Models/User.cs +++ b/SharedProject/Models/User.cs @@ -1,12 +1,18 @@ -namespace SharedProject.Models; +using System.Text.Json.Serialization; + +namespace SharedProject.Models; public class User { + [JsonPropertyName("baid")] public uint Baid { get; set; } - + + [JsonPropertyName("accessCodes")] public List AccessCodes { get; set; } = new(); - + + [JsonPropertyName("isAdmin")] public bool IsAdmin { get; set; } - + + [JsonPropertyName("userSetting")] public UserSetting UserSetting { get; set; } = new(); } \ No newline at end of file diff --git a/SharedProject/Models/UserAppearance.cs b/SharedProject/Models/UserAppearance.cs new file mode 100644 index 00000000..9206d79d --- /dev/null +++ b/SharedProject/Models/UserAppearance.cs @@ -0,0 +1,18 @@ +namespace SharedProject.Models; + +public class UserAppearance +{ + public uint Baid { get; set; } + public string MyDonName { get; set; } = string.Empty; + public uint MyDonNameLanguage { get; set; } + public string Title { get; set; } = string.Empty; + public uint TitlePlateId { get; set; } + public uint Kigurumi { get; set; } + public uint Head { get; set; } + public uint Body { get; set; } + public uint Face { get; set; } + public uint Puchi { get; set; } + public uint FaceColor { get; set; } + public uint BodyColor { get; set; } + public uint LimbColor { get; set; } +} diff --git a/SharedProject/Models/UserSetting.cs b/SharedProject/Models/UserSetting.cs index 6699bfdc..ec65f3c9 100644 --- a/SharedProject/Models/UserSetting.cs +++ b/SharedProject/Models/UserSetting.cs @@ -1,68 +1,100 @@ using SharedProject.Enums; +using System.Text.Json.Serialization; namespace SharedProject.Models; public class UserSetting { + [JsonPropertyName("baid")] public uint Baid { get; set; } - + + [JsonPropertyName("toneId")] public uint ToneId { get; set; } + [JsonPropertyName("isDisplayAchievement")] public bool IsDisplayAchievement { get; set; } + [JsonPropertyName("isDisplayDanOnNamePlate")] public bool IsDisplayDanOnNamePlate { get; set; } + [JsonPropertyName("difficultySettingCourse")] public uint DifficultySettingCourse { get; set; } + [JsonPropertyName("difficultySettingStar")] public uint DifficultySettingStar { get; set; } + [JsonPropertyName("difficultySettingSort")] public uint DifficultySettingSort { get; set; } + [JsonPropertyName("isVoiceOn")] public bool IsVoiceOn { get; set; } + [JsonPropertyName("isSkipOn")] public bool IsSkipOn { get; set; } + [JsonPropertyName("achievementDisplayDifficulty")] public Difficulty AchievementDisplayDifficulty { get; set; } + [JsonPropertyName("playSetting")] public PlaySetting PlaySetting { get; set; } = new(); + [JsonPropertyName("notesPosition")] public int NotesPosition { get; set; } + [JsonPropertyName("myDonName")] public string MyDonName { get; set; } = string.Empty; + [JsonPropertyName("myDonNameLanguage")] public uint MyDonNameLanguage { get; set; } + [JsonPropertyName("title")] public string Title { get; set; } = string.Empty; + [JsonPropertyName("titlePlateId")] public uint TitlePlateId { get; set; } + [JsonPropertyName("kigurumi")] public uint Kigurumi { get; set; } + [JsonPropertyName("head")] public uint Head { get; set; } + [JsonPropertyName("body")] public uint Body { get; set; } + [JsonPropertyName("face")] public uint Face { get; set; } + [JsonPropertyName("puchi")] public uint Puchi { get; set; } + [JsonPropertyName("unlockedKigurumi")] public List UnlockedKigurumi { get; set; } = new(); + [JsonPropertyName("unlockedHead")] public List UnlockedHead { get; set; } = new(); + [JsonPropertyName("unlockedBody")] public List UnlockedBody { get; set; } = new(); + [JsonPropertyName("unlockedFace")] public List UnlockedFace { get; set; } = new(); + [JsonPropertyName("unlockedPuchi")] public List UnlockedPuchi { get; set; } = new(); - + + [JsonPropertyName("unlockedTitle")] public List UnlockedTitle { get; set; } = new(); + [JsonPropertyName("faceColor")] public uint FaceColor { get; set; } + [JsonPropertyName("bodyColor")] public uint BodyColor { get; set; } + [JsonPropertyName("limbColor")] public uint LimbColor { get; set; } - + + [JsonPropertyName("lastPlayDateTime")] public DateTime LastPlayDateTime { get; set; } } \ No newline at end of file diff --git a/TaikoLocalServer/Controllers/Api/ChallengeCompeteManageController.cs b/TaikoLocalServer/Controllers/Api/ChallengeCompeteManageController.cs new file mode 100644 index 00000000..1887030c --- /dev/null +++ b/TaikoLocalServer/Controllers/Api/ChallengeCompeteManageController.cs @@ -0,0 +1,160 @@ +using MediatR; +using SharedProject.Models; +using SharedProject.Models.Responses; +using TaikoLocalServer.Filters; + +namespace TaikoLocalServer.Controllers.Api; + +[ApiController] +[Route("api/[controller]")] +public class ChallengeCompeteManageController(IChallengeCompeteService challengeCompeteService) : BaseController +{ + [HttpGet] + [ServiceFilter(typeof(AuthorizeIfRequiredAttribute))] + public async Task>> GetAllChallengeCompete() + { + List datum = await challengeCompeteService.GetAllChallengeCompete(); + List converted = new(); + foreach (var data in datum) + { + var challengeCompetition = Mappers.ChallengeCompeMappers.MapData(data); + challengeCompetition = await challengeCompeteService.FillData(challengeCompetition); + converted.Add(challengeCompetition); + } + + return Ok(converted); + } + + [HttpGet("queryPage")] + [ServiceFilter(typeof(AuthorizeIfRequiredAttribute))] + public async Task> GetChallengeCompePage([FromQuery] uint mode = 0, [FromQuery] uint baid = 0, [FromQuery] int inProgress = 0, [FromQuery] int page = 1, [FromQuery] int limit = 10, [FromQuery] string? searchTerm = null) + { + if (page < 1) + { + return BadRequest(new { Message = "Page number cannot be less than 1." }); + } + + if (limit > 200) + { + return BadRequest(new { Message = "Limit cannot be greater than 200." }); + } + + if (mode == 0) + { + return BadRequest(new { Message = "Invalid mode." }); + } + + ChallengeCompetitionResponse response = await challengeCompeteService.GetChallengeCompetePage((CompeteModeType)mode, baid, inProgress != 0, page, limit, searchTerm); + + return Ok(response); + } + + [HttpGet("comp/{compId}")] + [ServiceFilter(typeof(AuthorizeIfRequiredAttribute))] + public async Task> GetChallengeCompe(uint compId) + { + var data = await challengeCompeteService.GetFirstOrDefaultCompete(compId); + if (data == null) return BadRequest(new { Message = $"Compete(CompId={compId}) is Not Exist!"}); + var challengeCompetition = Mappers.ChallengeCompeMappers.MapData(data); + challengeCompetition = await challengeCompeteService.FillData(challengeCompetition); + + return Ok(challengeCompetition); + } + + [HttpGet("test/{mode}")] + [ServiceFilter(typeof(AuthorizeIfRequiredAttribute))] + public ActionResult> testCreateCompete(uint mode) + { + ChallengeCompeteCreateInfo info = new() + { + Name = "测试数据", + Desc = "测试数据描述", + CompeteMode = (CompeteModeType)mode, + MaxParticipant = 100, + LastFor = 365, + RequiredTitle = 0, + ShareType = ShareType.EveryOne, + CompeteTargetType = CompeteTargetType.EveryOne, + challengeCompeteSongs = [ + new() { + SongId = 1, + Difficulty = Difficulty.Oni, + RandomType = (int)RandomType.Messy + }, + new() { + SongId = 2, + Difficulty = Difficulty.Oni, + }, + new() { + SongId = 3, + Difficulty = Difficulty.Oni, + }, + ] + }; + challengeCompeteService.CreateCompete(1, info); + + return NoContent(); + } + + [HttpPost("createOfficialCompete")] + [ServiceFilter(typeof(AuthorizeIfRequiredAttribute))] + public async Task CreateCompete(ChallengeCompeteCreateInfo challengeCompeteInfo) + { + Logger.LogInformation("CreateOfficialCompete : {Request}", JsonFormatter.JsonSerialize(challengeCompeteInfo)); + + await challengeCompeteService.CreateCompete(0, challengeCompeteInfo); + + return Ok(); + } + + [HttpPost("{baid}/createCompete")] + [ServiceFilter(typeof(AuthorizeIfRequiredAttribute))] + public async Task CreateCompete(uint baid, ChallengeCompeteCreateInfo challengeCompeteInfo) + { + Logger.LogInformation("CreateCompete : {Request}", JsonFormatter.JsonSerialize(challengeCompeteInfo)); + await challengeCompeteService.CreateCompete(baid, challengeCompeteInfo); + + return Ok(); + } + + [HttpPost("{baid}/createChallenge/{targetBaid}")] + [ServiceFilter(typeof(AuthorizeIfRequiredAttribute))] + public async Task CreateChallenge(uint baid, uint targetBaid, ChallengeCompeteCreateInfo challengeCompeteInfo) + { + Logger.LogInformation("CreateChallenge : {Request}", JsonFormatter.JsonSerialize(challengeCompeteInfo)); + await challengeCompeteService.CreateChallenge(baid, targetBaid, challengeCompeteInfo); + + return Ok(); + } + + [HttpGet("{baid}/joinCompete/{compId}")] + [ServiceFilter(typeof(AuthorizeIfRequiredAttribute))] + public async Task> JoinCompete(uint baid, uint compId) + { + Logger.LogInformation($"JoinCompete {baid} {compId}"); + bool result = await challengeCompeteService.ParticipateCompete(compId, baid); + + return Ok(result); + } + + [HttpGet("{baid}/acceptChallenge/{compId}")] + [ServiceFilter(typeof(AuthorizeIfRequiredAttribute))] + public async Task> AcceptChallenge(uint baid, uint compId) + { + Logger.LogInformation($"AcceptChallenge {baid} {compId}"); + bool result = await challengeCompeteService.AnswerChallenge(compId, baid, true); + + return Ok(result); + } + + [HttpGet("{baid}/rejectChallenge/{compId}")] + [ServiceFilter(typeof(AuthorizeIfRequiredAttribute))] + public async Task> RejectChallenge(uint baid, uint compId) + { + Logger.LogInformation($"RejectChallenge {baid} {compId}"); + bool result = await challengeCompeteService.AnswerChallenge(compId, baid, false); + + return Ok(result); + } + +} \ No newline at end of file diff --git a/TaikoLocalServer/Controllers/Api/UsersController.cs b/TaikoLocalServer/Controllers/Api/UsersController.cs index dd2a4d33..2dce169d 100644 --- a/TaikoLocalServer/Controllers/Api/UsersController.cs +++ b/TaikoLocalServer/Controllers/Api/UsersController.cs @@ -88,4 +88,17 @@ public async Task DeleteUser(uint baid) return result ? NoContent() : NotFound(); } + + [HttpGet("{baid}/AllUserDict")] + [ServiceFilter(typeof(AuthorizeIfRequiredAttribute))] + public async Task AllUserDict(uint baid) + { + Dictionary data = await userDatumService.GetAllUserDict(); + if (baid != 0) + { + data.Remove(baid); + } + + return Ok(data); + } } \ No newline at end of file diff --git a/TaikoLocalServer/Controllers/Game/ChallengeCompetitionController.cs b/TaikoLocalServer/Controllers/Game/ChallengeCompetitionController.cs index 62a8f84c..b25fe6aa 100644 --- a/TaikoLocalServer/Controllers/Game/ChallengeCompetitionController.cs +++ b/TaikoLocalServer/Controllers/Game/ChallengeCompetitionController.cs @@ -3,31 +3,28 @@ [ApiController] public class ChallengeCompetitionController : BaseController { - [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 HandleChallenge([FromBody] ChallengeCompeRequest request) { Logger.LogInformation("ChallengeCompe request : {Request}", request.Stringify()); - var response = new ChallengeCompeResponse - { - Result = 1 - }; + CommonChallengeCompeResponse response = await Mediator.Send(new ChallengeCompeteQuery(request.Baid)); + var response_3906 = Mappers.ChallengeCompeMappers.MapTo3906(response); - return Ok(response); + return Ok(response_3906); } [HttpPost("/v12r00_cn/chassis/challengecompe.php")] [Produces("application/protobuf")] - public IActionResult HandleChallenge3209([FromBody] Models.v3209.ChallengeCompeRequest request) + public async Task HandleChallenge3209([FromBody] Models.v3209.ChallengeCompeRequest request) { Logger.LogInformation("ChallengeCompe request : {Request}", request.Stringify()); - var response = new Models.v3209.ChallengeCompeResponse - { - Result = 1 - }; + CommonChallengeCompeResponse response = await Mediator.Send(new ChallengeCompeteQuery((uint)request.Baid)); + var response_3209 = Mappers.ChallengeCompeMappers.MapTo3209(response); - return Ok(response); + return Ok(response_3209); } } \ No newline at end of file diff --git a/TaikoLocalServer/Handlers/ChallengeCompeteQuery.cs b/TaikoLocalServer/Handlers/ChallengeCompeteQuery.cs new file mode 100644 index 00000000..1b59c939 --- /dev/null +++ b/TaikoLocalServer/Handlers/ChallengeCompeteQuery.cs @@ -0,0 +1,73 @@ +using GameDatabase.Context; +using SharedProject.Utils; +using System.Buffers.Binary; + +namespace TaikoLocalServer.Handlers; + +public record ChallengeCompeteQuery(uint Baid) : IRequest; + +public class ChallengeCompeteQueryHandler(IChallengeCompeteService challengeCompeteService) + : IRequestHandler +{ + + public async Task Handle(ChallengeCompeteQuery request, CancellationToken cancellationToken) + { + List competes = await challengeCompeteService.GetInProgressChallengeCompete(request.Baid); + CommonChallengeCompeResponse response = new() + { + Result = 1 + }; + + foreach (var compete in competes) + { + CommonCompeData compeData = new() + { + CompeId = compete.CompId + }; + foreach (var song in compete.Songs) + { + var songOptions = new byte[2]; + short songOpt = PlaySettingConverter.PlaySettingToShort(new() + { + Speed = song.Speed != null ? (uint)song.Speed : 0, + IsVanishOn = song.IsVanishOn != null ? (bool)song.IsVanishOn : false, + IsInverseOn = song.IsInverseOn != null ? (bool)song.IsInverseOn : false, + RandomType = song.RandomType != null ? (RandomType)song.RandomType : RandomType.None, + }); + BinaryPrimitives.WriteInt16LittleEndian(songOptions, songOpt); + + uint myHighScore = 0; + foreach (var bestScore in song.BestScores) + { + if (bestScore.Baid == request.Baid) + { + myHighScore = bestScore.Score; + } + } + + CommonTracksData 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; + } +} diff --git a/TaikoLocalServer/Handlers/UpdatePlayResultCommand.cs b/TaikoLocalServer/Handlers/UpdatePlayResultCommand.cs index 1f89d184..68b5af73 100644 --- a/TaikoLocalServer/Handlers/UpdatePlayResultCommand.cs +++ b/TaikoLocalServer/Handlers/UpdatePlayResultCommand.cs @@ -5,7 +5,7 @@ namespace TaikoLocalServer.Handlers; public record UpdatePlayResultCommand(uint Baid, CommonPlayResultData PlayResultData) : IRequest; -public class UpdatePlayResultCommandHandler(TaikoDbContext context, ILogger logger) +public class UpdatePlayResultCommandHandler(TaikoDbContext context, IChallengeCompeteService challengeCompeteService, ILogger logger) : IRequestHandler { public async Task Handle(UpdatePlayResultCommand request, CancellationToken cancellationToken) @@ -116,6 +116,11 @@ public async Task Handle(UpdatePlayResultCommand request, CancellationToke Difficulty = (Difficulty)stageData.Level }; context.SongPlayData.Add(songPlayDatum); + + + byte[] option = stageData.OptionFlg; + short optionVal = (short)(option[0] + (option[1]) << 8); + await challengeCompeteService.UpdateBestScore(songPlayDatum.Baid, songPlayDatum, optionVal); } await context.SaveChangesAsync(cancellationToken); diff --git a/TaikoLocalServer/Handlers/UserDataQuery.cs b/TaikoLocalServer/Handlers/UserDataQuery.cs index 79723f6c..7ef75ce7 100644 --- a/TaikoLocalServer/Handlers/UserDataQuery.cs +++ b/TaikoLocalServer/Handlers/UserDataQuery.cs @@ -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; -public class UserDataQueryHandler(TaikoDbContext context, IGameDataService gameDataService, ILogger logger) +public class UserDataQueryHandler(TaikoDbContext context, IGameDataService gameDataService, IChallengeCompeteService challengeCompeteService, ILogger logger) : IRequestHandler { @@ -71,7 +72,9 @@ public async Task Handle(UserDataQuery request, Cancella difficultySettingArray[i] -= 1; } } - + + bool hasChallengeCompe = await challengeCompeteService.HasChallengeCompete(request.Baid); + var response = new CommonUserDataResponse { Result = 1, @@ -92,7 +95,7 @@ public async Task Handle(UserDataQuery request, Cancella DifficultyPlayedStar = userData.DifficultyPlayedStar, DifficultyPlayedSort = userData.DifficultyPlayedSort, SongRecentCnt = (uint)recentSongs.Length, - IsChallengecompe = false, + IsChallengecompe = hasChallengeCompe, // TODO: Other fields }; diff --git a/TaikoLocalServer/Mappers/ChallengeCompeMappers.cs b/TaikoLocalServer/Mappers/ChallengeCompeMappers.cs new file mode 100644 index 00000000..2b725917 --- /dev/null +++ b/TaikoLocalServer/Mappers/ChallengeCompeMappers.cs @@ -0,0 +1,12 @@ +using Riok.Mapperly.Abstractions; +using SharedProject.Models; + +namespace TaikoLocalServer.Mappers; + +[Mapper] +public static partial class ChallengeCompeMappers +{ + public static partial ChallengeCompeResponse MapTo3906(CommonChallengeCompeResponse response); + public static partial Models.v3209.ChallengeCompeResponse MapTo3209(CommonChallengeCompeResponse response); + public static partial ChallengeCompetition MapData(ChallengeCompeteDatum data); +} diff --git a/TaikoLocalServer/Models/Application/CommonChallengeCompeRequest.cs b/TaikoLocalServer/Models/Application/CommonChallengeCompeRequest.cs new file mode 100644 index 00000000..626da6f5 --- /dev/null +++ b/TaikoLocalServer/Models/Application/CommonChallengeCompeRequest.cs @@ -0,0 +1,8 @@ +namespace TaikoLocalServer.Models.Application; + +public class CommonChallengeCompeRequest +{ + public uint Baid { get; set; } + public string ChassisId { get; set; } = string.Empty; + public string ShopId { get; set; } = string.Empty; +} diff --git a/TaikoLocalServer/Models/Application/CommonChallengeCompeResponse.cs b/TaikoLocalServer/Models/Application/CommonChallengeCompeResponse.cs new file mode 100644 index 00000000..8d1ea226 --- /dev/null +++ b/TaikoLocalServer/Models/Application/CommonChallengeCompeResponse.cs @@ -0,0 +1,23 @@ +namespace TaikoLocalServer.Models.Application; + +public class CommonChallengeCompeResponse +{ + public uint Result { get; set; } + public List AryChallengeStats { get; set; } = []; + public List AryUserCompeStats { get; set; } = []; + public List AryBngCompeStats { get; set; } = []; +} + +public class CommonCompeData +{ + public uint CompeId { get; set; } + public List AryTrackStats { get; set; } = []; +} + +public class CommonTracksData +{ + public uint SongNo { get; set; } + public uint Level { get; set; } + public byte[] OptionFlg { get; set; } = []; + public uint HighScore { get; set; } +} \ No newline at end of file diff --git a/TaikoLocalServer/Models/ChallengeCompeteInfo.cs b/TaikoLocalServer/Models/ChallengeCompeteInfo.cs new file mode 100644 index 00000000..f32e3c38 --- /dev/null +++ b/TaikoLocalServer/Models/ChallengeCompeteInfo.cs @@ -0,0 +1,36 @@ +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("onlyPlayOnce")] + public bool OnlyPlayOnce { 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 challengeCompeteSongs { get; set; } = new(); +} diff --git a/TaikoLocalServer/Models/ChallengeCompeteSongInfo.cs b/TaikoLocalServer/Models/ChallengeCompeteSongInfo.cs new file mode 100644 index 00000000..546e11ee --- /dev/null +++ b/TaikoLocalServer/Models/ChallengeCompeteSongInfo.cs @@ -0,0 +1,24 @@ +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("speed")] + public uint? Speed { get; set; } = null; + + [JsonPropertyName("isVanishOn")] + public bool? IsVanishOn { get; set; } = null; + + [JsonPropertyName("isInverseOn")] + public bool? IsInverseOn { get; set; } = null; + + [JsonPropertyName("randomType")] + public RandomType? RandomType { get; set; } = null; +} diff --git a/TaikoLocalServer/Services/ChallengeCompeteService.cs b/TaikoLocalServer/Services/ChallengeCompeteService.cs new file mode 100644 index 00000000..9a085a1a --- /dev/null +++ b/TaikoLocalServer/Services/ChallengeCompeteService.cs @@ -0,0 +1,400 @@ + +using GameDatabase.Context; +using SharedProject.Models; +using SharedProject.Models.Responses; +using SharedProject.Utils; +using Throw; +using static Microsoft.EntityFrameworkCore.DbLoggerCategory; + +namespace TaikoLocalServer.Services; + +public class ChallengeCompeteService : IChallengeCompeteService +{ + private readonly TaikoDbContext context; + private readonly IGameDataService gameDataService; + private readonly IUserDatumService userDatumService; + + private Dictionary musicDetailDict; + public ChallengeCompeteService(TaikoDbContext context, IGameDataService gameDataService, IUserDatumService userDatumService) + { + this.context = context; + this.gameDataService = gameDataService; + this.userDatumService = userDatumService; + + this.musicDetailDict = gameDataService.GetMusicDetailDictionary(); + } + + public async Task HasChallengeCompete(uint baid) + { + return await context.ChallengeCompeteData + .Include(c => c.Participants) + .Include(c => c.Songs) + .ThenInclude(s => s.BestScores) + .AnyAsync(data => + data.State == CompeteState.Normal && + data.CreateTime < DateTime.Now && + data.ExpireTime > DateTime.Now && + data.Participants.Any(participant => participant.Baid == baid && participant.IsActive) && + ( + // Only Play Once need there is no Score for current Compete + !data.OnlyPlayOnce || data.Songs.Any(song => !song.BestScores.Any(s => s.Baid == baid)) + ) + ); + } + + public async Task> GetInProgressChallengeCompete(uint baid) + { + return await context.ChallengeCompeteData + .Include(c => c.Participants) + .Include(c => c.Songs) + .ThenInclude(s => s.BestScores) + .Where(data => + data.State == CompeteState.Normal && + data.CreateTime < DateTime.Now && + data.ExpireTime > DateTime.Now && + data.Participants.Any(participant => participant.Baid == baid && participant.IsActive) && + ( + // Only Play Once need there is no Score for current Compete + !data.OnlyPlayOnce || data.Songs.Any(song => !song.BestScores.Any(s => s.Baid == baid)) + ) + ).ToListAsync(); + } + + public async Task> GetAllChallengeCompete() + { + return await context.ChallengeCompeteData + .Include(c => c.Participants) + .Include(c => c.Songs) + .ThenInclude(s => s.BestScores) + .Where(data => true).ToListAsync(); + } + + public async Task GetChallengeCompetePage(CompeteModeType mode, uint baid, bool inProgress, int page, int limit, string? search) + { + IQueryable? query = null; + string? lowSearch = search != null ? search.ToLower() : null; + bool isAdmin = context.UserData.Where(u => u.Baid == baid).First().IsAdmin; + + if (mode == CompeteModeType.Chanllenge) + { + query = context.ChallengeCompeteData + .Include(e => e.Songs).ThenInclude(e => e.BestScores).Include(e => e.Participants) + .Where(e => e.CompeteMode == CompeteModeType.Chanllenge) + .Where(e => inProgress == false || (e.CreateTime < DateTime.Now && DateTime.Now < e.ExpireTime)) + .Where(e => isAdmin || (e.Baid == baid || e.Participants.Any(p => p.Baid == baid))) + .Where(e => lowSearch == null || (e.CompId.ToString() == lowSearch || e.CompeteName.ToLower().Contains(lowSearch))); + } + else if (mode == CompeteModeType.Compete) + { + query = context.ChallengeCompeteData + .Include(e => e.Songs).ThenInclude(e => e.BestScores).Include(e => e.Participants) + .Where(e => e.CompeteMode == CompeteModeType.Compete) + .Where(e => inProgress == false || (e.CreateTime < DateTime.Now && DateTime.Now < e.ExpireTime)) + .Where(e => isAdmin || (e.Baid == baid || e.Participants.Any(p => p.Baid == baid) || e.Share == ShareType.EveryOne)) + .Where(e => lowSearch == null || (e.CompId.ToString() == lowSearch || e.CompeteName.ToLower().Contains(lowSearch))); + } + else if (mode == CompeteModeType.OfficialCompete) + { + query = context.ChallengeCompeteData + .Include(e => e.Songs).ThenInclude(e => e.BestScores).Include(e => e.Participants) + .Where(e => e.CompeteMode == CompeteModeType.OfficialCompete) + .Where(e => inProgress == false || (e.CreateTime < DateTime.Now && DateTime.Now < e.ExpireTime)) + .Where(e => lowSearch == null || (e.CompId.ToString() == lowSearch || e.CompeteName.ToLower().Contains(lowSearch))); + } + if (query == null) return new ChallengeCompetitionResponse(); + + var total = await query.CountAsync(); + var totalPage = total / limit; + if (total % limit > 0) totalPage += 1; + + var challengeCompeteDatum= await query + .OrderBy(e => e.CompId).Skip((page - 1) * limit).Take(limit) + .ToListAsync(); + + List converted = new(); + foreach (var data in challengeCompeteDatum) + { + var challengeCompetition = Mappers.ChallengeCompeMappers.MapData(data); + challengeCompetition = await FillData(challengeCompetition); + converted.Add(challengeCompetition); + } + + return new ChallengeCompetitionResponse + { + List = converted, + Page = page, + TotalPages = totalPage, + Total = total + }; + } + + public Task GetFirstOrDefaultCompete(uint compId) + { + return context.ChallengeCompeteData + .Include(e => e.Songs).ThenInclude(e => e.BestScores).Include(e => e.Participants) + .Where(c => c.CompId == compId) + .FirstOrDefaultAsync(); + } + + public async Task CreateCompete(uint baid, ChallengeCompeteCreateInfo challengeCompeteInfo) + { + bool isAdmin = context.UserData.Where(u => u.Baid == baid).First().IsAdmin; + + ChallengeCompeteDatum challengeCompeteData = new() + { + CompId = context.ChallengeCompeteData.Any() ? context.ChallengeCompeteData.AsEnumerable().Max(c => c.CompId) + 1 : 1, + CompeteMode = challengeCompeteInfo.CompeteMode, + State = CompeteState.Normal, + Baid = baid, + CompeteName = challengeCompeteInfo.Name, + CompeteDescribe = challengeCompeteInfo.Desc, + MaxParticipant = challengeCompeteInfo.MaxParticipant, + OnlyPlayOnce = challengeCompeteInfo.OnlyPlayOnce, + 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, + Speed = song.Speed == -1 ? null : (uint)song.Speed, + IsInverseOn = song.IsInverseOn == -1 ? null : (song.IsInverseOn != 0), + IsVanishOn = song.IsVanishOn == -1 ? null : (song.IsVanishOn != 0), + RandomType = song.RandomType == -1 ? null : (RandomType)song.RandomType, + }; + await context.AddAsync(challengeCompeteSongData); + } + + if (!isAdmin){ + ChallengeCompeteParticipantDatum participantDatum = new() + { + CompId = challengeCompeteData.CompId, + Baid = baid, + IsActive = true + }; + await context.AddAsync(participantDatum); + } + + await context.SaveChangesAsync(); + + } + + public async Task ParticipateCompete(uint compId, uint baid) + { + var challengeCompete = await context.ChallengeCompeteData + .Include(c => c.Participants).Where(c => c.CompId == compId).FirstOrDefaultAsync(); + 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); + await context.SaveChangesAsync(); + + return true; + } + + public async Task CreateChallenge(uint baid, uint targetBaid, ChallengeCompeteCreateInfo challengeCompeteInfo) + { + ChallengeCompeteDatum challengeCompeteData = new() + { + CompId = context.ChallengeCompeteData.Any() ? context.ChallengeCompeteData.AsEnumerable().Max(c => c.CompId) + 1 : 1, + CompeteMode = CompeteModeType.Chanllenge, + State = CompeteState.Waiting, + Baid = baid, + CompeteName = challengeCompeteInfo.Name, + CompeteDescribe = challengeCompeteInfo.Desc, + MaxParticipant = 2, + OnlyPlayOnce = challengeCompeteInfo.OnlyPlayOnce, + 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, + Speed = song.Speed == -1 ? null : (uint)song.Speed, + IsInverseOn = song.IsInverseOn == -1 ? null : (song.IsInverseOn != 0), + IsVanishOn = song.IsVanishOn == -1 ? null : (song.IsVanishOn != 0), + RandomType = song.RandomType == -1 ? null : (RandomType)song.RandomType, + }; + 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); + await context.SaveChangesAsync(); + } + + public async Task AnswerChallenge(uint compId, uint baid, bool accept) + { + var challengeCompete = await context.ChallengeCompeteData + .Include(c => c.Participants).Where(c => c.CompId == compId).FirstOrDefaultAsync(); + challengeCompete.ThrowIfNull($"Challenge not found for CompId {compId}!"); + + if (challengeCompete.Baid == baid) return false; + if (!challengeCompete.Participants.Any(p => p.Baid == baid)) + { + return false; + } + + if (accept) + { + challengeCompete.State = CompeteState.Normal; + foreach (var participant in challengeCompete.Participants) + { + participant.IsActive = true; + context.Update(participant); + } + } + else + { + challengeCompete.State = CompeteState.Rejected; + } + context.Update(challengeCompete); + await context.SaveChangesAsync(); + + return true; + } + + public async Task UpdateBestScore(uint baid, SongPlayDatum playData, short option) + { + List challengeCompetes = context.ChallengeCompeteData + .Include(e => e.Songs) + .ThenInclude(s => s.BestScores) + .Include(e => e.Participants) + .Where(e => e.CreateTime < DateTime.Now && DateTime.Now < e.ExpireTime) + .Where(e => e.Participants.Any(d => d.Baid == baid && d.IsActive)) + .Where(e => e.Songs.Any(d => d.SongId == playData.SongId && d.Difficulty == playData.Difficulty)) + .Where(e => !e.OnlyPlayOnce || e.Songs.Any(song => !song.BestScores.Any(s => s.Baid == baid))) + .ToList(); + PlaySetting setting = PlaySettingConverter.ShortToPlaySetting(option); + foreach (var challengeCompete in challengeCompetes) + { + ChallengeCompeteSongDatum? song = challengeCompete.Songs.Find(e => e.SongId == playData.SongId && e.Difficulty == playData.Difficulty); + if (song == null) continue; + if (song.Speed != null && song.Speed != setting.Speed) continue; + if (song.IsVanishOn != null && song.IsVanishOn != setting.IsVanishOn) continue; + if (song.IsInverseOn != null && song.IsInverseOn != setting.IsInverseOn) continue; + if (song.RandomType != null && song.RandomType != setting.RandomType) continue; + + ChallengeCompeteBestDatum? bestScore = song.BestScores.Find(e => e.Baid == baid); + if (bestScore == null) + { + await context.AddAsync(new ChallengeCompeteBestDatum + { + CompId = song.CompId, + Baid = baid, + SongId = song.SongId, + Difficulty = song.Difficulty, + Crown = playData.Crown, + Score = playData.Score, + ScoreRate = playData.ScoreRate, + ScoreRank = playData.ScoreRank, + GoodCount = playData.GoodCount, + OkCount = playData.OkCount, + MissCount = playData.MissCount, + ComboCount = playData.ComboCount, + HitCount = playData.HitCount, + DrumrollCount = playData.DrumrollCount, + Skipped = playData.Skipped + }); + } + else if (!challengeCompete.OnlyPlayOnce && bestScore.Score < playData.Score) + { + bestScore.Crown = playData.Crown; + bestScore.Score = playData.Score; + bestScore.ScoreRate = playData.ScoreRate; + bestScore.ScoreRank = playData.ScoreRank; + bestScore.GoodCount = playData.GoodCount; + bestScore.OkCount = playData.OkCount; + bestScore.MissCount = playData.MissCount; + bestScore.ComboCount = playData.ComboCount; + bestScore.HitCount = playData.HitCount; + bestScore.DrumrollCount = playData.DrumrollCount; + bestScore.Skipped = playData.Skipped; + context.Update(bestScore); + } + } + await context.AddRangeAsync(); + } + + public async Task FillData(ChallengeCompetition challenge) + { + UserDatum? holder = await userDatumService.GetFirstUserDatumOrNull(challenge.Baid); + challenge.Holder = convert(holder); + foreach (var participant in challenge.Participants) + { + if (participant == null) continue; + UserDatum? user = await userDatumService.GetFirstUserDatumOrNull(participant.Baid); + participant.UserInfo = convert(user); + } + foreach (var song in challenge.Songs) + { + if (song == null) continue; + song.MusicDetail = musicDetailDict.GetValueOrDefault(song.SongId); + foreach (var score in song.BestScores) + { + UserDatum? user = await userDatumService.GetFirstUserDatumOrNull(score.Baid); + score.UserAppearance = convert(user); + } + } + + return challenge; + } + + private UserAppearance? convert(UserDatum? user) + { + if (user == null) return null; + return new UserAppearance + { + Baid = user.Baid, + MyDonName = user.MyDonName, + MyDonNameLanguage = user.MyDonNameLanguage, + Title = user.Title, + TitlePlateId = user.TitlePlateId, + Kigurumi = user.CurrentKigurumi, + Head = user.CurrentHead, + Body = user.CurrentBody, + Face = user.CurrentFace, + Puchi = user.CurrentPuchi, + FaceColor = user.ColorFace, + BodyColor = user.ColorBody, + LimbColor = user.ColorLimb, + }; + } +} diff --git a/TaikoLocalServer/Services/Extentions/ServiceExtensions.cs b/TaikoLocalServer/Services/Extentions/ServiceExtensions.cs index 578fbca2..f6f28132 100644 --- a/TaikoLocalServer/Services/Extentions/ServiceExtensions.cs +++ b/TaikoLocalServer/Services/Extentions/ServiceExtensions.cs @@ -9,6 +9,7 @@ public static IServiceCollection AddTaikoDbServices(this IServiceCollection serv services.AddScoped(); services.AddScoped(); services.AddScoped(); + services.AddScoped(); return services; } diff --git a/TaikoLocalServer/Services/Interfaces/IChallengeCompeteService.cs b/TaikoLocalServer/Services/Interfaces/IChallengeCompeteService.cs new file mode 100644 index 00000000..2a63ea56 --- /dev/null +++ b/TaikoLocalServer/Services/Interfaces/IChallengeCompeteService.cs @@ -0,0 +1,29 @@ +using SharedProject.Models; +using SharedProject.Models.Responses; + +namespace TaikoLocalServer.Services.Interfaces; + +public interface IChallengeCompeteService +{ + public Task HasChallengeCompete(uint baid); + + public Task> GetInProgressChallengeCompete(uint baid); + + public Task> GetAllChallengeCompete(); + + public Task GetChallengeCompetePage(CompeteModeType mode, uint baid, bool inProgress, int page, int limit, string? search); + + public Task GetFirstOrDefaultCompete(uint compId); + + public Task CreateCompete(uint baid, ChallengeCompeteCreateInfo challengeCompeteInfo); + + public Task ParticipateCompete(uint compId, uint baid); + + public Task CreateChallenge(uint baid, uint targetBaid, ChallengeCompeteCreateInfo challengeCompeteInfo); + + public Task AnswerChallenge(uint compId, uint baid, bool accept); + + public Task UpdateBestScore(uint baid, SongPlayDatum playData, short option); + + public Task FillData(ChallengeCompetition challenge); +} diff --git a/TaikoLocalServer/Services/Interfaces/IUserDatumService.cs b/TaikoLocalServer/Services/Interfaces/IUserDatumService.cs index e8b17859..fc07fd99 100644 --- a/TaikoLocalServer/Services/Interfaces/IUserDatumService.cs +++ b/TaikoLocalServer/Services/Interfaces/IUserDatumService.cs @@ -1,9 +1,13 @@ -namespace TaikoLocalServer.Services.Interfaces; +using SharedProject.Models; + +namespace TaikoLocalServer.Services.Interfaces; public interface IUserDatumService { public Task> GetAllUserDatum(); - + + public Task> GetAllUserDict(); + public Task GetFirstUserDatumOrNull(uint baid); public Task UpdateUserDatum(UserDatum userDatum); diff --git a/TaikoLocalServer/Services/UserDatumService.cs b/TaikoLocalServer/Services/UserDatumService.cs index d2211ee2..8f0ce9b8 100644 --- a/TaikoLocalServer/Services/UserDatumService.cs +++ b/TaikoLocalServer/Services/UserDatumService.cs @@ -1,5 +1,7 @@ using GameDatabase.Context; using Throw; +using SharedProject.Models; +using MudExtensions; namespace TaikoLocalServer.Services; @@ -9,6 +11,46 @@ public async Task> GetAllUserDatum() { return await context.UserData.Include(d => d.Tokens).ToListAsync(); } + + public async Task> GetAllUserDict() + { + List listUser = await GetAllUserDatum(); + Dictionary dict = new Dictionary(); + foreach (var user in listUser) + { + dict.Add(user.Baid, new() + { + Baid = user.Baid, + IsAdmin = false, + UserSetting = new() + { + Baid = user.Baid, + ToneId = user.SelectedToneId, + IsDisplayAchievement = user.DisplayAchievement, + IsDisplayDanOnNamePlate = user.DisplayDan, + DifficultySettingCourse = user.DifficultySettingCourse, + DifficultySettingStar = user.DifficultyPlayedStar, + DifficultySettingSort = user.DifficultyPlayedSort, + IsVoiceOn = user.IsVoiceOn, + IsSkipOn = user.IsSkipOn, + AchievementDisplayDifficulty = user.AchievementDisplayDifficulty, + MyDonName = user.MyDonName, + MyDonNameLanguage = user.MyDonNameLanguage, + Title = user.Title, + TitlePlateId = user.TitlePlateId, + Kigurumi = user.CurrentKigurumi, + Head = user.CurrentHead, + Body = user.CurrentBody, + Face = user.CurrentFace, + Puchi = user.CurrentPuchi, + FaceColor = user.ColorFace, + BodyColor = user.ColorFace, + LimbColor = user.ColorLimb + } + }); + } + return dict; + } public async Task GetFirstUserDatumOrNull(uint baid) { diff --git a/TaikoLocalServer/TaikoLocalServer.csproj b/TaikoLocalServer/TaikoLocalServer.csproj index b112262c..6a26cf42 100644 --- a/TaikoLocalServer/TaikoLocalServer.csproj +++ b/TaikoLocalServer/TaikoLocalServer.csproj @@ -28,34 +28,36 @@ - + + + - - - - - - - + + + + + + + all runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - - - - - - - - - + + + + + + + + + + + + + @@ -65,26 +67,26 @@ PreserveNewest - + PreserveNewest PreserveNewest - + PreserveNewest - + PreserveNewest - + PreserveNewest - + PreserveNewest @@ -199,8 +201,8 @@ - - - + + + diff --git a/TaikoWebUI/Components/ChallengeCompe.razor b/TaikoWebUI/Components/ChallengeCompe.razor new file mode 100644 index 00000000..724f3502 --- /dev/null +++ b/TaikoWebUI/Components/ChallengeCompe.razor @@ -0,0 +1,129 @@ +@using Blazored.LocalStorage + +@inject HttpClient Client +@inject AuthService AuthService +@inject IDialogService DialogService; +@inject IGameDataService GameDataService +@inject ILocalStorageService LocalStorage + +@if (ChallengeCompetition != null) +{ + + + + + @if (ChallengeCompetition.CompeteMode == CompeteModeType.Chanllenge) + { + if (AuthService.IsAdmin) + { + @FormatChallengeTitle(Localizer["FullChallengeTitle"]) + } + else if (ChallengeCompetition?.Baid != Baid) + { + + @FormatChallengeTitle(Localizer["ReceiverChallengeTitle"]) + } + else + { + + @FormatChallengeTitle(Localizer["CreatorChallengeTitle"]) + } + } + else + { + @ChallengeCompetition?.CompeteName + } + + + @Localizer["Comp ID"]: @ChallengeCompetition?.CompId + @Localizer["Describe"]: @ChallengeCompetition?.CompeteDescribe + + + @if (false && ChallengeCompetition?.Baid == Baid || AuthService.IsAdmin) + { + + } + + + + + @{ + foreach (var song in ChallengeCompetition.Songs) + { + @if (MusicDetailDictionary != null && song.MusicDetail!= null){ +
+ + @GameDataService.GetMusicNameBySongId(MusicDetailDictionary, song.MusicDetail.SongId, SongNameLanguage)@(song.BestScores.Any(bs => bs.Baid == Baid) ? (" (" + Localizer["Played"] + ")") : "") + +
+ } + } + } +
+ + + AnswerChallenge(true))>@Localizer["Information"] + @if (ChallengeCompetition.ExpireTime < DateTime.Now) + { + @Localizer["Finished"] + } + else if (ChallengeCompetition.CompeteMode == CompeteModeType.Chanllenge) + { + var targeted = true; + if (ChallengeCompetition?.Participants.Find(u => u.Baid == Baid) == null) targeted = false; + //The above is used for admins only: If you are the target of a challenge, you should be able to accept or reject it + if (ChallengeCompetition?.Baid == Baid || ChallengeCompetition?.State != CompeteState.Waiting || (!targeted && AuthService.IsAdmin)) + { + switch (ChallengeCompetition?.State) + { + case CompeteState.Waiting: + @Localizer["Waiting"] + break; + case CompeteState.Normal: + @Localizer["Accepted"] + break; + case CompeteState.Rejected: + @Localizer["Rejected"] + break; + } + } + else + { + + AnswerChallenge(true))>@Localizer["Accept"] + AnswerChallenge(false))>@Localizer["Reject"] + + // The buttons are disabled on (AuthService.IsAdmin && !targeted) which means "You are admin and you're not a target of the challenge" + // This should never happen as you should instead see the buttons from the switch statement above ! + } + } + else if (ChallengeCompetition.CompeteMode == CompeteModeType.Compete || ChallengeCompetition.CompeteMode == CompeteModeType.OfficialCompete) + { + if (!AuthService.IsAdmin) + { + if (ChallengeCompetition.Participants.Any(p => p.Baid == Baid)) + { + @Localizer["Participated"] + } + else + { + if (ChallengeCompetition.MaxParticipant <= ChallengeCompetition.Participants.Count) + { + @Localizer["Fulfilled"] + } + else + { + @Localizer["Participate"] + } + } + } else + { + @ChallengeCompetition.Participants.Count / @ChallengeCompetition.MaxParticipant + } + } + + +
+} \ No newline at end of file diff --git a/TaikoWebUI/Components/ChallengeCompe.razor.cs b/TaikoWebUI/Components/ChallengeCompe.razor.cs new file mode 100644 index 00000000..33b20125 --- /dev/null +++ b/TaikoWebUI/Components/ChallengeCompe.razor.cs @@ -0,0 +1,91 @@ +using TaikoWebUI.Pages.Dialogs; +namespace TaikoWebUI.Components; + +public partial class ChallengeCompe +{ + [Parameter] public ChallengeCompetition? ChallengeCompetition { get; set; } + [Parameter] public int Baid { get; set; } + [Parameter] public EventCallback Refresh { get; set; } + [Parameter] public Dictionary? MusicDetailDictionary { get; set; } = null; + [Parameter] public string? SongNameLanguage { get; set; } = null; + + protected override async Task OnInitializedAsync() + { + base.OnInitialized(); + SongNameLanguage ??= await LocalStorage.GetItemAsync("songNameLanguage"); + MusicDetailDictionary ??= await GameDataService.GetMusicDetailDictionary(); + } + + private string GetSongInfo(ChallengeCompetitionSong song) + { + MusicDetailDictionary.ThrowIfNull(); + song.MusicDetail.ThrowIfNull(); + + var songName = GameDataService.GetMusicNameBySongId(MusicDetailDictionary, song.MusicDetail.SongId, SongNameLanguage); + if (song.BestScores.Any(bs => bs.Baid == Baid)) + { + return songName + " (" + Localizer["Played"] + ")"; + } + return songName; + } + + private bool SelfHoldedChallengeCompetiton() + { + return ChallengeCompetition?.Baid == Baid || AuthService.IsAdmin; + } + + private bool ChallengeNeedAnswer() + { + return !AuthService.IsAdmin && ChallengeCompetition?.State == CompeteState.Waiting && ChallengeCompetition?.Baid != Baid; + } + + private bool ParticipatedChallengeCompetition() + { + return ChallengeCompetition?.Participants?.Find(p => p.Baid == Baid) != null; + } + + private bool CanParticipateChallengeCompetition() + { + return ChallengeCompetition?.CreateTime < DateTime.Now && DateTime.Now < ChallengeCompetition?.ExpireTime && !ParticipatedChallengeCompetition(); + } + + private string FormatChallengeTitle(string template) + { + return template + .Replace("{From}", ChallengeCompetition?.Holder?.MyDonName) + .Replace("{To}", ChallengeCompetition?.Participants?.Find(p => p.Baid != ChallengeCompetition?.Baid)?.UserInfo?.MyDonName); + } + + private async Task AnswerChallenge(bool accept) + { + if (ChallengeCompetition == null || ChallengeCompetition.State != CompeteState.Waiting) return; + var url = accept ? $"api/ChallengeCompeteManage/{Baid}/acceptChallenge/{ChallengeCompetition.CompId}" : $"api/ChallengeCompeteManage/{Baid}/rejectChallenge/{ChallengeCompetition.CompId}"; + var response = await Client.GetAsync(url); + if (!response.IsSuccessStatusCode) + { + await DialogService.ShowMessageBox( + Localizer["Error"], + Localizer["Request Error"], + Localizer["Dialog OK"], null, null, new DialogOptions { DisableBackdropClick = true }); + return; + } + await Refresh.InvokeAsync(ChallengeCompetition); + + ChallengeCompetition.State = accept ? CompeteState.Normal : CompeteState.Rejected; + } + + private async Task AnswerCompete() + { + if (ChallengeCompetition == null) return; + var response = await Client.GetAsync($"api/ChallengeCompeteManage/{Baid}/joinCompete/{ChallengeCompetition.CompId}"); + if (!response.IsSuccessStatusCode) + { + await DialogService.ShowMessageBox( + Localizer["Error"], + Localizer["Request Error"], + Localizer["Dialog OK"], null, null, new DialogOptions { DisableBackdropClick = true }); + return; + } + await Refresh.InvokeAsync(ChallengeCompetition); + } +} \ No newline at end of file diff --git a/TaikoWebUI/Components/ChallengeCompeteGrid.razor b/TaikoWebUI/Components/ChallengeCompeteGrid.razor new file mode 100644 index 00000000..be89aae5 --- /dev/null +++ b/TaikoWebUI/Components/ChallengeCompeteGrid.razor @@ -0,0 +1,105 @@ +@using Blazored.LocalStorage + +@inject HttpClient Client +@inject AuthService AuthService +@inject IDialogService DialogService; +@inject IGameDataService GameDataService +@inject ILocalStorageService LocalStorage +@inject NavigationManager NavigationManager +@inject BreadcrumbsStateContainer BreadcrumbsStateContainer + + + @if (!AuthService.LoginRequired || (AuthService.LoginRequired)) + { + +
+ + + @if (Mode == 1) + { + OpenDialogAsync(1, 1)) Style="width: 80px">@Localizer["Add"] + } + else if (Mode == 2) + { + OpenDialogAsync(2, 3)) Style="width: 80px">@Localizer["Add"] + } + else if ((Mode == 3 && AuthService.IsAdmin) || !AuthService.LoginRequired) + { + OpenDialogAsync(3, 5, 365, 100)) Style="width: 80px">@Localizer["Add"] + } + +
+
+ @if (isLoading || response == null) + { + // Loading... + for (uint i = 0; i < pageSize; i++) + { + + + + + + + + + + + + + + + + } + } + else if (response.List.Count > 0) + { + foreach (var challengeCompetition in response.List) + { + + + + } + } + else + { // No users in the database + + + @Localizer["No Data"] + + + } + } + else if (AuthService.LoginRequired && !AuthService.IsLoggedIn) + { + // Not logged in, redirect + NavigationManager.NavigateTo("/Login"); + } + else + { + NavigationManager.NavigateTo("/"); + } + + @if (response != null && TotalPages > 1) + { + +
+ +
+
+ } +
diff --git a/TaikoWebUI/Components/ChallengeCompeteGrid.razor.cs b/TaikoWebUI/Components/ChallengeCompeteGrid.razor.cs new file mode 100644 index 00000000..d8247b9e --- /dev/null +++ b/TaikoWebUI/Components/ChallengeCompeteGrid.razor.cs @@ -0,0 +1,117 @@ +using TaikoWebUI.Pages.Dialogs; +namespace TaikoWebUI.Components; + +public partial class ChallengeCompeteGrid +{ + [Parameter] public int Baid { get; set; } + [Parameter] public int Mode { get; set; } + [Parameter] public Dictionary? MusicDetailDictionary { get; set; } = null; + [Parameter] public string? SongNameLanguage { get; set; } = null; + + private ChallengeCompetitionResponse? response = new(); + private CancellationTokenSource? cts; + private int TotalPages { get; set; } = 0; + private bool isLoading = true; + private int currentPage = 1; + private readonly int pageSize = 12; + private string? searchTerm = null; + private bool inProgress = false; + + private async Task GetChallengeCompetitionData() + { + isLoading = true; + + response = await Client.GetFromJsonAsync($"api/ChallengeCompeteManage/queryPage?mode={(uint)Mode}&baid={Baid}&inProgress={(inProgress ? 1 : 0)}&page={currentPage}&limit={pageSize}&searchTerm={searchTerm}"); + response.ThrowIfNull(); + + TotalPages = response.TotalPages; + isLoading = false; + } + + private async Task UpdateCompete(ChallengeCompetition cc) + { + await GetChallengeCompetitionData(); + var updated = response?.List.Find(c => c.CompId == cc.CompId); + if (updated != null) + { + cc.CompeteMode = updated.CompeteMode; + cc.Participants = updated.Participants; + } + } + + protected override async Task OnInitializedAsync() + { + await base.OnInitializedAsync(); + SongNameLanguage ??= await LocalStorage.GetItemAsync("songNameLanguage"); + MusicDetailDictionary ??= await GameDataService.GetMusicDetailDictionary(); + + if (AuthService.LoginRequired && !AuthService.IsLoggedIn) + { + await AuthService.LoginWithAuthToken(); + } + + await GetChallengeCompetitionData(); + + + BreadcrumbsStateContainer.breadcrumbs.Clear(); + BreadcrumbsStateContainer.breadcrumbs.Add(new BreadcrumbItem((Mode == 1 ? Localizer["Challenge"] : Mode == 2 ? Localizer["Competition"] : Localizer["Official Competition"]), href: $"/ChallengeCompe/{Baid}/" + (Mode == 1 ? "Challenge" : Mode == 2 ? "Competition" : "OfficialCompetition"))); + BreadcrumbsStateContainer.NotifyStateChanged(); + } + + private async Task OnPageChange(int page) + { + currentPage = page; + await GetChallengeCompetitionData(); + } + + private async Task Debounce(Func action, int delayInMilliseconds) + { + // Cancel the previous task + cts?.Cancel(); + + // Create a new CancellationTokenSource + cts = new CancellationTokenSource(); + + try + { + // Wait for the delay + await Task.Delay(delayInMilliseconds, cts.Token); + + // Execute the action + await action(); + } + catch (TaskCanceledException) + { + // Ignore the exception + } + } + + private async Task OnSearch(string search) + { + searchTerm = search; + currentPage = 1; + + // Debounce the GetUsersData method + await Debounce(GetChallengeCompetitionData, 500); // 500 milliseconds delay + } + + private async Task OpenDialogAsync(int mode, int maxSongs, int maxDays = 30, int maxParticipant = 20) + { + var options = new DialogOptions { CloseOnEscapeKey = true }; + var parameters = new DialogParameters + { + { "Mode", mode }, + { "MaxSongs", maxSongs }, + { "MaxDays", maxDays }, + { "MaxParticipant", maxParticipant }, + { "Baid", Baid } + }; + + var dialogRet = await DialogService.ShowAsync(Localizer["Create"], parameters, options); + if (dialogRet != null) + { + var result = await dialogRet.GetReturnValueAsync(); + if (result != null && result == true) await GetChallengeCompetitionData(); + } + } +} \ No newline at end of file diff --git a/TaikoWebUI/Components/LanguageToggle.razor b/TaikoWebUI/Components/LanguageToggle.razor index 0862fe0c..d53abed4 100644 --- a/TaikoWebUI/Components/LanguageToggle.razor +++ b/TaikoWebUI/Components/LanguageToggle.razor @@ -16,7 +16,10 @@ @Localizer["Song List"] @foreach (var culture in supportedCultures) { - @culture.Value + @if (culture.Key.Name != "fr-FR") //We do not add an entry for French song names as the game's wordlist has no fields for this. + { + @culture.Value + } } diff --git a/TaikoWebUI/Components/NavMenu.razor b/TaikoWebUI/Components/NavMenu.razor index ce2e3fe7..f2a4797f 100644 --- a/TaikoWebUI/Components/NavMenu.razor +++ b/TaikoWebUI/Components/NavMenu.razor @@ -24,24 +24,34 @@ { @Localizer["Profile"] - + @Localizer["Song List"] @Localizer["High Scores"] @Localizer["Play History"] @Localizer["Dani Dojo"] + } + + if (AuthService.IsLoggedIn || !AuthService.LoginRequired) + { + + @Localizer["Challenge"] + @Localizer["Competition"] + @Localizer["Official Competition"] + + } + + if (AuthService.IsLoggedIn) + { @Localizer["Show QR Code"] @Localizer["Change Password"] @Localizer["Access Codes"] - } - if (AuthService.IsLoggedIn) - { @Localizer["Log Out"] - } + } } diff --git a/TaikoWebUI/Components/UserCard.razor b/TaikoWebUI/Components/UserCard.razor index 76510164..308946ed 100644 --- a/TaikoWebUI/Components/UserCard.razor +++ b/TaikoWebUI/Components/UserCard.razor @@ -39,7 +39,7 @@ @Localizer["Access Codes"] @@ -73,6 +73,18 @@ } + + @Localizer["Challenge"] + + + + @Localizer["Competition"] + + + + @Localizer["Official Competition"] + + @if (AuthService.AllowUserDelete) { + /// Recherche une chaîne localisée semblable à . + /// + internal static string Accept { + get { + return ResourceManager.GetString("Accept", resourceCulture); + } + } + + /// + /// Recherche une chaîne localisée semblable à . + /// + internal static string Accepted { + get { + return ResourceManager.GetString("Accepted", resourceCulture); + } + } + /// /// Recherche une chaîne localisée semblable à . /// @@ -339,6 +357,15 @@ internal static string And { } } + /// + /// Recherche une chaîne localisée semblable à . + /// + internal static string Any { + get { + return ResourceManager.GetString("Any", resourceCulture); + } + } + /// /// Recherche une chaîne localisée semblable à . /// @@ -369,673 +396,1114 @@ internal static string Best_Rank { /// /// Recherche une chaîne localisée semblable à . /// - internal static string Cancel { + internal static string Best_Score { get { - return ResourceManager.GetString("Cancel", resourceCulture); + return ResourceManager.GetString("Best Score", resourceCulture); } } /// /// Recherche une chaîne localisée semblable à . /// - internal static string Change_Password_Different_Confirm_Password_Error { + internal static string Body { get { - return ResourceManager.GetString("Change Password Different Confirm Password Error", resourceCulture); + return ResourceManager.GetString("Body", resourceCulture); } } /// /// Recherche une chaîne localisée semblable à . /// - internal static string Change_Password_Success { + internal static string Body_Color { get { - return ResourceManager.GetString("Change Password Success", resourceCulture); + return ResourceManager.GetString("Body Color", resourceCulture); } } /// /// Recherche une chaîne localisée semblable à . /// - internal static string Change_Password_Wrong_Current_Password_Error { + internal static string Cancel { get { - return ResourceManager.GetString("Change Password Wrong Current Password Error", resourceCulture); + return ResourceManager.GetString("Cancel", resourceCulture); } } /// /// Recherche une chaîne localisée semblable à . /// - internal static string Chinese_Simplified { + internal static string Challenge { get { - return ResourceManager.GetString("Chinese Simplified", resourceCulture); + return ResourceManager.GetString("Challenge", resourceCulture); } } /// /// Recherche une chaîne localisée semblable à . /// - internal static string Chinese_Traditional { + internal static string Challenge_Competition_Data { get { - return ResourceManager.GetString("Chinese Traditional", resourceCulture); + return ResourceManager.GetString("Challenge Competition Data", resourceCulture); } } /// /// Recherche une chaîne localisée semblable à . /// - internal static string Chojin { + internal static string Challenge_Target { get { - return ResourceManager.GetString("Chojin", resourceCulture); + return ResourceManager.GetString("Challenge Target", resourceCulture); } } /// /// Recherche une chaîne localisée semblable à . /// - internal static string Clapping { + internal static string Change_Password { get { - return ResourceManager.GetString("Clapping", resourceCulture); + return ResourceManager.GetString("Change Password", resourceCulture); } } /// /// Recherche une chaîne localisée semblable à . /// - internal static string Confirm_New_Password { + internal static string Change_Password_Different_Confirm_Password_Error { get { - return ResourceManager.GetString("Confirm New Password", resourceCulture); + return ResourceManager.GetString("Change Password Different Confirm Password Error", resourceCulture); } } /// /// Recherche une chaîne localisée semblable à . /// - internal static string Confirm_Password { + internal static string Change_Password_Success { get { - return ResourceManager.GetString("Confirm Password", resourceCulture); + return ResourceManager.GetString("Change Password Success", resourceCulture); } } /// /// Recherche une chaîne localisée semblable à . /// - internal static string Confirm_Password_is_Required { + internal static string Change_Password_Wrong_Current_Password_Error { get { - return ResourceManager.GetString("Confirm Password is Required", resourceCulture); + return ResourceManager.GetString("Change Password Wrong Current Password Error", resourceCulture); } } /// /// Recherche une chaîne localisée semblable à . /// - internal static string Conga { + internal static string Chinese_Simplified { get { - return ResourceManager.GetString("Conga", resourceCulture); + return ResourceManager.GetString("Chinese Simplified", resourceCulture); } } /// /// Recherche une chaîne localisée semblable à . /// - internal static string Copy_to_Clipboard { + internal static string Chinese_Traditional { get { - return ResourceManager.GetString("Copy to Clipboard", resourceCulture); + return ResourceManager.GetString("Chinese Traditional", resourceCulture); } } /// /// Recherche une chaîne localisée semblable à . /// - internal static string Course_Songs { + internal static string Chojin { get { - return ResourceManager.GetString("Course Songs", resourceCulture); + return ResourceManager.GetString("Chojin", resourceCulture); } } /// /// Recherche une chaîne localisée semblable à . /// - internal static string Currently_Selected_ { + internal static string Clapping { get { - return ResourceManager.GetString("Currently Selected:", resourceCulture); + return ResourceManager.GetString("Clapping", resourceCulture); } } /// /// Recherche une chaîne localisée semblable à . /// - internal static string Dani_Dojo { + internal static string Comp_ID { get { - return ResourceManager.GetString("Dani Dojo", resourceCulture); + return ResourceManager.GetString("Comp ID", resourceCulture); } } /// /// Recherche une chaîne localisée semblable à . /// - internal static string Dashboard { + internal static string Competition { get { - return ResourceManager.GetString("Dashboard", resourceCulture); + return ResourceManager.GetString("Competition", resourceCulture); } } /// - /// Recherche une chaîne localisée semblable à MM/dd/yyyy h:mm:ss tt. + /// Recherche une chaîne localisée semblable à . /// - internal static string DateFormat { + internal static string Conditions { get { - return ResourceManager.GetString("DateFormat", resourceCulture); + return ResourceManager.GetString("Conditions", resourceCulture); } } /// /// Recherche une chaîne localisée semblable à . /// - internal static string Default { + internal static string Confirm_New_Password { get { - return ResourceManager.GetString("Default", resourceCulture); + return ResourceManager.GetString("Confirm New Password", resourceCulture); } } /// /// Recherche une chaîne localisée semblable à . /// - internal static string Delete { + internal static string Confirm_Password { get { - return ResourceManager.GetString("Delete", resourceCulture); + return ResourceManager.GetString("Confirm Password", resourceCulture); } } /// /// Recherche une chaîne localisée semblable à . /// - internal static string Delete_User_Confirm { + internal static string Confirm_Password_is_Required { get { - return ResourceManager.GetString("Delete User Confirm", resourceCulture); + return ResourceManager.GetString("Confirm Password is Required", resourceCulture); } } /// /// Recherche une chaîne localisée semblable à . /// - internal static string Delete_User_Success { + internal static string Conga { get { - return ResourceManager.GetString("Delete User Success", resourceCulture); + return ResourceManager.GetString("Conga", resourceCulture); } } /// /// Recherche une chaîne localisée semblable à . /// - internal static string Dialog_OK { + internal static string Copy_to_Clipboard { get { - return ResourceManager.GetString("Dialog OK", resourceCulture); + return ResourceManager.GetString("Copy to Clipboard", resourceCulture); } } /// /// Recherche une chaîne localisée semblable à . /// - internal static string Difficulty { + internal static string Costume { get { - return ResourceManager.GetString("Difficulty", resourceCulture); + return ResourceManager.GetString("Costume", resourceCulture); } } /// /// Recherche une chaîne localisée semblable à . /// - internal static string Drum { + internal static string Costume_Options { get { - return ResourceManager.GetString("Drum", resourceCulture); + return ResourceManager.GetString("Costume Options", resourceCulture); } } /// /// Recherche une chaîne localisée semblable à . /// - internal static string Easy { + internal static string Course_Songs { get { - return ResourceManager.GetString("Easy", resourceCulture); + return ResourceManager.GetString("Course Songs", resourceCulture); } } /// /// Recherche une chaîne localisée semblable à . /// - internal static string Edit_Profile { + internal static string Create { get { - return ResourceManager.GetString("Edit Profile", resourceCulture); + return ResourceManager.GetString("Create", resourceCulture); } } /// /// Recherche une chaîne localisée semblable à . /// - internal static string Eighth_Dan { + internal static string Create_Challenge { get { - return ResourceManager.GetString("Eighth Dan", resourceCulture); + return ResourceManager.GetString("Create Challenge", resourceCulture); } } /// /// Recherche une chaîne localisée semblable à . /// - internal static string Electric_Guitar { + internal static string Create_Competition { get { - return ResourceManager.GetString("Electric Guitar", resourceCulture); + return ResourceManager.GetString("Create Competition", resourceCulture); } } /// /// Recherche une chaîne localisée semblable à . /// - internal static string English { + internal static string Create_Official_Competition { get { - return ResourceManager.GetString("English", resourceCulture); + return ResourceManager.GetString("Create Official Competition", resourceCulture); } } /// /// Recherche une chaîne localisée semblable à . /// - internal static string Error { + internal static string CreatorChallengeTitle { get { - return ResourceManager.GetString("Error", resourceCulture); + return ResourceManager.GetString("CreatorChallengeTitle", resourceCulture); } } /// /// Recherche une chaîne localisée semblable à . /// - internal static string Fifth_Dan { + internal static string Crown { get { - return ResourceManager.GetString("Fifth Dan", resourceCulture); + return ResourceManager.GetString("Crown", resourceCulture); } } /// /// Recherche une chaîne localisée semblable à . /// - internal static string Fifth_Kyuu { + internal static string Currently_Selected_ { get { - return ResourceManager.GetString("Fifth Kyuu", resourceCulture); + return ResourceManager.GetString("Currently Selected:", resourceCulture); } } /// /// Recherche une chaîne localisée semblable à . /// - internal static string Filter_by_Genre { + internal static string Dani_Dojo { get { - return ResourceManager.GetString("Filter by Genre", resourceCulture); + return ResourceManager.GetString("Dani Dojo", resourceCulture); } } /// /// Recherche une chaîne localisée semblable à . /// - internal static string First_Dan { + internal static string Dashboard { get { - return ResourceManager.GetString("First Dan", resourceCulture); + return ResourceManager.GetString("Dashboard", resourceCulture); } } /// - /// Recherche une chaîne localisée semblable à . + /// Recherche une chaîne localisée semblable à MM/dd/yyyy h:mm:ss tt. /// - internal static string First_Kyuu { + internal static string DateFormat { get { - return ResourceManager.GetString("First Kyuu", resourceCulture); + return ResourceManager.GetString("DateFormat", resourceCulture); } } /// /// Recherche une chaîne localisée semblable à . /// - internal static string Fourth_Dan { + internal static string Default { get { - return ResourceManager.GetString("Fourth Dan", resourceCulture); + return ResourceManager.GetString("Default", resourceCulture); } } /// /// Recherche une chaîne localisée semblable à . /// - internal static string Fourth_Kyuu { + internal static string Delete { get { - return ResourceManager.GetString("Fourth Kyuu", resourceCulture); + return ResourceManager.GetString("Delete", resourceCulture); } } /// /// Recherche une chaîne localisée semblable à . /// - internal static string Funassyi { + internal static string Delete_User { get { - return ResourceManager.GetString("Funassyi", resourceCulture); + return ResourceManager.GetString("Delete User", resourceCulture); } } /// /// Recherche une chaîne localisée semblable à . /// - internal static string Gaiden { + internal static string Delete_User_Confirm { get { - return ResourceManager.GetString("Gaiden", resourceCulture); + return ResourceManager.GetString("Delete User Confirm", resourceCulture); } } /// /// Recherche une chaîne localisée semblable à . /// - internal static string Generate_Invite_Code { + internal static string Delete_User_Success { get { - return ResourceManager.GetString("Generate Invite Code", resourceCulture); + return ResourceManager.GetString("Delete User Success", resourceCulture); } } /// /// Recherche une chaîne localisée semblable à . /// - internal static string Gold_Donderful_Combo { + internal static string Describe { get { - return ResourceManager.GetString("Gold Donderful Combo", resourceCulture); + return ResourceManager.GetString("Describe", resourceCulture); } } /// /// Recherche une chaîne localisée semblable à . /// - internal static string Gold_Full_Combo { + internal static string Details { get { - return ResourceManager.GetString("Gold Full Combo", resourceCulture); + return ResourceManager.GetString("Details", resourceCulture); } } /// /// Recherche une chaîne localisée semblable à . /// - internal static string Hard { + internal static string Dialog_OK { get { - return ResourceManager.GetString("Hard", resourceCulture); + return ResourceManager.GetString("Dialog OK", resourceCulture); } } /// /// Recherche une chaîne localisée semblable à . /// - internal static string High_Scores { + internal static string Difficulty { get { - return ResourceManager.GetString("High Scores", resourceCulture); + return ResourceManager.GetString("Difficulty", resourceCulture); } } /// /// Recherche une chaîne localisée semblable à . /// - internal static string ID { + internal static string Difficulty_Setting_Course { get { - return ResourceManager.GetString("ID", resourceCulture); + return ResourceManager.GetString("Difficulty Setting Course", resourceCulture); } } /// /// Recherche une chaîne localisée semblable à . /// - internal static string Inuneko { + internal static string Difficulty_Setting_Sort { get { - return ResourceManager.GetString("Inuneko", resourceCulture); + return ResourceManager.GetString("Difficulty Setting Sort", resourceCulture); } } /// /// Recherche une chaîne localisée semblable à . /// - internal static string Invite_Code { + internal static string Difficulty_Setting_Star { get { - return ResourceManager.GetString("Invite Code", resourceCulture); + return ResourceManager.GetString("Difficulty Setting Star", resourceCulture); } } /// /// Recherche une chaîne localisée semblable à . /// - internal static string Isogai { + internal static string Display_Achievement_Panel { get { - return ResourceManager.GetString("Isogai", resourceCulture); + return ResourceManager.GetString("Display Achievement Panel", resourceCulture); } } /// /// Recherche une chaîne localisée semblable à . /// - internal static string Japanese { + internal static string Display_Dan_Rank_on_Name_Plate { get { - return ResourceManager.GetString("Japanese", resourceCulture); + return ResourceManager.GetString("Display Dan Rank on Name Plate", resourceCulture); } } /// /// Recherche une chaîne localisée semblable à . /// - internal static string Korean { + internal static string Drum { get { - return ResourceManager.GetString("Korean", resourceCulture); + return ResourceManager.GetString("Drum", resourceCulture); } } /// /// Recherche une chaîne localisée semblable à . /// - internal static string Kuroto { + internal static string Drumroll { get { - return ResourceManager.GetString("Kuroto", resourceCulture); + return ResourceManager.GetString("Drumroll", resourceCulture); } } /// /// Recherche une chaîne localisée semblable à . /// - internal static string Last_Play_Date { + internal static string Easy { get { - return ResourceManager.GetString("Last Play Date", resourceCulture); + return ResourceManager.GetString("Easy", resourceCulture); } } /// /// Recherche une chaîne localisée semblable à . /// - internal static string Last_Play_Time_5_Min_Around_Credit_End_ { + internal static string Edit_Profile { get { - return ResourceManager.GetString("Last Play Time(5 Min Around Credit End)", resourceCulture); + return ResourceManager.GetString("Edit Profile", resourceCulture); } } /// /// Recherche une chaîne localisée semblable à . /// - internal static string Leaderboard { + internal static string Eighth_Dan { get { - return ResourceManager.GetString("Leaderboard", resourceCulture); + return ResourceManager.GetString("Eighth Dan", resourceCulture); } } /// /// Recherche une chaîne localisée semblable à . /// - internal static string Log_In { + internal static string Electric_Guitar { get { - return ResourceManager.GetString("Log In", resourceCulture); + return ResourceManager.GetString("Electric Guitar", resourceCulture); } } /// /// Recherche une chaîne localisée semblable à . /// - internal static string Log_In_First { + internal static string English { get { - return ResourceManager.GetString("Log In First", resourceCulture); + return ResourceManager.GetString("English", resourceCulture); } } /// /// Recherche une chaîne localisée semblable à . /// - internal static string Log_Out { + internal static string Error { get { - return ResourceManager.GetString("Log Out", resourceCulture); + return ResourceManager.GetString("Error", resourceCulture); } } /// /// Recherche une chaîne localisée semblable à . /// - internal static string Log_Out_Confirm { + internal static string Face { get { - return ResourceManager.GetString("Log Out Confirm", resourceCulture); + return ResourceManager.GetString("Face", resourceCulture); } } /// /// Recherche une chaîne localisée semblable à . /// - internal static string Login_Only_Admin_Error { + internal static string Face_Color { get { - return ResourceManager.GetString("Login Only Admin Error", resourceCulture); + return ResourceManager.GetString("Face Color", resourceCulture); } } /// /// Recherche une chaîne localisée semblable à . /// - internal static string Login_Wrong_Password_Error { + internal static string Fifth_Dan { get { - return ResourceManager.GetString("Login Wrong Password Error", resourceCulture); + return ResourceManager.GetString("Fifth Dan", resourceCulture); } } /// /// Recherche une chaîne localisée semblable à . /// - internal static string Matsuri { + internal static string Fifth_Kyuu { get { - return ResourceManager.GetString("Matsuri", resourceCulture); + return ResourceManager.GetString("Fifth Kyuu", resourceCulture); } } /// /// Recherche une chaîne localisée semblable à . /// - internal static string Meijin { + internal static string Filter_by_Genre { get { - return ResourceManager.GetString("Meijin", resourceCulture); + return ResourceManager.GetString("Filter by Genre", resourceCulture); } } /// /// Recherche une chaîne localisée semblable à . /// - internal static string Mekadon { + internal static string Finished { get { - return ResourceManager.GetString("Mekadon", resourceCulture); + return ResourceManager.GetString("Finished", resourceCulture); } } /// /// Recherche une chaîne localisée semblable à . /// - internal static string Messy { + internal static string First_Dan { get { - return ResourceManager.GetString("Messy", resourceCulture); + return ResourceManager.GetString("First Dan", resourceCulture); } } /// /// Recherche une chaîne localisée semblable à . /// - internal static string New_Access_Code { + internal static string First_Kyuu { get { - return ResourceManager.GetString("New Access Code", resourceCulture); + return ResourceManager.GetString("First Kyuu", resourceCulture); } } /// /// Recherche une chaîne localisée semblable à . /// - internal static string New_Password { + internal static string Fourth_Dan { get { - return ResourceManager.GetString("New Password", resourceCulture); + return ResourceManager.GetString("Fourth Dan", resourceCulture); } } /// /// Recherche une chaîne localisée semblable à . /// - internal static string Ninth_Dan { + internal static string Fourth_Kyuu { get { - return ResourceManager.GetString("Ninth Dan", resourceCulture); + return ResourceManager.GetString("Fourth Kyuu", resourceCulture); } } /// /// Recherche une chaîne localisée semblable à . /// - internal static string No_Data { + internal static string Fulfilled { get { - return ResourceManager.GetString("No Data", resourceCulture); + return ResourceManager.GetString("Fulfilled", resourceCulture); } } /// /// Recherche une chaîne localisée semblable à . /// - internal static string No_Play_History_Found { + internal static string FullChallengeTitle { get { - return ResourceManager.GetString("No Play History Found", resourceCulture); + return ResourceManager.GetString("FullChallengeTitle", resourceCulture); } } /// /// Recherche une chaîne localisée semblable à . /// - internal static string None { + internal static string Funassyi { get { - return ResourceManager.GetString("None", resourceCulture); + return ResourceManager.GetString("Funassyi", resourceCulture); } } /// /// Recherche une chaîne localisée semblable à . /// - internal static string Normal { + internal static string Gaiden { get { - return ResourceManager.GetString("Normal", resourceCulture); + return ResourceManager.GetString("Gaiden", resourceCulture); } } /// /// Recherche une chaîne localisée semblable à . /// - internal static string Not_Cleared { + internal static string Generate_Invite_Code { get { - return ResourceManager.GetString("Not Cleared", resourceCulture); + return ResourceManager.GetString("Generate Invite Code", resourceCulture); } } /// /// Recherche une chaîne localisée semblable à . /// - internal static string Not_Donderful_Combo { + internal static string Genre { get { - return ResourceManager.GetString("Not Donderful Combo", resourceCulture); + return ResourceManager.GetString("Genre", resourceCulture); } } /// /// Recherche une chaîne localisée semblable à . /// - internal static string Not_Full_Combo { + internal static string Gold { + get { + return ResourceManager.GetString("Gold", resourceCulture); + } + } + + /// + /// Recherche une chaîne localisée semblable à . + /// + internal static string Gold_Donderful_Combo { + get { + return ResourceManager.GetString("Gold Donderful Combo", resourceCulture); + } + } + + /// + /// Recherche une chaîne localisée semblable à . + /// + internal static string Gold_Full_Combo { + get { + return ResourceManager.GetString("Gold Full Combo", resourceCulture); + } + } + + /// + /// Recherche une chaîne localisée semblable à . + /// + internal static string Good { + get { + return ResourceManager.GetString("Good", resourceCulture); + } + } + + /// + /// Recherche une chaîne localisée semblable à . + /// + internal static string Hard { + get { + return ResourceManager.GetString("Hard", resourceCulture); + } + } + + /// + /// Recherche une chaîne localisée semblable à . + /// + internal static string Head { + get { + return ResourceManager.GetString("Head", resourceCulture); + } + } + + /// + /// Recherche une chaîne localisée semblable à . + /// + internal static string Hide { + get { + return ResourceManager.GetString("Hide", resourceCulture); + } + } + + /// + /// Recherche une chaîne localisée semblable à . + /// + internal static string High_Scores { + get { + return ResourceManager.GetString("High Scores", resourceCulture); + } + } + + /// + /// Recherche une chaîne localisée semblable à . + /// + internal static string ID { + get { + return ResourceManager.GetString("ID", resourceCulture); + } + } + + /// + /// Recherche une chaîne localisée semblable à . + /// + internal static string Information { + get { + return ResourceManager.GetString("Information", resourceCulture); + } + } + + /// + /// Recherche une chaîne localisée semblable à . + /// + internal static string Inuneko { + get { + return ResourceManager.GetString("Inuneko", resourceCulture); + } + } + + /// + /// Recherche une chaîne localisée semblable à . + /// + internal static string Inverse { + get { + return ResourceManager.GetString("Inverse", resourceCulture); + } + } + + /// + /// Recherche une chaîne localisée semblable à . + /// + internal static string Invite_Code { + get { + return ResourceManager.GetString("Invite Code", resourceCulture); + } + } + + /// + /// Recherche une chaîne localisée semblable à . + /// + internal static string Isogai { + get { + return ResourceManager.GetString("Isogai", resourceCulture); + } + } + + /// + /// Recherche une chaîne localisée semblable à . + /// + internal static string Japanese { + get { + return ResourceManager.GetString("Japanese", resourceCulture); + } + } + + /// + /// Recherche une chaîne localisée semblable à . + /// + internal static string Kigurumi { + get { + return ResourceManager.GetString("Kigurumi", resourceCulture); + } + } + + /// + /// Recherche une chaîne localisée semblable à . + /// + internal static string Korean { + get { + return ResourceManager.GetString("Korean", resourceCulture); + } + } + + /// + /// Recherche une chaîne localisée semblable à . + /// + internal static string Kuroto { + get { + return ResourceManager.GetString("Kuroto", resourceCulture); + } + } + + /// + /// Recherche une chaîne localisée semblable à . + /// + internal static string Language { + get { + return ResourceManager.GetString("Language", resourceCulture); + } + } + + /// + /// Recherche une chaîne localisée semblable à . + /// + internal static string Last_For__Days_ { + get { + return ResourceManager.GetString("Last For (Days)", resourceCulture); + } + } + + /// + /// Recherche une chaîne localisée semblable à . + /// + internal static string Last_Play_Date { + get { + return ResourceManager.GetString("Last Play Date", resourceCulture); + } + } + + /// + /// Recherche une chaîne localisée semblable à . + /// + internal static string Last_Play_Time_5_Min_Around_Credit_End_ { + get { + return ResourceManager.GetString("Last Play Time(5 Min Around Credit End)", resourceCulture); + } + } + + /// + /// Recherche une chaîne localisée semblable à . + /// + internal static string Last_Played { + get { + return ResourceManager.GetString("Last Played", resourceCulture); + } + } + + /// + /// Recherche une chaîne localisée semblable à . + /// + internal static string Leaderboard { + get { + return ResourceManager.GetString("Leaderboard", resourceCulture); + } + } + + /// + /// Recherche une chaîne localisée semblable à . + /// + internal static string Level { + get { + return ResourceManager.GetString("Level", resourceCulture); + } + } + + /// + /// Recherche une chaîne localisée semblable à . + /// + internal static string Limb_Color { + get { + return ResourceManager.GetString("Limb Color", resourceCulture); + } + } + + /// + /// Recherche une chaîne localisée semblable à . + /// + internal static string Log_In { + get { + return ResourceManager.GetString("Log In", resourceCulture); + } + } + + /// + /// Recherche une chaîne localisée semblable à . + /// + internal static string Log_In_First { + get { + return ResourceManager.GetString("Log In First", resourceCulture); + } + } + + /// + /// Recherche une chaîne localisée semblable à . + /// + internal static string Log_Out { + get { + return ResourceManager.GetString("Log Out", resourceCulture); + } + } + + /// + /// Recherche une chaîne localisée semblable à . + /// + internal static string Log_Out_Confirm { + get { + return ResourceManager.GetString("Log Out Confirm", resourceCulture); + } + } + + /// + /// Recherche une chaîne localisée semblable à . + /// + internal static string Login_Only_Admin_Error { + get { + return ResourceManager.GetString("Login Only Admin Error", resourceCulture); + } + } + + /// + /// Recherche une chaîne localisée semblable à . + /// + internal static string Login_Wrong_Password_Error { + get { + return ResourceManager.GetString("Login Wrong Password Error", resourceCulture); + } + } + + /// + /// Recherche une chaîne localisée semblable à . + /// + internal static string Matsuri { + get { + return ResourceManager.GetString("Matsuri", resourceCulture); + } + } + + /// + /// Recherche une chaîne localisée semblable à . + /// + internal static string MAX_Combo { + get { + return ResourceManager.GetString("MAX Combo", resourceCulture); + } + } + + /// + /// Recherche une chaîne localisée semblable à . + /// + internal static string Max_Participant { + get { + return ResourceManager.GetString("Max Participant", resourceCulture); + } + } + + /// + /// Recherche une chaîne localisée semblable à . + /// + internal static string Meijin { + get { + return ResourceManager.GetString("Meijin", resourceCulture); + } + } + + /// + /// Recherche une chaîne localisée semblable à . + /// + internal static string Mekadon { + get { + return ResourceManager.GetString("Mekadon", resourceCulture); + } + } + + /// + /// Recherche une chaîne localisée semblable à . + /// + internal static string Messy { + get { + return ResourceManager.GetString("Messy", resourceCulture); + } + } + + /// + /// Recherche une chaîne localisée semblable à . + /// + internal static string Name { + get { + return ResourceManager.GetString("Name", resourceCulture); + } + } + + /// + /// Recherche une chaîne localisée semblable à . + /// + internal static string New_Access_Code { + get { + return ResourceManager.GetString("New Access Code", resourceCulture); + } + } + + /// + /// Recherche une chaîne localisée semblable à . + /// + internal static string New_Password { + get { + return ResourceManager.GetString("New Password", resourceCulture); + } + } + + /// + /// Recherche une chaîne localisée semblable à . + /// + internal static string Ninth_Dan { + get { + return ResourceManager.GetString("Ninth Dan", resourceCulture); + } + } + + /// + /// Recherche une chaîne localisée semblable à . + /// + internal static string No_Data { + get { + return ResourceManager.GetString("No Data", resourceCulture); + } + } + + /// + /// Recherche une chaîne localisée semblable à . + /// + internal static string No_Play_History_Found { + get { + return ResourceManager.GetString("No Play History Found", resourceCulture); + } + } + + /// + /// Recherche une chaîne localisée semblable à . + /// + internal static string No_Select { + get { + return ResourceManager.GetString("No Select", resourceCulture); + } + } + + /// + /// Recherche une chaîne localisée semblable à . + /// + internal static string None { + get { + return ResourceManager.GetString("None", resourceCulture); + } + } + + /// + /// Recherche une chaîne localisée semblable à . + /// + internal static string Normal { + get { + return ResourceManager.GetString("Normal", resourceCulture); + } + } + + /// + /// Recherche une chaîne localisée semblable à . + /// + internal static string Not_Cleared { + get { + return ResourceManager.GetString("Not Cleared", resourceCulture); + } + } + + /// + /// Recherche une chaîne localisée semblable à . + /// + internal static string Not_Donderful_Combo { + get { + return ResourceManager.GetString("Not Donderful Combo", resourceCulture); + } + } + + /// + /// Recherche une chaîne localisée semblable à . + /// + internal static string Not_Full_Combo { get { return ResourceManager.GetString("Not Full Combo", resourceCulture); } @@ -1044,126 +1512,270 @@ internal static string Not_Full_Combo { /// /// Recherche une chaîne localisée semblable à . /// - internal static string Not_Logged_In_Error { + internal static string Not_Logged_In_Error { + get { + return ResourceManager.GetString("Not Logged In Error", resourceCulture); + } + } + + /// + /// Recherche une chaîne localisée semblable à . + /// + internal static string Not_Passed { + get { + return ResourceManager.GetString("Not Passed", resourceCulture); + } + } + + /// + /// Recherche une chaîne localisée semblable à . + /// + internal static string Notes_Position { + get { + return ResourceManager.GetString("Notes Position", resourceCulture); + } + } + + /// + /// Recherche une chaîne localisée semblable à . + /// + internal static string Off { + get { + return ResourceManager.GetString("Off", resourceCulture); + } + } + + /// + /// Recherche une chaîne localisée semblable à . + /// + internal static string Official_Competition { + get { + return ResourceManager.GetString("Official Competition", resourceCulture); + } + } + + /// + /// Recherche une chaîne localisée semblable à . + /// + internal static string OK { + get { + return ResourceManager.GetString("OK", resourceCulture); + } + } + + /// + /// Recherche une chaîne localisée semblable à . + /// + internal static string Old_Password { + get { + return ResourceManager.GetString("Old Password", resourceCulture); + } + } + + /// + /// Recherche une chaîne localisée semblable à . + /// + internal static string On { + get { + return ResourceManager.GetString("On", resourceCulture); + } + } + + /// + /// Recherche une chaîne localisée semblable à . + /// + internal static string Oni { + get { + return ResourceManager.GetString("Oni", resourceCulture); + } + } + + /// + /// Recherche une chaîne localisée semblable à . + /// + internal static string Only_Play_Once { + get { + return ResourceManager.GetString("Only Play Once", resourceCulture); + } + } + + /// + /// Recherche une chaîne localisée semblable à . + /// + internal static string other_access_code_s_ { + get { + return ResourceManager.GetString("other access code(s)", resourceCulture); + } + } + + /// + /// Recherche une chaîne localisée semblable à . + /// + internal static string Participate { + get { + return ResourceManager.GetString("Participate", resourceCulture); + } + } + + /// + /// Recherche une chaîne localisée semblable à . + /// + internal static string Participated { + get { + return ResourceManager.GetString("Participated", resourceCulture); + } + } + + /// + /// Recherche une chaîne localisée semblable à . + /// + internal static string Pass { + get { + return ResourceManager.GetString("Pass", resourceCulture); + } + } + + /// + /// Recherche une chaîne localisée semblable à . + /// + internal static string Password { + get { + return ResourceManager.GetString("Password", resourceCulture); + } + } + + /// + /// Recherche une chaîne localisée semblable à . + /// + internal static string Password_is_Required { get { - return ResourceManager.GetString("Not Logged In Error", resourceCulture); + return ResourceManager.GetString("Password is Required", resourceCulture); } } /// /// Recherche une chaîne localisée semblable à . /// - internal static string Not_Passed { + internal static string Play_Data { get { - return ResourceManager.GetString("Not Passed", resourceCulture); + return ResourceManager.GetString("Play Data", resourceCulture); } } /// /// Recherche une chaîne localisée semblable à . /// - internal static string Old_Password { + internal static string Play_History { get { - return ResourceManager.GetString("Old Password", resourceCulture); + return ResourceManager.GetString("Play History", resourceCulture); } } /// /// Recherche une chaîne localisée semblable à . /// - internal static string Oni { + internal static string Play_Time { get { - return ResourceManager.GetString("Oni", resourceCulture); + return ResourceManager.GetString("Play Time", resourceCulture); } } /// /// Recherche une chaîne localisée semblable à . /// - internal static string other_access_code_s_ { + internal static string Player { get { - return ResourceManager.GetString("other access code(s)", resourceCulture); + return ResourceManager.GetString("Player", resourceCulture); } } /// /// Recherche une chaîne localisée semblable à . /// - internal static string Password { + internal static string Player_Titles { get { - return ResourceManager.GetString("Password", resourceCulture); + return ResourceManager.GetString("Player Titles", resourceCulture); } } /// /// Recherche une chaîne localisée semblable à . /// - internal static string Password_is_Required { + internal static string Profile { get { - return ResourceManager.GetString("Password is Required", resourceCulture); + return ResourceManager.GetString("Profile", resourceCulture); } } /// /// Recherche une chaîne localisée semblable à . /// - internal static string Play_Data { + internal static string Profile_Options { get { - return ResourceManager.GetString("Play Data", resourceCulture); + return ResourceManager.GetString("Profile Options", resourceCulture); } } /// /// Recherche une chaîne localisée semblable à . /// - internal static string Play_History { + internal static string Puchi { get { - return ResourceManager.GetString("Play History", resourceCulture); + return ResourceManager.GetString("Puchi", resourceCulture); } } /// /// Recherche une chaîne localisée semblable à . /// - internal static string Play_Time { + internal static string Puchipuchi { get { - return ResourceManager.GetString("Play Time", resourceCulture); + return ResourceManager.GetString("Puchipuchi", resourceCulture); } } /// /// Recherche une chaîne localisée semblable à . /// - internal static string Player_Titles { + internal static string QR_Code { get { - return ResourceManager.GetString("Player Titles", resourceCulture); + return ResourceManager.GetString("QR Code", resourceCulture); } } /// /// Recherche une chaîne localisée semblable à . /// - internal static string Puchipuchi { + internal static string Random { get { - return ResourceManager.GetString("Puchipuchi", resourceCulture); + return ResourceManager.GetString("Random", resourceCulture); } } /// /// Recherche une chaîne localisée semblable à . /// - internal static string QR_Code { + internal static string Rank { get { - return ResourceManager.GetString("QR Code", resourceCulture); + return ResourceManager.GetString("Rank", resourceCulture); } } /// /// Recherche une chaîne localisée semblable à . /// - internal static string Rank { + internal static string ReceiverChallengeTitle { get { - return ResourceManager.GetString("Rank", resourceCulture); + return ResourceManager.GetString("ReceiverChallengeTitle", resourceCulture); + } + } + + /// + /// Recherche une chaîne localisée semblable à . + /// + internal static string Red { + get { + return ResourceManager.GetString("Red", resourceCulture); } } @@ -1239,6 +1851,24 @@ internal static string Register_Wrong_Last_Play_Time_Error { } } + /// + /// Recherche une chaîne localisée semblable à . + /// + internal static string Reject { + get { + return ResourceManager.GetString("Reject", resourceCulture); + } + } + + /// + /// Recherche une chaîne localisée semblable à . + /// + internal static string Rejected { + get { + return ResourceManager.GetString("Rejected", resourceCulture); + } + } + /// /// Recherche une chaîne localisée semblable à . /// @@ -1248,6 +1878,15 @@ internal static string Reset { } } + /// + /// Recherche une chaîne localisée semblable à . + /// + internal static string Reset_Password { + get { + return ResourceManager.GetString("Reset Password", resourceCulture); + } + } + /// /// Recherche une chaîne localisée semblable à . /// @@ -1266,6 +1905,15 @@ internal static string Reset_Password_Confirm_2 { } } + /// + /// Recherche une chaîne localisée semblable à . + /// + internal static string Result { + get { + return ResourceManager.GetString("Result", resourceCulture); + } + } + /// /// Recherche une chaîne localisée semblable à . /// @@ -1275,6 +1923,24 @@ internal static string Rows_Per_Page_ { } } + /// + /// Recherche une chaîne localisée semblable à . + /// + internal static string Save { + get { + return ResourceManager.GetString("Save", resourceCulture); + } + } + + /// + /// Recherche une chaîne localisée semblable à . + /// + internal static string Score { + get { + return ResourceManager.GetString("Score", resourceCulture); + } + } + /// /// Recherche une chaîne localisée semblable à . /// @@ -1284,6 +1950,15 @@ internal static string Search { } } + /// + /// Recherche une chaîne localisée semblable à . + /// + internal static string Search_by_Name__Comp_ID { + get { + return ResourceManager.GetString("Search by Name, Comp ID", resourceCulture); + } + } + /// /// Recherche une chaîne localisée semblable à . /// @@ -1329,6 +2004,42 @@ internal static string Second_Kyuu { } } + /// + /// Recherche une chaîne localisée semblable à . + /// + internal static string Section_No_ { + get { + return ResourceManager.GetString("Section No.", resourceCulture); + } + } + + /// + /// Recherche une chaîne localisée semblable à . + /// + internal static string Select_a_Title { + get { + return ResourceManager.GetString("Select a Title", resourceCulture); + } + } + + /// + /// Recherche une chaîne localisée semblable à . + /// + internal static string Select_Song { + get { + return ResourceManager.GetString("Select Song", resourceCulture); + } + } + + /// + /// Recherche une chaîne localisée semblable à . + /// + internal static string Select_User { + get { + return ResourceManager.GetString("Select User", resourceCulture); + } + } + /// /// Recherche une chaîne localisée semblable à . /// @@ -1356,6 +2067,24 @@ internal static string Seventh_Dan { } } + /// + /// Recherche une chaîne localisée semblable à . + /// + internal static string Show { + get { + return ResourceManager.GetString("Show", resourceCulture); + } + } + + /// + /// Recherche une chaîne localisée semblable à . + /// + internal static string Show_QR_Code { + get { + return ResourceManager.GetString("Show QR Code", resourceCulture); + } + } + /// /// Recherche une chaîne localisée semblable à . /// @@ -1383,6 +2112,15 @@ internal static string Skip_Song { } } + /// + /// Recherche une chaîne localisée semblable à . + /// + internal static string Song { + get { + return ResourceManager.GetString("Song", resourceCulture); + } + } + /// /// Recherche une chaîne localisée semblable à . /// @@ -1410,6 +2148,15 @@ internal static string Song_Number { } } + /// + /// Recherche une chaîne localisée semblable à . + /// + internal static string Song_Options { + get { + return ResourceManager.GetString("Song Options", resourceCulture); + } + } + /// /// Recherche une chaîne localisée semblable à . /// @@ -1419,6 +2166,15 @@ internal static string Song_Title___Artist { } } + /// + /// Recherche une chaîne localisée semblable à . + /// + internal static string Soul_Gauge { + get { + return ResourceManager.GetString("Soul Gauge", resourceCulture); + } + } + /// /// Recherche une chaîne localisée semblable à . /// @@ -1428,6 +2184,24 @@ internal static string Soya { } } + /// + /// Recherche une chaîne localisée semblable à . + /// + internal static string Speed { + get { + return ResourceManager.GetString("Speed", resourceCulture); + } + } + + /// + /// Recherche une chaîne localisée semblable à . + /// + internal static string Stage { + get { + return ResourceManager.GetString("Stage", resourceCulture); + } + } + /// /// Recherche une chaîne localisée semblable à . /// @@ -1500,6 +2274,42 @@ internal static string Third_Kyuu { } } + /// + /// Recherche une chaîne localisée semblable à . + /// + internal static string Title { + get { + return ResourceManager.GetString("Title", resourceCulture); + } + } + + /// + /// Recherche une chaîne localisée semblable à . + /// + internal static string Title_Plate { + get { + return ResourceManager.GetString("Title Plate", resourceCulture); + } + } + + /// + /// Recherche une chaîne localisée semblable à . + /// + internal static string Tone { + get { + return ResourceManager.GetString("Tone", resourceCulture); + } + } + + /// + /// Recherche une chaîne localisée semblable à . + /// + internal static string Total_Clears { + get { + return ResourceManager.GetString("Total Clears", resourceCulture); + } + } + /// /// Recherche une chaîne localisée semblable à . /// @@ -1509,6 +2319,42 @@ internal static string Total_Credits_Played { } } + /// + /// Recherche une chaîne localisée semblable à . + /// + internal static string Total_Donderful_Combos { + get { + return ResourceManager.GetString("Total Donderful Combos", resourceCulture); + } + } + + /// + /// Recherche une chaîne localisée semblable à . + /// + internal static string Total_Full_Combos { + get { + return ResourceManager.GetString("Total Full Combos", resourceCulture); + } + } + + /// + /// Recherche une chaîne localisée semblable à . + /// + internal static string Total_Hits { + get { + return ResourceManager.GetString("Total Hits", resourceCulture); + } + } + + /// + /// Recherche une chaîne localisée semblable à . + /// + internal static string Totals { + get { + return ResourceManager.GetString("Totals", resourceCulture); + } + } + /// /// Recherche une chaîne localisée semblable à . /// @@ -1590,6 +2436,15 @@ internal static string Users { } } + /// + /// Recherche une chaîne localisée semblable à . + /// + internal static string Vanish { + get { + return ResourceManager.GetString("Vanish", resourceCulture); + } + } + /// /// Recherche une chaîne localisée semblable à . /// @@ -1599,6 +2454,15 @@ internal static string View_Play_Data { } } + /// + /// Recherche une chaîne localisée semblable à . + /// + internal static string Voice { + get { + return ResourceManager.GetString("Voice", resourceCulture); + } + } + /// /// Recherche une chaîne localisée semblable à . /// @@ -1608,6 +2472,15 @@ internal static string Wadadon { } } + /// + /// Recherche une chaîne localisée semblable à . + /// + internal static string Welcome_to_TaikoWebUI_ { + get { + return ResourceManager.GetString("Welcome to TaikoWebUI!", resourceCulture); + } + } + /// /// Recherche une chaîne localisée semblable à . /// diff --git a/TaikoWebUI/Localization/LocalizationResource.en-US.resx b/TaikoWebUI/Localization/LocalizationResource.en-US.resx index e9c2c413..c45f8439 100644 --- a/TaikoWebUI/Localization/LocalizationResource.en-US.resx +++ b/TaikoWebUI/Localization/LocalizationResource.en-US.resx @@ -1,839 +1,936 @@  - - - - + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, - PublicKeyToken=b77a5c561934e089 - - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, - PublicKeyToken=b77a5c561934e089 - - - - Dashboard - - - Users - - - Edit Profile - - - User - - - View Play Data - - - High Scores - - - Show QR Code - - - Manage Access Codes - - - Change Password - - - Reset Password - - - Delete User - - - Welcome to TaikoWebUI! - - - Song - - - Level - - - Genre - - - Best Score - - - Best Crown - - - Best Rank - - - Good - - - OK - - - Bad - - - Drumroll - - - MAX Combo - - - AI Battle Data - - - Last Played - - - Total Plays - - - Total Clears - - - Total Full Combos - - - Total Donderful Combos - - - Songs - - - Hide - - - Show - - - Section No. - - - Result - - - Score - - - Crown - - - No data - - - "Please log in by clicking on "Users" tab first. - - - Total Hits - - - Soul Gauge - - - Songs - - - Conditions - - - Red Clear - - - Gold - - - Not Passed - - - Pass - - - Totals - - - Details - - - Stage - - - Dani Dojo - - - Profile - - - Profile Options - - - Costume + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + MM/dd/yyyy h:mm:ss tt - - Costume Options + + Generate Invite Code - - Song Options + + Register - - Player + + Log In - + Achievement Panel - - Save - - - Language - - - Name - - - Title - - - Title Plate - - + Achievement Panel Difficulty - - Display Dan Rank on Name Plate - - - Display Achievement Panel - - - Difficulty Setting Course - - - Difficulty Setting Star - - - Difficulty Setting Sort - - - Select a Title - - - Head - - - Body - - - Face - - - Kigurumi - - - Puchi - - - Body Color - - - Face Color - - - Limb Color - - - Vanish - - - Inverse - - - Skip Song - - - Voice - - - Speed - - - Random - - - Tone - - - Notes Position - - - Are you sure you want to reset the password for this user? - - - This will remove the user's current password and user will have to register again. - - - MM/dd/yyyy h:mm:ss tt + + AI Battle Data - - Generate Invite Code + + Bad - - Register + + Best Crown - - Log In + + Best Rank - + Log Out - + Play Data - + + High Scores + + + Manage Access Codes + + Add Access Code - + New Access Code - + Delete - + Access Code - + Old Password - + New Password - + Confirm New Password - + OK - + QR Code - - Chojin + + 5th Kyuu - - Eighth Dan + + 4th Kyuu - - 5th Dan + + 3rd Kyuu - - 5th Kyuu + + 2nd Kyuu + + + 1st Kyuu - + 1st Dan - - 1st Kyuu + + 2nd Dan - + + 3rd Dan + + 4th Dan - - 4th Kyuu + + 5th Dan - - Gaiden + + 6th Dan - - Kuroto + + 7th Dan - - Meijin + + Eighth Dan - + 9th Dan - - 2nd Dan + + 10th Dan - - 2nd Kyuu + + Kuroto - - 7th Dan + + Meijin - - 6th Dan + + Chojin - + Tatsujin - - 10th Dan - - - 3rd Dan - - - 3rd Kyuu + + Gaiden - + Gold Full Combo - - Red Donderful Combo - - + Red Full Combo - + + Red Donderful Combo + + Gold Donderful Combo - + + Songs + + + "Please log in by clicking on "Users" tab first. + + + Dani Dojo + + + Songs + + + Song + + Song Title / Artist - + Search by Title or Artist - + Filter by Genre - + Play History - + No play history found - + Password - + Settings - + Play Time - + Rank - + Difficulty - + Song Number - + Search by Title, Artist or Date - + + Users + + + Dashboard + + Unregister - + and - + other Access Code(s) - + Copy to Clipboard - + Invite Code - + Error - + + View Play Data + + + Not Passed + + + User + + Access Code is required - + "Invite Code (Optional)" - + Last Play Date - + Last Play Time(5 Min Around Credit End) - + Password is required - + Confirm Password - + Confirm password is required - + Unknown Error - + Success - + Ura - + Extreme - + Hard - + Normal - + Easy - + Rows Per Page: - + + Total Plays + + UI - + Add - + New access code bound successfully. - + Not logged in.<br />Please log in first and try again. - + Bound access code upper limit reached.<br />Please delete one access code first. - + This access code has already been bound. - + Access code cannot be empty.<br />Please enter a valid access code. - + This action is not allowed.<br />Only admin will be able to edit another user's access code. - + Only admin can log in. - + Password changed successfully. - + Confirm new password is different from new password.<br />Please check again. - + Unknown access code.<br />Please play one game with this access code and try again. - + Current password is wrong.<br />Please check again. - + Access code not registered.<br />Please register first and try again. - + Wrong password.<br />Please check again. - + Only admin can register. - + Access code registered successfully. - + Confirm password is not the same as password.<br />Please check again. - + Access code is already registered.<br />Please use set password to login. - + Wrong last play time.<br />If you have forgotten when you last played, please play another game with this access code or contact admin. - + Cancel - + Cannot delete user's last access code. - + Access code deleted successfully. - + ID - + + Edit Profile + + Are you sure you want to delete this access code? - + Currently Selected: - + Reset - + + Are you sure you want to reset the password for this user? + + + This will remove the user's current password and user will have to register again. + + Do you really want to delete this user's data?<br />All the related data will be deleted and this process cannot be undone! - + User deleted successfully. - + + Skip Song + + Off - + Whimsical - + Messy - + Taiko - + Festival - + Dogs & Cats - + Deluxe Taiko - + Drumset - + Tambourine - + Wadadon - + Clapping - + Conga - + 8-bit Taiko - + Heave-ho - + Mecha Don - + Funassyi - + Rap - + Hosogai - + Akemi - + Synth Drum - + Shuriken - + Bubble Pop - + Electric Guitar - + Ura - + Set Up Each Time - + Default - + Not Cleared - + Not Full Combo - + Not Donderful Combo - + Japanese - + English - + Chinese Traditional - + Korean - + Chinese Simplified - + ★ 1 - - ★ 10 - - + ★ 2 - + ★ 3 - + ★ 4 - + ★ 5 - + ★ 6 - + ★ 7 - + ★ 8 - + ★ 9 - + + ★ 10 + + Are you sure you want to log out? - + Leaderboard - + + No data + + User ID - + Search by Name, ID, or Access Code - - Player Titles - - - Search - + + Player Titles + + + Search + + + Show QR Code + + + Change Password + + + Reset Password + + + Delete User + + + Welcome to TaikoWebUI! + + + Level + + + Genre + + + Best Score + + + Good + + + OK + + + Drumroll + + + MAX Combo + + + Last Played + + + Total Clears + + + Total Full Combos + + + Total Donderful Combos + + + Hide + + + Show + + + Section No. + + + Result + + + Score + + + Crown + + + Total Hits + + + Soul Gauge + + + Conditions + + + Red Clear + + + Gold + + + Pass + + + Totals + + + Details + + + Stage + + + Profile + + + Profile Options + + + Costume + + + Costume Options + + + Song Options + + + Player + + + Save + + + Language + + + Name + + + Title + + + Title Plate + + + Display Dan Rank on Name Plate + + + Display Achievement Panel + + + Difficulty Setting Course + + + Difficulty Setting Star + + + Difficulty Setting Sort + + + Select a Title + + + Head + + + Body + + + Face + + + Kigurumi + + + Puchi + + + Body Color + + + Face Color + + + Limb Color + + + Vanish + + + Inverse + + + Voice + + + Speed + + + Random + + + Tone + + + Notes Position + + + Challenge + + + Competition + + + Official Competition + + + Comp ID + + + Search by Name, Comp ID + + + Comment + + + Participate + + + Accept + + + Reject + + + Information + + + Challenge Competition Data + + + Accepted + + + Rejected + + + Challenge User + + + Duration (days) + + + Song + + + Only Play Once + + + Limit Reached + + + Participated + + + Challenge from {From} to {To} + + + Challenge from {From} + + + Challenge to {To} + + + Create Challenge + + + Create Competition + + + Create Official Competition + + + Create + + + No Selected Song + + + Max Participant + + + Select a Song with Difficulty + + + Select Challenge Target User + + + Any + + + On + + + Off + + + Finished + \ No newline at end of file diff --git a/TaikoWebUI/Localization/LocalizationResource.fr-FR.resx b/TaikoWebUI/Localization/LocalizationResource.fr-FR.resx index 5bffda97..77d72ae3 100644 --- a/TaikoWebUI/Localization/LocalizationResource.fr-FR.resx +++ b/TaikoWebUI/Localization/LocalizationResource.fr-FR.resx @@ -117,257 +117,362 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - Tableau de bord + + dd/MM/yyyy h:mm:ss tt - - Utilisateurs + + Créer un code d'invitation - - Profil + + Inscription - - Utilisateur + + Connexion - - Données de jeu + + Tableau de reussite - - Meilleurs Scores + + Difficulté du tableau de réussite - - Afficher le Code QR + + Données du mode IA Battle - - Codes d'accès + + Bad - - Changer le mot de passe + + Meilleure couronne - - Réinitialiser le mot de passe + + Meilleur rank - - Supprimer l'utilisateur + + Déconnexion - - Bienvenue sur TaikoWebUI ! + + Données de jeu - - Musique + + Meilleurs Scores - - Niveau + + Codes d'accès - - Genre + + Ajouter un code d'accès - - Meilleur score + + Nouveau code d'accès - - Meilleure couronne + + Supprimer - - Meilleur rank + + Code d'accès - - Good + + Ancien mot de passe - - OK + + Nouveau mot de passe - - Bad + + Confirmer le nouveau mot de passe - - Drumroll + + OK - - Combo MAX + + Code QR - - Données du mode IA Battle + + 5ème Kyuu - - Joué la dernière fois + + 4ème Kyuu - - Nombre total de parties + + 3ème Kyuu - - Total Clears + + 2ème Kyuu - - Nombre total de Full Combos + + 1er Kyuu - - Nombre total de Combos Donderful + + 1er Dan - - Musiques + + 2ème Dan - - Cacher + + 3ème Dan - - Afficher + + 4ème Dan - - Numéro de section + + 5ème Dan - - Résultats + + 6ème Dan - - Score + + 7ème Dan - - Couronnes + + 8ème Dan - - Pas de données + + 9ème Dan - - Veuillez vous connecter en cliquant d'abord sur l'onglet “Utilisateurs”. + + 10ème Dan - - Total Hits + + Kuroto - - Jauge d'âme + + Meijin - - Musiques + + Chojin - - Conditions + + Tatsujin - - Red Clear + + Gaiden - - Gold + + Gold Full Combo - - Pas Clear + + Red Full Combo - - Pass + + Red Donderful Combo - - Totaux + + Gold Donderful Combo - - Details + + Musiques - - Stage + + Veuillez vous connecter en cliquant d'abord sur l'onglet “Utilisateurs”. Dani Dojo - - Profil + + Musiques - - Options de profil + + Musique - - Costume + + Titre / Artiste de la musique - - Options de costume + + Recherche par titre ou par artiste - - Options de jeu + + Filtrer par Genre - - Joueur + + Historique de jeu - - Tableau de reussite + + Aucun historique de jeu trouvé - - Sauvegarder + + Mot de passe - - Langue + + Paramètres - - Nom + + Date de jeu - - Titre + + Rank - - Décor de Plaque + + Difficulté - - Difficulté du tableau de réussite + + Chart ID - - Afficher le Dan sur la plaque + + Recherche par titre, artiste ou date - - Afficher le Tableau de Réussite + + Utilisateurs - - Mode recherche : Difficulté + + Tableau de bord - - Mode recherche : Etoiles + + Désinscription - - Mode recherche : Tri + + et - - Sélectionner un titre + + autre(s) code(s) d'accès - - Tête + + Copier dans le presse papier - - Corps + + Code d'invitation - - Visage + + Erreur - - Kigurumi + + Données de jeu - - Puchi + + Non validé - - Couleur du Corps + + Utilisateur - - Couleur du Visage + + Le code d'accès est requis - - Couleur des Membres + + "Code d'invitation (facultatif)" - - Disparition + + Date de dernière partie - - Inverser + + Joué la dernière fois (à 5 minutes près de la fin du crédit) - - Voix + + Mot de passe est requis - - Vitesse + + Confirmer le mot de passe - - Aléatoire + + Vous devez confirmer le mot de passe - - Son de tambour + + Erreur inconnue - - Position des notes + + Succès + + + Ura + + + Oni + + + Difficile + + + Normal + + + Facile + + + Rangées par page : + + + Nombre total de parties + + + UI + + + Ajouter + + + Nouveau code d'accès lié avec succès. + + + Vous n'êtes pas connecté.<br />Veuillez d'abord vous connecter et réessayer. + + + Le nombre maximal de code d'accès est atteint.<br />Veuillez d'abord supprimer un code d'accès. + + + Ce code d'accès a déjà été lié. + + + Le code d'accès ne peut pas être vide.<br />Veuillez saisir un code d'accès valide. + + + Cette action n'est pas autorisée.<br />Seuls les administrateur pouvent modifier le code d'accès d'un autre utilisateur. + + + Seuls les administrateurs peuvent se connecter. + + + Mot de passe changé ! + + + La confirmation du nouveau mot de passe est différent du nouveau mot de passe.<br />Veuillez réessayer. + + + Code d'accès inconnu.<br />Veuillez jouer une partie avec ce code d'accès et réessayer. + + + Le mot de passe actuel est erroné.<br />>Veuillez réessayer. + + + Code d'accès non enregistré.<br />Veuillez d'abord vous inscrire et réessayer. + + + Mot de passe erroné.<br />Vérifiez à nouveau. + + + Seuls les administrateurs peuvent s'inscrire. + + + Code d'accès enregistré avec succès. + + + Le mot de passe de confirmation est différent.<br />Veuillez réessayer. + + + Le code d'accès est déjà enregistré.<br />Veuillez utiliser le mot de passe défini pour vous connecter. + + + Mauvaise date de dernière partie.<br />Si vous avez oublié la date de votre derniere partie, veuillez en jouer une autre avec ce code d'accès ou contacter l'administrateur du serveur! + + + Annuler + + + Impossible de supprimer le dernier code d'accès de l'utilisateur. + + + Code d'accès supprimé avec succès. + + + ID + + + Profil + + + Êtes-vous sûr de vouloir supprimer ce code d'accès ? + + + Actuellement sélectionné : + + + Réinitialiser Êtes-vous sûr de vouloir réinitialiser le mot de passe de cet utilisateur ? @@ -375,460 +480,457 @@ Le mot de passe actuel de l'utilisateur sera alors supprimé et l'utilisateur devra s'inscrire à nouveau. - - dd/MM/yyyy h:mm:ss tt - - - Créer un code d'invitation - - - Inscription + + Voulez-vous vraiment supprimer les données de cet utilisateur ? <br />Toutes les données associées seront supprimées et ne pourront pas être récupérées ! - - Connexion + + Utilisateur supprimé. - - Déconnexion + + Passer la chanson - - Données de jeu + + Désactivé - - Ajouter un code d'accès + + Fantaisiste - - Nouveau code d'accès + + Désordonné - - Supprimer + + Taiko - - Code d'accès + + Festival - - Ancien mot de passe + + Chiens & Chats - - Nouveau mot de passe + + Taiko Deluxe - - Confirmer le nouveau mot de passe + + Tambour - - OK + + Tambourin - - Code QR + + Wadadon - - Chojin + + Applaudissements - - 8ème Dan + + Conga - - 5ème Dan + + Taiko 8 bits - - 5ème Kyuu + + Oh hisse - - 1er Dan + + Don Mecha - - 1er Kyuu + + Funassyi - - 4ème Dan + + Rap - - 4ème Kyuu + + Hosogai - - Gaiden + + Akemi - - Kuroto + + Tambour Synthétique - - Meijin + + Shuriken - - 9ème Dan + + Bubble Pop - - 2ème Dan + + Guitare électrique - - 2ème Kyuu + + Ura - - 7ème Dan + + Configurer à chaque fois - - 6ème Dan + + Défaut - - Tatsujin + + Pas Clear - - 10ème Dan + + Pas Full Combo - - 3ème Dan + + Pas Donderful Combo - - 3ème Kyuu + + Japonais - - Gold Full Combo + + Anglais - - Red Donderful Combo + + Chinois traditionnel - - Red Full Combo + + Coréen - - Gold Donderful Combo + + Chinois simplifié - - Titre / Artiste de la musique + + ★ 1 - - Recherche par titre ou par artiste + + ★ 2 - - Filtrer par Genre + + ★ 3 - - Historique de jeu + + ★ 4 - - Aucun historique de jeu trouvé + + ★ 5 - - Mot de passe + + ★ 6 - - Paramètres + + ★ 7 - - Date de jeu + + ★ 8 - - Rank + + ★ 9 - - Difficulté + + ★ 10 - - Chart ID + + Êtes-vous sûr de vouloir vous déconnecter ? - - Recherche par titre, artiste ou date + + Classement - - Désinscription + + Pas de données - - et + + ID de l'utilisateur - - autre(s) code(s) d'accès + + Recherche par nom, identifiant ou code d'accès - - Copier dans le presse papier + + Titres du joueur - - Code d'invitation + + Rechercher - - Erreur + + Afficher le Code QR - - Le code d'accès est requis + + Changer le mot de passe - - "Code d'invitation (facultatif)" + + Réinitialiser le mot de passe - - Date de dernière partie + + Supprimer l'utilisateur - - Joué la dernière fois (à 5 minutes près de la fin du crédit) + + Bienvenue sur TaikoWebUI ! - - Mot de passe est requis + + Niveau - - Confirmer le mot de passe + + Genre - - Vous devez confirmer le mot de passe + + Meilleur score - - Erreur inconnue + + Good - - Succès + + OK - - Ura + + Drumroll - - Oni + + Combo MAX - - Difficile + + Joué la dernière fois - - Normal + + Total Clears - - Facile + + Nombre total de Full Combos - - Rangées par page : + + Nombre total de Combos Donderful - - UI + + Cacher - - Ajouter + + Afficher - - Nouveau code d'accès lié avec succès. + + Numéro de section - - Vous n'êtes pas connecté.<br />Veuillez d'abord vous connecter et réessayer. + + Résultats - - Le nombre maximal de code d'accès est atteint.<br />Veuillez d'abord supprimer un code d'accès. + + Score - - Ce code d'accès a déjà été lié. + + Couronnes - - Le code d'accès ne peut pas être vide.<br />Veuillez saisir un code d'accès valide. + + Total Hits - - Cette action n'est pas autorisée.<br />Seuls les administrateur pouvent modifier le code d'accès d'un autre utilisateur. + + Jauge d'âme - - Seuls les administrateurs peuvent se connecter. + + Conditions - - Mot de passe changé ! + + Red Clear - - La confirmation du nouveau mot de passe est différent du nouveau mot de passe.<br />Veuillez réessayer. + + Gold - - Code d'accès inconnu.<br />Veuillez jouer une partie avec ce code d'accès et réessayer. + + Pass - - Le mot de passe actuel est erroné.<br />>Veuillez réessayer. + + Totaux - - Code d'accès non enregistré.<br />Veuillez d'abord vous inscrire et réessayer. + + Details - - Mot de passe erroné.<br />Vérifiez à nouveau. + + Stage - - Seuls les administrateurs peuvent s'inscrire. + + Profil - - Code d'accès enregistré avec succès. + + Options de profil - - Le mot de passe de confirmation est différent.<br />Veuillez réessayer. + + Costume - - Le code d'accès est déjà enregistré.<br />Veuillez utiliser le mot de passe défini pour vous connecter. + + Options de costume - - Mauvaise date de dernière partie.<br />Si vous avez oublié la date de votre derniere partie, veuillez en jouer une autre avec ce code d'accès ou contacter l'administrateur du serveur! + + Options de jeu - - Annuler + + Joueur - - Impossible de supprimer le dernier code d'accès de l'utilisateur. + + Sauvegarder - - Code d'accès supprimé avec succès. + + Langue - - ID + + Nom - - Êtes-vous sûr de vouloir supprimer ce code d'accès ? + + Titre - - Actuellement sélectionné : + + Décor de Plaque - - Réinitialiser + + Afficher le Dan sur la plaque - - Voulez-vous vraiment supprimer les données de cet utilisateur ? <br />Toutes les données associées seront supprimées et ne pourront pas être récupérées ! + + Afficher le Tableau de Réussite - - Utilisateur supprimé. + + Mode recherche : Difficulté - - ★ 1 + + Mode recherche : Etoiles - - ★ 2 + + Mode recherche : Tri - - ★ 3 + + Sélectionner un titre - - ★ 4 + + Tête - - ★ 5 + + Corps - - ★ 6 + + Visage - - ★ 7 + + Kigurumi - - ★ 8 + + Puchi - - ★ 9 + + Couleur du Corps - - ★ 10 + + Couleur du Visage - - Non validé + + Couleur des Membres - - ID de l'utilisateur + + Disparition - - Classement + + Inverser - - Êtes-vous sûr de vouloir vous déconnecter ? + + Voix - - Taiko 8 bits + + Vitesse - - Akemi + + Aléatoire - - Chinois simplifié + + Son de tambour - - Chinois traditionnel + + Position des notes - - Applaudissements + + Défis - - Conga + + Tournois - - Défaut + + Tournois Officiels - - Tambour + + Identifiant de tournoi - - Désactivé + + Recherche par nom, Identifiant de tournoi - - Fantaisiste + + Commentaire - - Désordonné + + Rejoindre - - Taiko + + Accepter - - Festival + + Rejeter - - Chiens & Chats + + Informations - - Taiko Deluxe + + Tournois - - Tambourin + + Accepté - - Wadadon + + Rejeté - - Oh hisse + + Utilisateur défié - - Don Mecha + + Durée (jours) - - Funassyi + + Musique - - Rap + + Jouer une seule fois - - Hosogai + + Limite atteinte - - Tambour Synthétique + + Inscrit - - Shuriken + + Défi de {From} à {To} - - Bubble Pop + + Défi de {From} - - Guitare électrique + + Défi à {To} - - Ura + + Créer un défi - - Configurer à chaque fois + + Créer une compétition - - Pas Full Combo + + Créer une compétition officielle - - Pas Donderful Combo + + Créer - - Japonais + + Selectionnez une musique - - Anglais + + Nombre maximal de participants - - Coréen + + Sélectionnez une musique par difficulté - - Passer la chanson + + Sélectionnez l'utilisateur défié - - Rechercher + + N'importe lequel - - Titres du joueur + + On - - Recherche par nom, identifiant ou code d'accès + + Off + + + Terminé \ No newline at end of file diff --git a/TaikoWebUI/Localization/LocalizationResource.ja.resx b/TaikoWebUI/Localization/LocalizationResource.ja.resx index b571791a..0155ad14 100644 --- a/TaikoWebUI/Localization/LocalizationResource.ja.resx +++ b/TaikoWebUI/Localization/LocalizationResource.ja.resx @@ -1,839 +1,936 @@  - - - - + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, - PublicKeyToken=b77a5c561934e089 - - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, - PublicKeyToken=b77a5c561934e089 - - - - メニュー - - - ユーザー管理 - - - プロフィール編集 - - - ユーザー - - - プレイデータ - - - 自己ベスト - - - QRコード - - - アクセスコード管理 - - - パスワード変更 - - - パスワードリセット - - - ユーザー削除 - - - TaikoWebUIへようこそ! - - - 曲名 - - - ★の数 - - - ジャンル - - - ベストスコア - - - ベスト王冠 - - - ベストランク - - - - - - - - - 不可 - - - 連打 - - - 最大コンボ数 - - - AIバトル演奏データ - - - ラストプレイ - - - プレイ回数 - - - クリア回数 - - - フルコンボ回数 - - - ドンダフルコンボ回数 - - - 曲目リスト - - - 隠す - - - 表示 - - - 区間 - - - 結果 - - - スコア - - - 王冠 - - - データがありません - - - "ユーザー管理"タブでログインしてください。 - - - 叩けた数 - - - 魂ゲージ - - - 課題曲 - - - 条件 - - - 赤合格 - - - 金合格 - - - 未合格 - - - 合格 - - - 合計 - - - 記録 - - - 曲目 - - - 段位道場 - - - プロフィール - - - プロフィール設定 - - - 着せ替え + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + yyyy/MM/dd HH:mm:ss - - 着せ替え設定 + + 招待コード生成 - - 演奏オプション + + 登録 - - プレイヤー + + ログイン - + 総合成績パネル - - 保存 - - - 言語 - - - 名前 - - - 称号 - - - 称号タイプ - - + 総合成績パネルの難易度 - - 段位表示 - - - 成績表示 - - - むずかしさからえらぶの難易度 - - - むずかしさからえらぶの★の数 - - - むずかしさからえらぶの表示順 - - - 称号を選択してください - - - あたま - - - からだ - - - メイク - - - きぐるみ - - - ぷちキャラ - - - どうの色 - - - かおの色 - - - てあしの色 - - - ドロン - - - あべこべ - - - 演奏スキップ - - - ボイス - - - はやさ - - - ランダム - - - 音色 - - - 音符位置調整 - - - yyyy/MM/dd HH:mm:ss - - - 招待コード生成 - - - 登録 + + AIバトル演奏データ - - 本当にこのユーザーのパスワードをリセットしますか? + + 不可 - - これにより、ユーザーの現在のパスワードは削除され、ユーザーは再度登録する必要があります。 + + ベスト王冠 - - ログイン + + ベストランク - + ログアウト - + プレイデータ - + + 自己ベスト + + + アクセスコード管理 + + アクセスコード追加 - + 新しいアクセスコード - + 削除 - + アクセスコード - + 旧パスワード - + 新しいパスワード - + パスワードの再入力 - + 確認 - + QRコード - - 超人 + + 五級 - - 八段 + + 四級 - - 五段 + + 三級 - - 五級 + + 二級 + + + 一級 - + 一段 - - 一級 + + 二段 - + + 三段 + + 四段 - - 四級 + + 五段 - - 外伝 + + 六段 - - 玄人 + + 七段 - - 名人 + + 八段 - + 九段 - - 二段 + + 十段 - - 二級 + + 玄人 - - 七段 + + 名人 - - 六段 + + 超人 - + 達人 - - 十段 - - - 三段 - - - 三級 + + 外伝 - + 金金合格 - - 虹赤合格 - - + 金赤合格 - + + 虹赤合格 + + 虹金合格 - + + 曲目リスト + + + "ユーザー管理"タブでログインしてください。 + + + 段位道場 + + + 課題曲 + + + 曲名 + + 曲名 / Artist - + 曲名、アーティスト名で検索 - + ジャンル検索 - + プレイ履歴 - + プレイ履歴なし - + パスワード - + 設定 - + プレイ時間 - + ランク - + 難易度 - + 曲数 - + 曲名、アーティスト名、日付で検索 - + + ユーザー管理 + + + メニュー + + 登録解除 - + - + 他のアクセスコード - + クリップボードにコピー - + 招待コード - + エラー - + + プレイデータ + + + 未合格 + + + ユーザー + + アクセスコードが必要です - + 招待コード(任意) - + 前回プレイデート - + 前回プレイ時間(クレジット終了5分以内) - + パスワードが必要です - + パスワードの再入力 - + アクセスコードの再入力が必要です - + 未知のエラー - + 成功 - + おに裏 - + おに - + むずかしい - + ふつう - + かんたん - + 1ページ当たりの行数 - + + プレイ回数 + + UI - + 追加 - + 新しいアクセスコードのバインドに成功。 - + ログインしていません。<br />ログインしてからもう一度お試しください。 - + バウンドアクセスコードの上限に達しました。<br />まずアクセスコードを1つ削除してください。 - + このアクセスコードはすでにバインドされています。 - + アクセスコードは空ではありません。<br />有効なアクセスコードを入力してください。 - + この操作は許可されていません。<br />他のユーザーのアクセスコードを編集できるのは管理者のみです。 - + ログインできるのは管理者のみです。 - + パスワードの変更に成功しました。 - + 新しいパスワードが違うことを確認してください。<br />もう一度確認してください。 - + 不明なアクセスコードです。<br />このアクセスコードでゲームを1回プレイしてから、再度お試しください。 - + 現在のパスワードが間違っています。<br />再度ご確認ください。 - + アクセスコードが登録されていません。<br />まず登録してから再度お試しください。 - + パスワードが間違っています。<br />再度ご確認ください。 - + 登録できるのは管理者のみです。 - + アクセスコードが正常に登録されました。 - + パスワードの確認がパスワードと一致しません。<br />再度ご確認ください。 - + アクセスコードは既に登録されています。<br />設定したパスワードを使用してログインしてください。 - + 最後のプレイ時間が間違っています。<br />最後にプレイした時間を忘れた場合は、このアクセスコードで再度ゲームをプレイするか、管理者に連絡してください。 - + キャンセル - + ユーザーの最後のアクセスコードを削除できません。 - + アクセスコードが正常に削除されました。 - + ID - + + プロフィール編集 + + このアクセスコードを削除してもよろしいですか? - + 現在選択中: - + リセット - + + 本当にこのユーザーのパスワードをリセットしますか? + + + これにより、ユーザーの現在のパスワードは削除され、ユーザーは再度登録する必要があります。 + + このユーザーのデータを本当に削除してもよろしいですか?<br />関連するすべてのデータが削除され、この操作は元に戻せません! - + ユーザーが正常に削除されました。 - + + 演奏スキップ + + なし - + きまぐれ - + でたらめ - + 太鼓 - + お祭り - + いぬねこ - + 豪華な太鼓 - + ドラム - + タンバリン - + 和田どん - + 手拍子 - + コンガ - + 8ビット太鼓 - + ソイヤ - + メカドン - + ふなっしー - + ラップ - + 細貝さん - + 朱美ちゃん - + シンセドラム - + しゅりけん - + プチプチ - + エレキギター - + おに裏 - + 毎回設定 - + デフォルト - + 未クリア優先 - + 未フルコンボ優先 - + 未ドンダフルコンボ優先 - + 日本語 - + 英語 - + 繁体字中国語 - + 韓国語 - + 簡体字中国語 - + ★ 1 - - ★ 10 - - + ★ 2 - + ★ 3 - + ★ 4 - + ★ 5 - + ★ 6 - + ★ 7 - + ★ 8 - + ★ 9 - + + ★ 10 + + ログアウトしてもよろしいですか? - + ランキング - + + データがありません + + ユーザーID - + 名前、ID、アクセスコードで検索 - - プレイヤー称号 - - - 検索 - + + プレイヤー称号 + + + 検索 + + + QRコード + + + パスワード変更 + + + パスワードリセット + + + ユーザー削除 + + + TaikoWebUIへようこそ! + + + ★の数 + + + ジャンル + + + ベストスコア + + + + + + + + + 連打 + + + 最大コンボ数 + + + ラストプレイ + + + クリア回数 + + + フルコンボ回数 + + + ドンダフルコンボ回数 + + + 隠す + + + 表示 + + + 区間 + + + 結果 + + + スコア + + + 王冠 + + + 叩けた数 + + + 魂ゲージ + + + 条件 + + + 赤合格 + + + 金合格 + + + 合格 + + + 合計 + + + 記録 + + + 曲目 + + + プロフィール + + + プロフィール設定 + + + 着せ替え + + + 着せ替え設定 + + + 演奏オプション + + + プレイヤー + + + 保存 + + + 言語 + + + 名前 + + + 称号 + + + 称号タイプ + + + 段位表示 + + + 成績表示 + + + むずかしさからえらぶの難易度 + + + むずかしさからえらぶの★の数 + + + むずかしさからえらぶの表示順 + + + 称号を選択してください + + + あたま + + + からだ + + + メイク + + + きぐるみ + + + ぷちキャラ + + + どうの色 + + + かおの色 + + + てあしの色 + + + ドロン + + + あべこべ + + + ボイス + + + はやさ + + + ランダム + + + 音色 + + + 音符位置調整 + + + 挑戦状 + + + 大会 + + + 公式大会 + + + 挑戦ID + + + 名前、挑戦IDで検索 + + + コメント + + + 参加する + + + 受け入れる + + + 拒否する + + + 詳細 + + + 挑戦と大会 + + + 受け入れられました + + + 拒否されました + + + 挑戦対象 + + + 期間 (日) + + + + + + 一度だけプレイ + + + すでに満席 + + + 参加済み + + + {From} から {To} への挑戦状 + + + {From} からの挑戦状 + + + {To} への挑戦状 + + + 挑戦状を作成する + + + 大会を作成する + + + 公式大会を作成する + + + 作成する + + + 曲が選択されていません + + + 最大参加者数 + + + 難しいと曲を選ぶ + + + 挑戦対象を選択 + + + 指定しない + + + オン + + + オフ + + + 終わった + \ No newline at end of file diff --git a/TaikoWebUI/Localization/LocalizationResource.resx b/TaikoWebUI/Localization/LocalizationResource.resx index 12e87441..cfb61e11 100644 --- a/TaikoWebUI/Localization/LocalizationResource.resx +++ b/TaikoWebUI/Localization/LocalizationResource.resx @@ -1,650 +1,936 @@  - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, - PublicKeyToken=b77a5c561934e089 - - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, - PublicKeyToken=b77a5c561934e089 - - - + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + MM/dd/yyyy h:mm:ss tt - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - \ No newline at end of file diff --git a/TaikoWebUI/Localization/LocalizationResource.zh-Hans.resx b/TaikoWebUI/Localization/LocalizationResource.zh-Hans.resx index 8551b35c..6e5c521c 100644 --- a/TaikoWebUI/Localization/LocalizationResource.zh-Hans.resx +++ b/TaikoWebUI/Localization/LocalizationResource.zh-Hans.resx @@ -1,839 +1,936 @@  - - - - + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, - PublicKeyToken=b77a5c561934e089 - - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, - PublicKeyToken=b77a5c561934e089 - - - - 主页 - - - 用户管理 - - - 编辑档案 - - - 用户 - - - 查看记录 - - - 最高分 - - - 查看二维码 - - - 管理访问码 - - - 更改密码 - - - 重置密码 - - - 删除帐号 - - - 欢迎来到TaikoWebUI! - - - 曲名 - - - ★数 - - - 分类 - - - 最佳成绩 - - - 最佳王冠 - - - 最佳评价 - - - - - - - - - 不可 - - - 连打 - - - 最大连击数 - - - AI对战数据 - - - 最后游玩时间 - - - 总游玩次数 - - - 总通过次数 - - - 总全连段次数 - - - 总完美连段次数 - - - 曲目列表 - - - 隐藏 - - - 显示 - - - 区间 - - - 结果 - - - 成绩 - - - 王冠 - - - 没有数据 - - - "请先在用户管理那边登录 - - - 总打击次数 - - - 魂条 - - - 课题曲 - - - 条件 - - - 赤合格 - - - 金合格 - - - 未合格 - - - 合格 - - - 总共 - - - 记录 - - - 曲目 - - - 段位道场 - - - 档案 - - - 档案设定 - - - 装饰 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + yyyy/M/d HH:mm:ss - - 装饰设定 + + 生成邀请码 - - 演奏设定 + + 注册 - - 玩家 + + 登录 - + 成绩版面 - - 储存 - - - 语言 - - - 名字 - - - 称号 - - - 称号种类 - - + 成绩版面难度 - - 显示段位 - - - 显示成绩版面 - - - 筛选歌曲版面难度 - - - 筛选歌曲版面★数 - - - 筛选歌曲版面顺序条件 - - - 选择一个称号 - - - 头部 - - - 身体 - - - 面部 - - - 套装 - - - 小角色 - - - 身体颜色 - - - 面部颜色 - - - 边框颜色 - - - 隐谱 - - - 反谱 - - - 跳过演奏 - - - 声音 - - - 流速 - - - 随机 - - - 音色 - - - 音符位置调整 - - - yyyy/M/d HH:mm:ss - - - 生成邀请码 - - - 注册 + + AI对战数据 - - 确定要为这位用户重置密码吗? + + 不可 - - 重置密码后,用户需要再次注册 + + 最佳王冠 - - 登录 + + 最佳评价 - + 登出 - + 游玩数据 - + + 最高分 + + + 管理访问码 + + 新增访问码 - + 新访问码 - + 删除 - + 访问码 - + 现有密码 - + 新密码 - + 再次输入新密码 - + 确定 - + 二维码 - - 超人 + + 五级 - - 八段 + + 四级 - - 五段 + + 三级 - - 五级 + + 二级 - + + 一级 + + 一段 - - 一级 + + 二段 - + + 三段 + + 四段 - - 四级 + + 五段 - - 外传 + + 六段 - - 玄人 + + 七段 - - 名人 + + 八段 - + 九段 - - 二段 + + 十段 - - 二级 + + 玄人 - - 七段 + + 名人 - - 六段 + + 超人 - + 达人 - - 十段 - - - 三段 - - - 三级 + + 外传 - + 金金合格 - - 虹赤合格 - - + 金赤合格 - + + 虹赤合格 + + 虹金合格 - + + 曲目列表 + + + "请先在用户管理那边登录 + + + 段位道场 + + + 课题曲 + + + 曲名 + + 曲名 / Artist - + 曲名/Artist名搜索 - + 分类过滤 - + 游玩历史 - + 沒有游玩历史 - + 密码 - + 设定 - + 游玩时间 - + 评价 - + 难度 - + 曲数 - + 曲名/Artist名/日期搜索 - + + 用户管理 + + + 主页 + + 注销账号 - + - + 个其他访问码 - + 复制到粘贴板 - + 邀请码 - + 错误 - + + 查看记录 + + + 未合格 + + + 用户 + + 访问码为必填项 - + 邀请码(可选) - + + 最后游玩日期 + + 最后游玩时间(游戏结束5分钟内) - + 密码为必填项 - + 再次输入密码 - + 再次输入密码为必填项 - + 不明错误 - + 成功 - + 里譜面 - + 魔王 - + 困难 - + 普通 - + 简单 - + 每页行数 - + + 总游玩次数 + + 界面 - + 添加 - + 新访问码绑定成功。 - + 用户未登录。<br />请先登录,然后再试一次。 - + 已达到绑定访问码数量上限。<br />请先删除一个已绑定的访问码。 - + 此访问码已被绑定。 - + 访问码不能为空。<br/>请输入有效的访问码。 - + 不允许执行此操作。<br />只有管理员可以编辑其他用户的访问码。 - + 只有管理员可以登录。 - + 密码更改成功。 - + 确认新密码与新密码不同。<br />请再次检查。 - + 未知的访问码。<br />请使用此访问码玩一局游戏后再试一次。 - + 当前密码错误。<br />请再检查一次。 - + 访问码未注册。<br />请先注册然后再试一次。 - + 密码错误。<br />请再检查一次。 - + 只有管理员可以注册。 - + 访问码已成功注册。 - + 确认密码与密码不一致。<br />请再检查一次。 - + 访问码已注册。<br />请使用设置的密码登录。 - + 最后的游戏时间错误。<br />如果您忘记了上次玩游戏的时间,请使用此访问码再玩一局游戏或联系管理员。 - + 取消 - + 无法删除用户的最后一个访问码。 - + 访问码已成功删除。 - + ID - - 最后游玩日期 + + 编辑档案 - + 您确定要删除此访问码吗? - + 当前选择: - + 重置 - + + 确定要为这位用户重置密码吗? + + + 重置密码后,用户需要再次注册 + + 您真的要删除该用户的数据吗?<br />所有相关数据将被删除,此过程无法撤销! - + 用户已成功删除。 - + + 跳过演奏 + + - + 随兴 - + 随意 - + 太鼓 - + 祭典 - + 狗与猫 - + 豪华的太鼓 - + 架子鼓 - + + 铃鼓 + + 和田咚 - + 手拍子 - + 康加鼓 - + 8-bit太鼓 - + 嘿哟 - + 机械咚 - + 船梨精 - + 说唱 - + 細貝先生 - + 朱美酱 - + 合成鼓 - - 铃鼓 - - + 手里剑 - + 泡泡 - + 电吉他 - + 里譜面 - + 每次设置 - + 默认 - + 未通关优先 - + 未全连段优先 - + 未全良连段优先 - + 日语 - + 英语 - + 繁体中文 - + 韩语 - + 简体中文 - + ★ 1 - - ★ 10 - - + ★ 2 - + ★ 3 - + ★ 4 - + ★ 5 - + ★ 6 - + ★ 7 - + ★ 8 - + ★ 9 - + + ★ 10 + + 您确定要登出吗? - + 排行榜 - + + 没有数据 + + 用户ID - + 名称,ID,访问码搜索 - - 玩家称号 - - - 搜索 - + + 玩家称号 + + + 搜索 + + + 查看二维码 + + + 更改密码 + + + 重置密码 + + + 删除帐号 + + + 欢迎来到TaikoWebUI! + + + ★数 + + + 分类 + + + 最佳成绩 + + + + + + + + + 连打 + + + 最大连击数 + + + 最后游玩时间 + + + 总通过次数 + + + 总全连段次数 + + + 总完美连段次数 + + + 隐藏 + + + 显示 + + + 区间 + + + 结果 + + + 成绩 + + + 王冠 + + + 总打击次数 + + + 魂条 + + + 条件 + + + 赤合格 + + + 金合格 + + + 合格 + + + 总共 + + + 记录 + + + 曲目 + + + 档案 + + + 档案设定 + + + 装饰 + + + 装饰设定 + + + 演奏设定 + + + 玩家 + + + 储存 + + + 语言 + + + 名字 + + + 称号 + + + 称号种类 + + + 显示段位 + + + 显示成绩版面 + + + 筛选歌曲版面难度 + + + 筛选歌曲版面★数 + + + 筛选歌曲版面顺序条件 + + + 选择一个称号 + + + 头部 + + + 身体 + + + 面部 + + + 套装 + + + 小角色 + + + 身体颜色 + + + 面部颜色 + + + 边框颜色 + + + 隐谱 + + + 反谱 + + + 声音 + + + 流速 + + + 随机 + + + 音色 + + + 音符位置调整 + + + 挑战书 + + + 大赛 + + + 官方大赛 + + + 比赛ID + + + 名称,比赛ID搜索 + + + 简介 + + + 参加 + + + 接受 + + + 拒绝 + + + 详情 + + + 挑战与大赛 + + + 已接受 + + + 已拒绝 + + + 挑战对象 + + + 持续时间(天) + + + 歌曲 + + + 单次挑战 + + + 已满员 + + + 已参加 + + + {From} 向 {To} 发起的挑战书 + + + 来自 {From} 的挑战书 + + + 向 {To} 发起的挑战书 + + + 发起挑战 + + + 创建大赛 + + + 创建官方大赛 + + + 创建 + + + 无歌曲 + + + 最大参与人数 + + + 请选择歌曲与难度 + + + 请选择挑战的对象 + + + 任意 + + + 开启 + + + 关闭 + + + 已结束 + \ No newline at end of file diff --git a/TaikoWebUI/Localization/LocalizationResource.zh-Hant.resx b/TaikoWebUI/Localization/LocalizationResource.zh-Hant.resx index 76376807..5eb5ac4a 100644 --- a/TaikoWebUI/Localization/LocalizationResource.zh-Hant.resx +++ b/TaikoWebUI/Localization/LocalizationResource.zh-Hant.resx @@ -1,839 +1,936 @@  - - - - + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, - PublicKeyToken=b77a5c561934e089 - - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, - PublicKeyToken=b77a5c561934e089 - - - - 首頁 - - - 管理用戶 - - - 編輯檔案 - - - 用戶 - - - 查看記錄 - - - 最高分 - - - 查看QR Code - - - 管理訪問碼 - - - 更改密碼 - - - 重置密碼 - - - 刪除帳號 - - - 歡迎來到TaikoWebUI! - - - 曲名 - - - ★數 - - - 分類 - - - 最佳成績 - - - 最佳皇冠 - - - 最佳評價 - - - - - - - - - 不可 - - - 連打 - - - 最大連擊數 - - - AI對戰數據 - - - 最後遊玩時間 - - - 總遊玩次數 - - - 總通過次數 - - - 總全接次數 - - - 總全良次數 - - - 曲目列表 - - - 隱藏 - - - 顯示 - - - 區間 - - - 结果 - - - 成績 - - - 皇冠 - - - 沒有數據 - - - "請先在管理用戶那邊登入 - - - 總打擊次數 - - - 魂條 - - - 課題曲 - - - 條件 - - - 赤合格 - - - 金合格 - - - 未合格 - - - 合格 - - - 總共 - - - 記錄 - - - 曲目 - - - 段位道埸 - - - 檔案 - - - 檔案設定 - - - 裝飾 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + yyyy/M/d HH:mm:ss - - 裝飾設定 + + 生成邀請碼 - - 演奏設定 + + 注冊 - - 玩家 + + 登錄 - + 成績版面 - - 儲存 - - - 語言 - - - 名字 - - - 稱號 - - - 稱號種類 - - + 成績版面難度 - - 顯示段位 - - - 顯示成績版面 - - - 篩選歌曲版面難度 - - - 篩選歌曲版面★數 - - - 篩選歌曲版面順序條件 - - - 選擇一個稱號 - - - 頭部 - - - 身體 - - - 面部 - - - 套装 - - - 小角色 - - - 身體顏色 - - - 面部顏色 - - - 邊框顏色 - - - 隱譜 - - - 反譜 - - - 跳略演奏 - - - 聲音 - - - 流速 - - - 隨機 - - - 音色 - - - 音符位置調整 - - - yyyy/M/d HH:mm:ss - - - 生成邀請碼 - - - 注冊 + + AI對戰數據 - - 確定要為這位用戶重置密碼嗎? + + 不可 - - 重置密碼后,用戶需要再次注冊 + + 最佳皇冠 - - 登錄 + + 最佳評價 - + 登出 - + 游玩數據 - + + 最高分 + + + 管理訪問碼 + + 新增訪問碼 - + 新訪問碼 - + 删除 - + 訪問碼 - + 現有密碼 - + 新密碼 - + 再次輸入新密碼 - + 確認 - + 查看QR Code - - 超人 - - - 八段 - - - 外傳 + + 五級 - + 四級 - - 四段 + + 三級 - + + 二級 + + 一級 - + 一段 - - 五級 + + 二段 - + + 三段 + + + 四段 + + 五段 - - 玄人 + + 六段 - - 名人 + + 七段 + + + 八段 - + 九段 - - 二段 + + 十段 - - 二級 + + 玄人 - - 七段 + + 名人 - - 六段 + + 超人 - + 達人 - - 十段 - - - 三段 - - - 三級 + + 外傳 - + 金金合格 - - 虹赤合格 - - + 金赤合格 - + + 虹赤合格 + + 虹金合格 - + + 曲目列表 + + + "請先在管理用戶那邊登入 + + + 段位道埸 + + + 課題曲 + + + 曲名 + + 曲名 / Artist - + 曲名/Artist名搜索 - + 分類過濾 - + 游玩歷史 - + 没有游玩歷史 - + 密碼 - + 設定 - + 游玩時間 - + 評價 - + 難度 - + 曲數 - + 曲名/Artist名/日期搜索 - + + 管理用戶 + + + 首頁 + + 注銷賬號 - + - + 個其他訪問碼 - + 複製到粘貼板 - + 邀請碼 - + 錯誤 - + + 查看記錄 + + + 未合格 + + + 用戶 + + 訪問碼為必填項 - + 邀請碼(可選) - + + 最後游玩日期 + + 最後游玩時間(游戲結束5分鐘内) - + 密碼為必填項 - + 再次輸入密碼 - + 再次輸入密碼為必填項 - + 不明錯誤 - + 成功 - + 裏譜面 - + 魔王 - + 困難 - + 普通 - + 簡單 - + 每頁行數 - + + 總遊玩次數 + + 界面 - + 添加 - + 新訪問碼綁定成功 。 - + 用戶未登錄。<br />請先登錄,然後再試一次。 - + 已達到綁定訪問碼數量上限。<br />請先刪除一個已綁定的訪問碼。 - + 此訪問碼已被綁定。 - + 訪問碼不能爲空。<br/>請輸入有效的訪問碼。 - + 不允許執行此操作。<br />只有管理員可以編輯其他用戶的訪問碼。 - + 只有管理員可以登錄。 - + 密碼更改成功。 - + 確認新密碼與新密碼不同。<br />請再次檢查。 - + 未知的訪問碼。<br />請使用此訪問碼玩一局遊戲後再試一次。 - + 當前密碼錯誤。<br />請再檢查一次。 - + 訪問碼未註冊。<br />請先註冊然後再試一次。 - + 密碼錯誤。<br />請再檢查一次。 - + 只有管理員可以註冊。 - + 訪問碼已成功註冊。 - + 確認密碼與密碼不一致。<br />請再檢查一次。 - + 訪問碼已註冊。<br />請使用設置的密碼登錄。 - + 最後的遊戲時間錯誤。<br />如果您忘記了上次玩遊戲的時間,請使用此訪問碼再玩一局遊戲或聯繫管理員。 - + 取消 - + 無法刪除用戶的最後一個訪問碼。 - + 訪問碼已成功刪除。 - + ID - - 最後游玩日期 + + 編輯檔案 - + 您確定要刪除此訪問碼嗎? - + 當前選擇: - + 重置 - + + 確定要為這位用戶重置密碼嗎? + + + 重置密碼后,用戶需要再次注冊 + + 您真的要刪除該用戶的數據嗎?<br />所有相關數據將被刪除,此過程無法撤銷! - + 用戶已成功刪除。 - + + 跳略演奏 + + - + 隨興 - + 隨意 - + 太鼓 - + 祭典 - + 狗與貓 - + 豪華的太鼓 - + 爵士鼓 - + + 鈴鼓 + + 和田咚 - + 手拍子 - + 康加鼓 - + 8-bit太鼓 - + 嘿喲 - + 機械咚 - + 船梨精 - + 説唱 - + 細貝先生 - + 朱美醬 - + 合成鼓 - - 鈴鼓 - - + 手裏劍 - + 泡泡 - + 電吉他 - + 裏譜面 - + 每次設置 - + 默認 - + 未通關優先 - + 未全連段優先 - + 未全良連段優先 - + 日語 - + 英語 - + 繁體中文 - + 韓語 - + 簡體中文 - + ★ 1 - - ★ 10 - - + ★ 2 - + ★ 3 - + ★ 4 - + ★ 5 - + ★ 6 - + ★ 7 - + ★ 8 - + ★ 9 - + + ★ 10 + + 您確定要登出嗎? - + 排行榜 - + + 沒有數據 + + 用戶ID - + 按名稱,ID ,訪問碼搜索 - - 玩家稱號 - - - 搜索 - + + 玩家稱號 + + + 搜索 + + + 查看QR Code + + + 更改密碼 + + + 重置密碼 + + + 刪除帳號 + + + 歡迎來到TaikoWebUI! + + + ★數 + + + 分類 + + + 最佳成績 + + + + + + + + + 連打 + + + 最大連擊數 + + + 最後遊玩時間 + + + 總通過次數 + + + 總全接次數 + + + 總全良次數 + + + 隱藏 + + + 顯示 + + + 區間 + + + 结果 + + + 成績 + + + 皇冠 + + + 總打擊次數 + + + 魂條 + + + 條件 + + + 赤合格 + + + 金合格 + + + 合格 + + + 總共 + + + 記錄 + + + 曲目 + + + 檔案 + + + 檔案設定 + + + 裝飾 + + + 裝飾設定 + + + 演奏設定 + + + 玩家 + + + 儲存 + + + 語言 + + + 名字 + + + 稱號 + + + 稱號種類 + + + 顯示段位 + + + 顯示成績版面 + + + 篩選歌曲版面難度 + + + 篩選歌曲版面★數 + + + 篩選歌曲版面順序條件 + + + 選擇一個稱號 + + + 頭部 + + + 身體 + + + 面部 + + + 套装 + + + 小角色 + + + 身體顏色 + + + 面部顏色 + + + 邊框顏色 + + + 隱譜 + + + 反譜 + + + 聲音 + + + 流速 + + + 隨機 + + + 音色 + + + 音符位置調整 + + + 挑戰書 + + + 大賽 + + + 官方大赛 + + + 比赛ID + + + 按名稱,比赛ID搜索 + + + 簡介 + + + 參加 + + + 接受 + + + 拒絕 + + + 詳情 + + + 挑戰與大赛 + + + 已接受 + + + 已拒絕 + + + 挑戰對象 + + + 持續時間(天) + + + 歌曲 + + + 單次挑戰 + + + 已滿員 + + + 已參加 + + + {From} 向 {To} 發起的挑戰書 + + + 來自 {From} 的挑戰書 + + + 向 {To} 發起的挑戰書 + + + 發起挑戰 + + + 創建大賽 + + + 創建官方大賽 + + + 創建 + + + 未選擇歌曲 + + + 最大參與人數 + + + 請選擇歌曲與難度 + + + 請選擇挑戰的對象 + + + 任意 + + + 開啟 + + + 關閉 + + + 已結束 + \ No newline at end of file diff --git a/TaikoWebUI/Pages/Challenge.razor b/TaikoWebUI/Pages/Challenge.razor new file mode 100644 index 00000000..7a6ca1f9 --- /dev/null +++ b/TaikoWebUI/Pages/Challenge.razor @@ -0,0 +1,10 @@ +@using TaikoWebUI.Components; + +@page "/ChallengeCompe/{baid:int}/Challenge" + + + +@code { + [Parameter] + public int Baid { get; set; } +} diff --git a/TaikoWebUI/Pages/Compete.razor b/TaikoWebUI/Pages/Compete.razor new file mode 100644 index 00000000..5843dd52 --- /dev/null +++ b/TaikoWebUI/Pages/Compete.razor @@ -0,0 +1,10 @@ +@using TaikoWebUI.Components; + +@page "/ChallengeCompe/{baid:int}/Competition" + + + +@code { + [Parameter] + public int Baid { get; set; } +} diff --git a/TaikoWebUI/Pages/Dialogs/AddChallengeCompetitionDialog.razor b/TaikoWebUI/Pages/Dialogs/AddChallengeCompetitionDialog.razor new file mode 100644 index 00000000..22657eff --- /dev/null +++ b/TaikoWebUI/Pages/Dialogs/AddChallengeCompetitionDialog.razor @@ -0,0 +1,336 @@ +@using System.Net +@using Blazored.LocalStorage +@using TaikoWebUI.Utilities + +@inject HttpClient Client +@inject ISnackbar Snackbar +@inject IDialogService DialogService +@inject IGameDataService GameDataService +@inject ILocalStorageService LocalStorage + + + + @if (Mode == 1) + { + + + @Localizer["Create Challenge"] + + } + else if (Mode == 2) + { + + + @Localizer["Create Competition"] + + } + else if (Mode == 3) + { + + + @Localizer["Create Official Competition"] + + } + + + + + @if (Mode == 2 || Mode == 3) + { + + } + + @if (Mode == 1) + { + + + @Localizer["Select"] + + } + @for (int i = 0; i < Info.challengeCompeteSongs.Count; i ++) + { + var song_idx = i; + var song_label = Localizer["Song"] + $" {song_idx + 1}"; + var song = Info.challengeCompeteSongs[song_idx]; + + + + + + @if (difficulties[song_idx] != Difficulty.None) + { + Difficulty difficulty = difficulties[song_idx]; + + } + @(musicDetails[song_idx].SongId == 0 ? Localizer["No Select"] : GameDataService.GetMusicNameBySongId(MusicDetailDictionary, musicDetails[song_idx].SongId, SongNameLanguage)) + @if (levels[song_idx] > 0) { + @levels[song_idx] + } + + + @if (Info.challengeCompeteSongs.Count > 1) + { + + } + + + + + + @Localizer["Any"] + @Localizer["On"] + @Localizer["Off"] + + + @Localizer["Any"] + @Localizer["On"] + @Localizer["Off"] + + + @Localizer["Any"] + @for (uint idx = 0; idx < SpeedStrings.Length; idx++) + { + var speed_idx = idx; + @SpeedStrings[speed_idx] + } + + + @Localizer["Any"] + @foreach (var item in Enum.GetValues()) + { + @Localizer[item.ToString()] + } + + + + + + } + @if (Info.challengeCompeteSongs.Count < MaxSongs) + { + + } + @if (Mode != 1) + { + + } + + @Localizer["Only Play Once"] + + + + @Localizer["Cancel"] + @Localizer["Create"] + + + +@code { + [CascadingParameter] + private MudDialogInstance MudDialog { get; set; } = null!; + + [Parameter] + public int Mode { get; set; } = 0; + + [Parameter] + public int Baid { get; set; } = 0; + + [Parameter] + public int MaxSongs { get; set; } = 1; + + [Parameter] + public int MaxDays { get; set; } = 30; + + [Parameter] + public int MaxParticipant { get; set; } = 20; + + [Parameter] + public ChallengeCompeteCreateInfo Info { get; set; } = new(); + + private Dictionary MusicDetailDictionary = new(); + + private string? SongNameLanguage; + + private static readonly string[] SpeedStrings = + { + "1.0", "1.1", "1.2", "1.3", "1.4", + "1.5", "1.6", "1.7", "1.8", "1.9", + "2.0", "2.5", "3.0", "3.5", "4.0" + }; + + private uint TargetBaid = 0; + + private string TargetUserName = string.Empty; + + private bool[] _expandeds = new bool[0]; + + private MusicDetail[] musicDetails = new MusicDetail[0]; + + private Difficulty[] difficulties = new Difficulty[0]; + + private int[] levels = new int[0]; + + private int LastFor = 7; + + private int ParticipantCount = 5; + + private bool OnlyPlayOnce = false; + + + protected override async Task OnInitializedAsync() + { + base.OnInitialized(); + _expandeds = new bool[MaxSongs]; + musicDetails = new MusicDetail[MaxSongs]; + difficulties = new Difficulty[MaxSongs]; + levels = new int[MaxSongs]; + for (int i = 0; i < MaxSongs; i++) + { + musicDetails[i] = new(); + difficulties[i] = Difficulty.None; + levels[i] = 0; + } + Info.challengeCompeteSongs.Add(new()); + SongNameLanguage = await LocalStorage.GetItemAsync("songNameLanguage"); + MusicDetailDictionary = await GameDataService.GetMusicDetailDictionary(); + } + + private void AddSong() + { + Info.challengeCompeteSongs.Add(new()); + } + + private async Task SelSong(int i) + { + var options = new DialogOptions { CloseOnEscapeKey = true }; + var parameters = new DialogParameters(); + parameters.Add("MusicDetailDictionary", MusicDetailDictionary); + parameters.Add("SongNameLanguage", SongNameLanguage); + + var reference = await DialogService.ShowAsync(Localizer["Select Song"], parameters, options); + if (reference != null) + { + var songInfo = await reference.GetReturnValueAsync(); + + if (songInfo != null) + { + musicDetails[i] = songInfo.MusicDetail; + difficulties[i] = songInfo.Difficulty; + levels[i] = songInfo.Level; + } + } + } + + private void DelSong(int i) + { + Info.challengeCompeteSongs.RemoveAt(i); + for (int ex = i; ex < MaxSongs; ex ++) + { + if (ex + 1 < MaxSongs) + { + _expandeds[ex] = _expandeds[ex + 1]; + musicDetails[ex] = musicDetails[ex + 1]; + difficulties[ex] = difficulties[ex + 1]; + levels[ex] = levels[ex + 1]; + } + else + { + _expandeds[ex] = false; + musicDetails[ex] = new(); + difficulties[ex] = Difficulty.None; + levels[ex] = 0; + } + } + } + + private async Task SelTarget() + { + var options = new DialogOptions { CloseOnEscapeKey = true }; + var parameters = new DialogParameters(); + parameters.Add("Exclude", Baid); + + var reference = await DialogService.ShowAsync(Localizer["Select User"], parameters, options); + var user = await reference.GetReturnValueAsync(); + + if (user != null) + { + TargetUserName = user.UserSetting.MyDonName; + TargetBaid = user.Baid; + } + } + + private void Cancel() => MudDialog.Cancel(); + + private async Task Create() + { + var options = new DialogOptions { CloseOnEscapeKey = true }; + + for (int i = 0; i < Info.challengeCompeteSongs.Count; i ++) + { + if (difficulties[i] == Difficulty.None) + { + await ShowError(Localizer["Must Select Song Error"]); + return; + } + + Info.challengeCompeteSongs[i].SongId = musicDetails[i].SongId; + Info.challengeCompeteSongs[i].Difficulty = difficulties[i]; + } + Info.MaxParticipant = (uint) ParticipantCount; + Info.LastFor = (uint) LastFor; + Info.CompeteMode = (CompeteModeType)Mode; + Info.OnlyPlayOnce = OnlyPlayOnce; + + if (Mode == 1) + { + Info.MaxParticipant = 2; + if (TargetBaid == 0) + { + await ShowError(Localizer["Must Select Challenge Target Error"]); + return; + } + var resp = await Client.PostAsJsonAsync($"api/ChallengeCompeteManage/{Baid}/createChallenge/{TargetBaid}", Info); + if (resp.StatusCode != HttpStatusCode.OK) + { + await ShowError(Localizer["Create Compete Error"]); + return; + } + } + else if (Mode == 2) + { + var resp = await Client.PostAsJsonAsync($"api/ChallengeCompeteManage/{Baid}/createCompete", Info); + if (resp.StatusCode != HttpStatusCode.OK) + { + await ShowError(Localizer["Create Compete Error"]); + return; + } + } + else if (Mode == 3) + { + var resp = await Client.PostAsJsonAsync($"api/ChallengeCompeteManage/createOfficialCompete", Info); + if (resp.StatusCode != HttpStatusCode.OK) + { + await ShowError(Localizer["Create Compete Error"]); + return; + } + } + + MudDialog.Close(DialogResult.Ok(true)); + } + + private async Task ShowError(string errorWord) + { + var options = new DialogOptions { CloseOnEscapeKey = true }; + await DialogService.ShowMessageBox( + Localizer["Error"], + (MarkupString) + (string)errorWord, + Localizer["Dialog OK"], + null, null, options + ); + } + + private void OnExpandCollapseClick(int i) + { + _expandeds[i] = !_expandeds[i]; + } +} diff --git a/TaikoWebUI/Pages/Dialogs/ChooseSongDialog.razor b/TaikoWebUI/Pages/Dialogs/ChooseSongDialog.razor new file mode 100644 index 00000000..2b993a8c --- /dev/null +++ b/TaikoWebUI/Pages/Dialogs/ChooseSongDialog.razor @@ -0,0 +1,135 @@ +@using Blazored.LocalStorage +@using TaikoWebUI.Utilities; + +@inject IJSRuntime Js +@inject ILocalStorageService LocalStorage +@inject IGameDataService GameDataService + + + + + + + + + + + + + + + @Localizer["Song Title"] + + + @foreach (var difficulty in Enum.GetValues()) + { + @if (difficulty is not Difficulty.None) + { + + + @ScoreUtils.GetDifficultyTitle(difficulty) + + + } + } + + + + + @GameDataService.GetMusicNameBySongId(MusicDetailDictionary, context.SongId, SongNameLanguage) + + + @foreach (var difficulty in Enum.GetValues()) + { + @if (difficulty is not Difficulty.None) + { + var starLevel = GameDataService.GetMusicStarLevel(MusicDetailDictionary, context.SongId, difficulty); + + @if (starLevel > 0) + { + @starLevel + } + else + { + + - + + } + + } + } + + + + + + + + + @Localizer["Cancel"] + + + + +@code { + + [CascadingParameter] MudDialogInstance MudDialog { get; set; } = null!; + + [Parameter] public Dictionary? MusicDetailDictionary { get; set; } = null; + + [Parameter] public string? SongNameLanguage { get; set; } = null; + + private string Search { get; set; } = string.Empty; + + private string searchString = string.Empty; + + protected override async Task OnInitializedAsync() + { + base.OnInitialized(); + if (SongNameLanguage == null) SongNameLanguage = await LocalStorage.GetItemAsync("songNameLanguage"); + if (MusicDetailDictionary == null) MusicDetailDictionary = await GameDataService.GetMusicDetailDictionary(); + + } + + private bool FilterSongs(MusicDetail musicDetail) + { + var stringsToCheck = new List + { + musicDetail.SongName, + musicDetail.SongNameEN, + musicDetail.SongNameCN, + musicDetail.SongNameKO, + }; + + if (!string.IsNullOrEmpty(Search) && !stringsToCheck.Any(s => s.Contains(Search, StringComparison.OrdinalIgnoreCase))) + { + return false; + } + + return true; + } + + private void Select(MusicDetail musicDetail, Difficulty difficulty, int level) + { + MudDialog.Close(DialogResult.Ok(new SongInfo() + { + MusicDetail = musicDetail, + Difficulty = difficulty, + Level = level, + })); + } + + private void Cancel() + { + MudDialog.Cancel(); + } + +} \ No newline at end of file diff --git a/TaikoWebUI/Pages/Dialogs/ChooseUserDialog.razor b/TaikoWebUI/Pages/Dialogs/ChooseUserDialog.razor new file mode 100644 index 00000000..9f7dc7f9 --- /dev/null +++ b/TaikoWebUI/Pages/Dialogs/ChooseUserDialog.razor @@ -0,0 +1,102 @@ +@using Blazored.LocalStorage +@using TaikoWebUI.Utilities; + +@inject IJSRuntime Js +@inject ILocalStorageService LocalStorage +@inject HttpClient HttpClient + + + + + + + + + + + + + + + @Localizer["User ID"] + + + + + @Localizer["Users"] + + + + + @context.Baid + + @context.UserSetting.MyDonName + + + + + + + + + + @Localizer["Cancel"] + + + + +@code { + + [CascadingParameter] MudDialogInstance MudDialog { get; set; } = null!; + + [Parameter] public int Exclude { get; set; } = 0; + + private Dictionary userDict = new(); + + private string Search { get; set; } = string.Empty; + + private string searchString = string.Empty; + + protected override async Task OnInitializedAsync() + { + base.OnInitialized(); + Dictionary? dict = await HttpClient.GetFromJsonAsync>($"api/Users/{Exclude}/AllUserDict"); + dict.ThrowIfNull(); + userDict = dict; + } + + private bool FilterUser(User user) + { + var stringsToCheck = new List + { + user.Baid + "", + user.UserSetting.MyDonName + }; + + if (!string.IsNullOrEmpty(Search) && !stringsToCheck.Any(s => s.Contains(Search, StringComparison.OrdinalIgnoreCase))) + { + return false; + } + + return true; + } + + private void Select(User user) + { + MudDialog.Close(DialogResult.Ok(user)); + } + + private void Cancel() + { + MudDialog.Cancel(); + } + +} \ No newline at end of file diff --git a/TaikoWebUI/Pages/OfficialCompete.razor b/TaikoWebUI/Pages/OfficialCompete.razor new file mode 100644 index 00000000..5850db2c --- /dev/null +++ b/TaikoWebUI/Pages/OfficialCompete.razor @@ -0,0 +1,10 @@ +@using TaikoWebUI.Components; + +@page "/ChallengeCompe/{baid:int}/OfficialCompetition" + + + +@code { + [Parameter] + public int Baid { get; set; } +}