From 0042f9afce287c39f54ffe56b7d361a4c937060c Mon Sep 17 00:00:00 2001 From: asesidaa <1061472754@qq.com> Date: Mon, 18 Mar 2024 01:00:49 +0800 Subject: [PATCH] Split remaining fields --- GameDatabase/Entities/UserDatum.cs | 18 +- ...0317153533_SplitCurrentCostume.Designer.cs | 554 +++++++++++++++++ .../20240317153533_SplitCurrentCostume.cs | 81 +++ ...17163817_SplitDifficultyArrays.Designer.cs | 572 ++++++++++++++++++ .../20240317163817_SplitDifficultyArrays.cs | 95 +++ .../Migrations/TaikoDbContextModelSnapshot.cs | 35 +- TaikoLocalServer/Common/Utils/JsonHelper.cs | 26 +- .../Controllers/Api/UserSettingsController.cs | 41 +- TaikoLocalServer/Handlers/BaidQuery.cs | 6 +- .../Handlers/UpdatePlayResultCommand.cs | 12 +- TaikoLocalServer/Handlers/UserDataQuery.cs | 12 +- .../Application/CommonPlayResultData.cs | 80 +-- 12 files changed, 1426 insertions(+), 106 deletions(-) create mode 100644 GameDatabase/Migrations/20240317153533_SplitCurrentCostume.Designer.cs create mode 100644 GameDatabase/Migrations/20240317153533_SplitCurrentCostume.cs create mode 100644 GameDatabase/Migrations/20240317163817_SplitDifficultyArrays.Designer.cs create mode 100644 GameDatabase/Migrations/20240317163817_SplitDifficultyArrays.cs diff --git a/GameDatabase/Entities/UserDatum.cs b/GameDatabase/Entities/UserDatum.cs index 5c97058..f700fb6 100644 --- a/GameDatabase/Entities/UserDatum.cs +++ b/GameDatabase/Entities/UserDatum.cs @@ -23,24 +23,34 @@ namespace GameDatabase.Entities public int NotesPosition { get; set; } public bool IsVoiceOn { get; set; } public bool IsSkipOn { get; set; } - // TODO: Split into separate fields public string DifficultyPlayedArray { get; set; } = "[]"; - // TODO: Split into separate fields + public uint DifficultyPlayedCourse { get; set; } + public uint DifficultyPlayedStar { get; set; } + public uint DifficultyPlayedSort { get; set; } + public string DifficultySettingArray { get; set; } = "[]"; + public uint DifficultySettingCourse { get; set; } + public uint DifficultySettingStar { get; set; } + public uint DifficultySettingSort { get; set; } public uint SelectedToneId { get; set; } public DateTime LastPlayDatetime { get; set; } public uint LastPlayMode { get; set; } public uint ColorBody { get; set; } public uint ColorFace { get; set; } public uint ColorLimb { get; set; } - // TODO: Split into separate fields + public string CostumeData { 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; } public bool DisplayDan { get; set; } public bool DisplayAchievement { get; set; } public Difficulty AchievementDisplayDifficulty { get; set; } public int AiWinCount { get; set; } public List Tokens { get; set; } = new(); - public List UnlockedSongIdList { get; set; } = []; + public List UnlockedSongIdList { get; set; } = []; public bool IsAdmin { get; set; } } } \ No newline at end of file diff --git a/GameDatabase/Migrations/20240317153533_SplitCurrentCostume.Designer.cs b/GameDatabase/Migrations/20240317153533_SplitCurrentCostume.Designer.cs new file mode 100644 index 0000000..a4c7f0f --- /dev/null +++ b/GameDatabase/Migrations/20240317153533_SplitCurrentCostume.Designer.cs @@ -0,0 +1,554 @@ +// +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("20240317153533_SplitCurrentCostume")] + partial class SplitCurrentCostume + { + /// + 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.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("DifficultySettingArray") + .IsRequired() + .HasColumnType("TEXT"); + + 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.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.DanScoreDatum", b => + { + b.Navigation("DanStageScoreData"); + }); + + modelBuilder.Entity("GameDatabase.Entities.UserDatum", b => + { + b.Navigation("Tokens"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/GameDatabase/Migrations/20240317153533_SplitCurrentCostume.cs b/GameDatabase/Migrations/20240317153533_SplitCurrentCostume.cs new file mode 100644 index 0000000..f355a1f --- /dev/null +++ b/GameDatabase/Migrations/20240317153533_SplitCurrentCostume.cs @@ -0,0 +1,81 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace GameDatabase.Migrations +{ + /// + public partial class SplitCurrentCostume : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "CurrentBody", + table: "UserData", + type: "INTEGER", + nullable: false, + defaultValue: 0u); + + migrationBuilder.AddColumn( + name: "CurrentFace", + table: "UserData", + type: "INTEGER", + nullable: false, + defaultValue: 0u); + + migrationBuilder.AddColumn( + name: "CurrentHead", + table: "UserData", + type: "INTEGER", + nullable: false, + defaultValue: 0u); + + migrationBuilder.AddColumn( + name: "CurrentKigurumi", + table: "UserData", + type: "INTEGER", + nullable: false, + defaultValue: 0u); + + migrationBuilder.AddColumn( + name: "CurrentPuchi", + table: "UserData", + type: "INTEGER", + nullable: false, + defaultValue: 0u); + // Split CostumeData (json array) into the new fields + migrationBuilder.Sql(@" + UPDATE UserData + SET CurrentKigurumi = json_extract(CostumeData, '$[0]'), + CurrentHead = json_extract(CostumeData, '$[1]'), + CurrentBody = json_extract(CostumeData, '$[2]'), + CurrentFace = json_extract(CostumeData, '$[3]'), + CurrentPuchi = json_extract(CostumeData, '$[4]')"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "CurrentBody", + table: "UserData"); + + migrationBuilder.DropColumn( + name: "CurrentFace", + table: "UserData"); + + migrationBuilder.DropColumn( + name: "CurrentHead", + table: "UserData"); + + migrationBuilder.DropColumn( + name: "CurrentKigurumi", + table: "UserData"); + + migrationBuilder.DropColumn( + name: "CurrentPuchi", + table: "UserData"); + } + } +} diff --git a/GameDatabase/Migrations/20240317163817_SplitDifficultyArrays.Designer.cs b/GameDatabase/Migrations/20240317163817_SplitDifficultyArrays.Designer.cs new file mode 100644 index 0000000..c892c07 --- /dev/null +++ b/GameDatabase/Migrations/20240317163817_SplitDifficultyArrays.Designer.cs @@ -0,0 +1,572 @@ +// +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("20240317163817_SplitDifficultyArrays")] + partial class SplitDifficultyArrays + { + /// + 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.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.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.DanScoreDatum", b => + { + b.Navigation("DanStageScoreData"); + }); + + modelBuilder.Entity("GameDatabase.Entities.UserDatum", b => + { + b.Navigation("Tokens"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/GameDatabase/Migrations/20240317163817_SplitDifficultyArrays.cs b/GameDatabase/Migrations/20240317163817_SplitDifficultyArrays.cs new file mode 100644 index 0000000..539d611 --- /dev/null +++ b/GameDatabase/Migrations/20240317163817_SplitDifficultyArrays.cs @@ -0,0 +1,95 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace GameDatabase.Migrations +{ + /// + public partial class SplitDifficultyArrays : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "DifficultyPlayedCourse", + table: "UserData", + type: "INTEGER", + nullable: false, + defaultValue: 0u); + + migrationBuilder.AddColumn( + name: "DifficultyPlayedSort", + table: "UserData", + type: "INTEGER", + nullable: false, + defaultValue: 0u); + + migrationBuilder.AddColumn( + name: "DifficultyPlayedStar", + table: "UserData", + type: "INTEGER", + nullable: false, + defaultValue: 0u); + + migrationBuilder.AddColumn( + name: "DifficultySettingCourse", + table: "UserData", + type: "INTEGER", + nullable: false, + defaultValue: 0u); + + migrationBuilder.AddColumn( + name: "DifficultySettingSort", + table: "UserData", + type: "INTEGER", + nullable: false, + defaultValue: 0u); + + migrationBuilder.AddColumn( + name: "DifficultySettingStar", + table: "UserData", + type: "INTEGER", + nullable: false, + defaultValue: 0u); + + // Extract from json arrays + migrationBuilder.Sql(@" + UPDATE UserData + SET DifficultyPlayedCourse = json_extract(DifficultyPlayedArray, '$[0]'), + DifficultyPlayedStar = json_extract(DifficultyPlayedArray, '$[1]'), + DifficultyPlayedSort = json_extract(DifficultyPlayedArray, '$[2]') , + DifficultySettingCourse = json_extract(DifficultySettingArray, '$[0]'), + DifficultySettingStar = json_extract(DifficultySettingArray, '$[1]'), + DifficultySettingSort = json_extract(DifficultySettingArray, '$[2]'); + "); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "DifficultyPlayedCourse", + table: "UserData"); + + migrationBuilder.DropColumn( + name: "DifficultyPlayedSort", + table: "UserData"); + + migrationBuilder.DropColumn( + name: "DifficultyPlayedStar", + table: "UserData"); + + migrationBuilder.DropColumn( + name: "DifficultySettingCourse", + table: "UserData"); + + migrationBuilder.DropColumn( + name: "DifficultySettingSort", + table: "UserData"); + + migrationBuilder.DropColumn( + name: "DifficultySettingStar", + table: "UserData"); + } + } +} diff --git a/GameDatabase/Migrations/TaikoDbContextModelSnapshot.cs b/GameDatabase/Migrations/TaikoDbContextModelSnapshot.cs index f4b1848..8fa0e9f 100644 --- a/GameDatabase/Migrations/TaikoDbContextModelSnapshot.cs +++ b/GameDatabase/Migrations/TaikoDbContextModelSnapshot.cs @@ -15,7 +15,7 @@ namespace TaikoLocalServer.Migrations protected override void BuildModel(ModelBuilder modelBuilder) { #pragma warning disable 612, 618 - modelBuilder.HasAnnotation("ProductVersion", "8.0.0-rc.2.23480.1"); + modelBuilder.HasAnnotation("ProductVersion", "8.0.3"); modelBuilder.Entity("GameDatabase.Entities.AiScoreDatum", b => { @@ -320,14 +320,47 @@ namespace TaikoLocalServer.Migrations .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"); diff --git a/TaikoLocalServer/Common/Utils/JsonHelper.cs b/TaikoLocalServer/Common/Utils/JsonHelper.cs index f86a724..85be317 100644 --- a/TaikoLocalServer/Common/Utils/JsonHelper.cs +++ b/TaikoLocalServer/Common/Utils/JsonHelper.cs @@ -22,33 +22,9 @@ public static class JsonHelper return array; } - logger.LogWarning($"{fieldName} is null or length less than {length}!"); + logger.LogWarning("{FieldName} is null or length less than {Length}!", fieldName, length); array = new uint[length]; return array; } - - public static List GetCostumeDataFromUserData(UserDatum userData, ILogger logger) - { - var costumeData = new List { 0, 0, 0, 0, 0 }; - try - { - // logger.LogInformation(userData.CostumeData); - costumeData = JsonSerializer.Deserialize>(userData.CostumeData); - } - catch (JsonException e) - { - logger.LogError(e, "Parsing costume json data failed"); - } - - if (costumeData != null && costumeData.Count >= 5) - { - return costumeData; - } - - logger.LogWarning("Costume data is null or count less than 5!"); - costumeData = new List { 0, 0, 0, 0, 0 }; - - return costumeData; - } } \ No newline at end of file diff --git a/TaikoLocalServer/Controllers/Api/UserSettingsController.cs b/TaikoLocalServer/Controllers/Api/UserSettingsController.cs index fb624c1..dcf05d0 100644 --- a/TaikoLocalServer/Controllers/Api/UserSettingsController.cs +++ b/TaikoLocalServer/Controllers/Api/UserSettingsController.cs @@ -25,11 +25,6 @@ public class UserSettingsController : BaseController return NotFound(); } - var difficultySettingArray = JsonHelper.GetUIntArrayFromJson(user.DifficultySettingArray, 3, Logger, - nameof(user.DifficultySettingArray)); - - var costumeData = JsonHelper.GetCostumeDataFromUserData(user, Logger); - List> costumeUnlockData = [user.UnlockedKigurumi, user.UnlockedHead, user.UnlockedBody, user.UnlockedFace, user.UnlockedPuchi]; @@ -49,9 +44,9 @@ public class UserSettingsController : BaseController AchievementDisplayDifficulty = user.AchievementDisplayDifficulty, IsDisplayAchievement = user.DisplayAchievement, IsDisplayDanOnNamePlate = user.DisplayDan, - DifficultySettingCourse = difficultySettingArray[0], - DifficultySettingStar = difficultySettingArray[1], - DifficultySettingSort = difficultySettingArray[2], + DifficultySettingCourse = user.DifficultySettingCourse, + DifficultySettingStar = user.DifficultySettingStar, + DifficultySettingSort = user.DifficultySettingSort, IsVoiceOn = user.IsVoiceOn, IsSkipOn = user.IsSkipOn, NotesPosition = user.NotesPosition, @@ -61,11 +56,11 @@ public class UserSettingsController : BaseController MyDonNameLanguage = user.MyDonNameLanguage, Title = user.Title, TitlePlateId = user.TitlePlateId, - Kigurumi = costumeData[0], - Head = costumeData[1], - Body = costumeData[2], - Face = costumeData[3], - Puchi = costumeData[4], + Kigurumi = user.CurrentKigurumi, + Head = user.CurrentHead, + Body = user.CurrentBody, + Face = user.CurrentFace, + Puchi = user.CurrentPuchi, UnlockedKigurumi = costumeUnlockData[0], UnlockedHead = costumeUnlockData[1], UnlockedBody = costumeUnlockData[2], @@ -90,15 +85,6 @@ public class UserSettingsController : BaseController return NotFound(); } - var costumes = new List - { - userSetting.Kigurumi, - userSetting.Head, - userSetting.Body, - userSetting.Face, - userSetting.Puchi, - }; - var difficultySettings = new List { userSetting.DifficultySettingCourse, @@ -110,7 +96,9 @@ public class UserSettingsController : BaseController user.IsVoiceOn = userSetting.IsVoiceOn; user.DisplayAchievement = userSetting.IsDisplayAchievement; user.DisplayDan = userSetting.IsDisplayDanOnNamePlate; - user.DifficultySettingArray = JsonSerializer.Serialize(difficultySettings); + user.DifficultySettingCourse = userSetting.DifficultySettingCourse; + user.DifficultySettingStar = userSetting.DifficultySettingStar; + user.DifficultySettingSort = userSetting.DifficultySettingSort; user.NotesPosition = userSetting.NotesPosition; user.SelectedToneId = userSetting.ToneId; user.AchievementDisplayDifficulty = userSetting.AchievementDisplayDifficulty; @@ -122,7 +110,12 @@ public class UserSettingsController : BaseController user.ColorBody = userSetting.BodyColor; user.ColorFace = userSetting.FaceColor; user.ColorLimb = userSetting.LimbColor; - user.CostumeData = JsonSerializer.Serialize(costumes); + // user.CostumeData = JsonSerializer.Serialize(costumes); + user.CurrentKigurumi = userSetting.Kigurumi; + user.CurrentHead = userSetting.Head; + user.CurrentBody = userSetting.Body; + user.CurrentFace = userSetting.Face; + user.CurrentPuchi = userSetting.Puchi; // If a locked tone is selected, unlock it var toneFlg = user.ToneFlgArray; diff --git a/TaikoLocalServer/Handlers/BaidQuery.cs b/TaikoLocalServer/Handlers/BaidQuery.cs index ef20ee1..a4fe168 100644 --- a/TaikoLocalServer/Handlers/BaidQuery.cs +++ b/TaikoLocalServer/Handlers/BaidQuery.cs @@ -66,9 +66,9 @@ public class BaidQueryHandler( scoreRankCount[(int)scoreRank - 2] = scoreRankData.GetValueOrDefault(scoreRank, (uint)0); } } - - var costumeData = JsonHelper.GetCostumeDataFromUserData(userData, logger); - + + List costumeData = [userData.CurrentKigurumi, userData.CurrentHead, userData.CurrentBody, userData.CurrentFace, userData.CurrentPuchi]; + List> costumeArrays = [userData.UnlockedKigurumi, userData.UnlockedHead, userData.UnlockedBody, userData.UnlockedFace, userData.UnlockedPuchi]; diff --git a/TaikoLocalServer/Handlers/UpdatePlayResultCommand.cs b/TaikoLocalServer/Handlers/UpdatePlayResultCommand.cs index 66761d8..cfa8598 100644 --- a/TaikoLocalServer/Handlers/UpdatePlayResultCommand.cs +++ b/TaikoLocalServer/Handlers/UpdatePlayResultCommand.cs @@ -238,7 +238,12 @@ public class UpdatePlayResultCommandHandler(TaikoDbContext context, ILogger data.IsWin); } diff --git a/TaikoLocalServer/Handlers/UserDataQuery.cs b/TaikoLocalServer/Handlers/UserDataQuery.cs index 4e38340..20cc93a 100644 --- a/TaikoLocalServer/Handlers/UserDataQuery.cs +++ b/TaikoLocalServer/Handlers/UserDataQuery.cs @@ -64,7 +64,7 @@ public class UserDataQueryHandler(TaikoDbContext context, IGameDataService gameD var defaultOptions = new byte[2]; BinaryPrimitives.WriteInt16LittleEndian(defaultOptions, userData.OptionSetting); - var difficultySettingArray = JsonHelper.GetUIntArrayFromJson(userData.DifficultySettingArray, 3, logger, nameof(userData.DifficultySettingArray)); + uint[] difficultySettingArray = [userData.DifficultySettingCourse, userData.DifficultySettingStar, userData.DifficultySettingSort]; for (int i = 0; i < 3; i++) { if (difficultySettingArray[i] >= 2) @@ -72,9 +72,7 @@ public class UserDataQueryHandler(TaikoDbContext context, IGameDataService gameD difficultySettingArray[i] -= 1; } } - - var difficultyPlayedArray = JsonHelper.GetUIntArrayFromJson(userData.DifficultyPlayedArray, 3, logger, nameof(userData.DifficultyPlayedArray)); - + var response = new CommonUserDataResponse { Result = 1, @@ -91,9 +89,9 @@ public class UserDataQueryHandler(TaikoDbContext context, IGameDataService gameD DifficultySettingCourse = difficultySettingArray[0], DifficultySettingStar = difficultySettingArray[1], DifficultySettingSort = difficultySettingArray[2], - DifficultyPlayedCourse = difficultyPlayedArray[0], - DifficultyPlayedStar = difficultyPlayedArray[1], - DifficultyPlayedSort = difficultyPlayedArray[2], + DifficultyPlayedCourse = userData.DifficultyPlayedCourse, + DifficultyPlayedStar = userData.DifficultyPlayedStar, + DifficultyPlayedSort = userData.DifficultyPlayedSort, SongRecentCnt = (uint)recentSongs.Length, IsChallengecompe = false, // TODO: Other fields diff --git a/TaikoLocalServer/Models/Application/CommonPlayResultData.cs b/TaikoLocalServer/Models/Application/CommonPlayResultData.cs index 33189e0..f34e61b 100644 --- a/TaikoLocalServer/Models/Application/CommonPlayResultData.cs +++ b/TaikoLocalServer/Models/Application/CommonPlayResultData.cs @@ -3,46 +3,46 @@ namespace TaikoLocalServer.Models.Application; public class CommonPlayResultData { - public uint Baid { get; set; } - public string ChassisId { get; set; } = string.Empty; - public string ShopId { get; set; } = string.Empty; - public string PlayDatetime { get; set; } = string.Empty; - public bool IsRight { get; set; } - public uint CardType { get; set; } - public bool IsTwoPlayers { get; set; } - public List AryStageInfoes { get; set; } = []; - public List ReleaseSongNoes { get; set; } = []; - public List UraReleaseSongNoes { get; set; } = []; - public List GetToneNoes { get; set; } = []; - public List GetCostumeNo1s { get; set; } = []; - public List GetCostumeNo2s { get; set; } = []; - public List GetCostumeNo3s { get; set; } = []; - public List GetCostumeNo4s { get; set; } = []; - public List GetCostumeNo5s { get; set; } = []; - public List GetTitleNoes { get; set; } = []; - public List GetGenericInfoNoes { get; set; } = []; - public CostumeData AryPlayCostume { get; set; } = new(); - public CostumeData AryCurrentCostume { get; set; } = new(); - public string Title { get; set; } = string.Empty; - public uint TitleplateId { get; set; } - public uint PlayMode { get; set; } - public uint CollaborationId { get; set; } - public uint DanId { get; set; } - public uint DanResult { get; set; } - public uint SoulGaugeTotal { get; set; } - public uint ComboCntTotal { get; set; } - public bool IsNotRecordedDan { get; set; } - public uint AreaCode { get; set; } - public byte[] Reserved { get; set; } = []; - public uint TournamentMode { get; set; } - public string Accesstoken { get; set; } = string.Empty; - public byte[] ContentInfo { get; set; } = []; - public uint DifficultyPlayedCourse { get; set; } - public uint DifficultyPlayedStar { get; set; } - public uint DifficultyPlayedSort { get; set; } - public uint IsRandomUsePlay { get; set; } - public string InputMedian { get; set; } = string.Empty; - public string InputVariance { get; set; } = string.Empty; + public uint Baid { get; set; } + public string ChassisId { get; set; } = string.Empty; + public string ShopId { get; set; } = string.Empty; + public string PlayDatetime { get; set; } = string.Empty; + public bool IsRight { get; set; } + public uint CardType { get; set; } + public bool IsTwoPlayers { get; set; } + public List AryStageInfoes { get; set; } = []; + public List ReleaseSongNoes { get; set; } = []; + public List UraReleaseSongNoes { get; set; } = []; + public List GetToneNoes { get; set; } = []; + public List GetCostumeNo1s { get; set; } = []; + public List GetCostumeNo2s { get; set; } = []; + public List GetCostumeNo3s { get; set; } = []; + public List GetCostumeNo4s { get; set; } = []; + public List GetCostumeNo5s { get; set; } = []; + public List GetTitleNoes { get; set; } = []; + public List GetGenericInfoNoes { get; set; } = []; + public CostumeData AryPlayCostume { get; set; } = new(); + public CostumeData AryCurrentCostume { get; set; } = new(); + public string Title { get; set; } = string.Empty; + public uint TitleplateId { get; set; } + public uint PlayMode { get; set; } + public uint CollaborationId { get; set; } + public uint DanId { get; set; } + public uint DanResult { get; set; } + public uint SoulGaugeTotal { get; set; } + public uint ComboCntTotal { get; set; } + public bool IsNotRecordedDan { get; set; } + public uint AreaCode { get; set; } + public byte[] Reserved { get; set; } = []; + public uint TournamentMode { get; set; } + public string Accesstoken { get; set; } = string.Empty; + public byte[] ContentInfo { get; set; } = []; + public uint DifficultyPlayedCourse { get; set; } + public uint DifficultyPlayedStar { get; set; } + public uint DifficultyPlayedSort { get; set; } + public uint IsRandomUsePlay { get; set; } + public string InputMedian { get; set; } = string.Empty; + public string InputVariance { get; set; } = string.Empty; public class StageData {