diff --git a/SharedProject/Models/SongBestData.cs b/SharedProject/Models/SongBestData.cs index e674c5c..003673b 100644 --- a/SharedProject/Models/SongBestData.cs +++ b/SharedProject/Models/SongBestData.cs @@ -19,4 +19,16 @@ public class SongBestData public DateTime LastPlayTime { get; set; } public bool IsFavorite { 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; } } \ No newline at end of file diff --git a/TaikoLocalServer/Controllers/Game/PlayResultController.cs b/TaikoLocalServer/Controllers/Game/PlayResultController.cs index 31f01ff..67cb523 100644 --- a/TaikoLocalServer/Controllers/Game/PlayResultController.cs +++ b/TaikoLocalServer/Controllers/Game/PlayResultController.cs @@ -141,6 +141,7 @@ public class PlayResultController : BaseController MissCount = stageData.NgCnt, ComboCount = stageData.ComboCnt, HitCount = stageData.HitCnt, + DrumrollCount = stageData.PoundCnt, Crown = PlayResultToCrown(stageData), Score = stageData.PlayScore, ScoreRate = stageData.ScoreRate, diff --git a/TaikoLocalServer/Entities/SongPlayDatum.cs b/TaikoLocalServer/Entities/SongPlayDatum.cs index 0b18c68..a6893c5 100644 --- a/TaikoLocalServer/Entities/SongPlayDatum.cs +++ b/TaikoLocalServer/Entities/SongPlayDatum.cs @@ -18,6 +18,7 @@ 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 DateTime PlayTime { get; set; } diff --git a/TaikoLocalServer/Migrations/20220910055624_AddDrumrollCount.Designer.cs b/TaikoLocalServer/Migrations/20220910055624_AddDrumrollCount.Designer.cs new file mode 100644 index 0000000..fb0964e --- /dev/null +++ b/TaikoLocalServer/Migrations/20220910055624_AddDrumrollCount.Designer.cs @@ -0,0 +1,329 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using TaikoLocalServer.Context; + +#nullable disable + +namespace TaikoLocalServer.Migrations +{ + [DbContext(typeof(TaikoDbContext))] + [Migration("20220910055624_AddDrumrollCount")] + partial class AddDrumrollCount + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder.HasAnnotation("ProductVersion", "7.0.0-preview.7.22376.2"); + + modelBuilder.Entity("TaikoLocalServer.Entities.Card", b => + { + b.Property("AccessCode") + .HasColumnType("TEXT"); + + b.Property("Baid") + .HasColumnType("INTEGER"); + + b.HasKey("AccessCode"); + + b.HasIndex(new[] { "Baid" }, "IX_Card_Baid") + .IsUnique(); + + b.ToTable("Card", (string)null); + }); + + modelBuilder.Entity("TaikoLocalServer.Entities.DanScoreDatum", b => + { + b.Property("Baid") + .HasColumnType("INTEGER"); + + b.Property("DanId") + .HasColumnType("INTEGER"); + + 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"); + + b.ToTable("DanScoreData"); + }); + + modelBuilder.Entity("TaikoLocalServer.Entities.DanStageScoreDatum", b => + { + b.Property("Baid") + .HasColumnType("INTEGER"); + + b.Property("DanId") + .HasColumnType("INTEGER"); + + 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", "SongNumber"); + + b.ToTable("DanStageScoreData"); + }); + + modelBuilder.Entity("TaikoLocalServer.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("TaikoLocalServer.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("TaikoLocalServer.Entities.UserDatum", b => + { + b.Property("Baid") + .HasColumnType("INTEGER"); + + b.Property("AchievementDisplayDifficulty") + .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("DisplayAchievement") + .HasColumnType("INTEGER"); + + b.Property("DisplayDan") + .HasColumnType("INTEGER"); + + b.Property("FavoriteSongsArray") + .IsRequired() + .HasColumnType("TEXT"); + + 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("NotesPosition") + .HasColumnType("INTEGER"); + + b.Property("OptionSetting") + .HasColumnType("INTEGER"); + + b.Property("SelectedToneId") + .HasColumnType("INTEGER"); + + b.Property("Title") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("TitlePlateId") + .HasColumnType("INTEGER"); + + b.HasKey("Baid"); + + b.ToTable("UserData"); + }); + + modelBuilder.Entity("TaikoLocalServer.Entities.DanScoreDatum", b => + { + b.HasOne("TaikoLocalServer.Entities.Card", "Ba") + .WithMany() + .HasForeignKey("Baid") + .HasPrincipalKey("Baid") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Ba"); + }); + + modelBuilder.Entity("TaikoLocalServer.Entities.DanStageScoreDatum", b => + { + b.HasOne("TaikoLocalServer.Entities.DanScoreDatum", "Parent") + .WithMany("DanStageScoreData") + .HasForeignKey("Baid", "DanId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Parent"); + }); + + modelBuilder.Entity("TaikoLocalServer.Entities.SongBestDatum", b => + { + b.HasOne("TaikoLocalServer.Entities.Card", "Ba") + .WithMany() + .HasForeignKey("Baid") + .HasPrincipalKey("Baid") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Ba"); + }); + + modelBuilder.Entity("TaikoLocalServer.Entities.SongPlayDatum", b => + { + b.HasOne("TaikoLocalServer.Entities.Card", "Ba") + .WithMany() + .HasForeignKey("Baid") + .HasPrincipalKey("Baid") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Ba"); + }); + + modelBuilder.Entity("TaikoLocalServer.Entities.UserDatum", b => + { + b.HasOne("TaikoLocalServer.Entities.Card", "Ba") + .WithMany() + .HasForeignKey("Baid") + .HasPrincipalKey("Baid") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Ba"); + }); + + modelBuilder.Entity("TaikoLocalServer.Entities.DanScoreDatum", b => + { + b.Navigation("DanStageScoreData"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/TaikoLocalServer/Migrations/20220910055624_AddDrumrollCount.cs b/TaikoLocalServer/Migrations/20220910055624_AddDrumrollCount.cs new file mode 100644 index 0000000..3805ed4 --- /dev/null +++ b/TaikoLocalServer/Migrations/20220910055624_AddDrumrollCount.cs @@ -0,0 +1,29 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace TaikoLocalServer.Migrations +{ + /// + public partial class AddDrumrollCount : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "DrumrollCount", + table: "SongPlayData", + type: "INTEGER", + nullable: false, + defaultValue: 0u); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "DrumrollCount", + table: "SongPlayData"); + } + } +} diff --git a/TaikoLocalServer/Migrations/TaikoDbContextModelSnapshot.cs b/TaikoLocalServer/Migrations/TaikoDbContextModelSnapshot.cs index 2562bd1..b775c53 100644 --- a/TaikoLocalServer/Migrations/TaikoDbContextModelSnapshot.cs +++ b/TaikoLocalServer/Migrations/TaikoDbContextModelSnapshot.cs @@ -57,7 +57,7 @@ namespace TaikoLocalServer.Migrations b.HasKey("Baid", "DanId"); - b.ToTable("DanScoreData"); + b.ToTable("DanScoreData", (string)null); }); modelBuilder.Entity("TaikoLocalServer.Entities.DanStageScoreDatum", b => @@ -97,7 +97,7 @@ namespace TaikoLocalServer.Migrations b.HasKey("Baid", "DanId", "SongNumber"); - b.ToTable("DanStageScoreData"); + b.ToTable("DanStageScoreData", (string)null); }); modelBuilder.Entity("TaikoLocalServer.Entities.SongBestDatum", b => @@ -125,7 +125,7 @@ namespace TaikoLocalServer.Migrations b.HasKey("Baid", "SongId", "Difficulty"); - b.ToTable("SongBestData"); + b.ToTable("SongBestData", (string)null); }); modelBuilder.Entity("TaikoLocalServer.Entities.SongPlayDatum", b => @@ -146,6 +146,9 @@ namespace TaikoLocalServer.Migrations b.Property("Difficulty") .HasColumnType("INTEGER"); + b.Property("DrumrollCount") + .HasColumnType("INTEGER"); + b.Property("GoodCount") .HasColumnType("INTEGER"); @@ -183,7 +186,7 @@ namespace TaikoLocalServer.Migrations b.HasIndex("Baid"); - b.ToTable("SongPlayData"); + b.ToTable("SongPlayData", (string)null); }); modelBuilder.Entity("TaikoLocalServer.Entities.UserDatum", b => @@ -251,7 +254,7 @@ namespace TaikoLocalServer.Migrations b.HasKey("Baid"); - b.ToTable("UserData"); + b.ToTable("UserData", (string)null); }); modelBuilder.Entity("TaikoLocalServer.Entities.DanScoreDatum", b => diff --git a/TaikoLocalServer/Services/SongBestDatumService.cs b/TaikoLocalServer/Services/SongBestDatumService.cs index 33b7a98..b596e9e 100644 --- a/TaikoLocalServer/Services/SongBestDatumService.cs +++ b/TaikoLocalServer/Services/SongBestDatumService.cs @@ -38,18 +38,33 @@ public class SongBestDatumService : ISongBestDatumService public async Task> GetAllSongBestAsModel(uint baid) { - var songbestDbData = await context.SongBestData.Where(datum => datum.Baid == baid).ToListAsync(); + var songbestDbData = await context.SongBestData.Where(datum => datum.Baid == baid) + .ToListAsync(); var result = songbestDbData.Select(datum => datum.CopyPropertiesToNew()).ToList(); var playLogs = await context.SongPlayData.Where(datum => datum.Baid == baid).ToListAsync(); foreach (var bestData in result) { - var lastPlayLog = playLogs.Where(datum => datum.Difficulty == bestData.Difficulty && - datum.SongId == bestData.SongId) + var songPlayDatums = playLogs.Where(datum => datum.Difficulty == bestData.Difficulty && + datum.SongId == bestData.SongId).ToArray(); + songPlayDatums.Throw($"Play log for song id {bestData.SongId} is null! " + + "Something is wrong with db!") + .IfEmpty(); + var lastPlayLog = songPlayDatums .MaxBy(datum => datum.PlayTime); - lastPlayLog.ThrowIfNull("Last play log is null! Something is wrong with db!"); - bestData.LastPlayTime = lastPlayLog.PlayTime; + bestData.LastPlayTime = lastPlayLog!.PlayTime; + + var bestLog = songPlayDatums + .MaxBy(datum => datum.Score); + bestLog.CopyOnlyPropertiesTo(bestData, + nameof(SongPlayDatum.GoodCount), + nameof(SongPlayDatum.OkCount), + nameof(SongPlayDatum.MissCount), + nameof(SongPlayDatum.HitCount), + nameof(SongPlayDatum.DrumrollCount), + nameof(SongPlayDatum.ComboCount) + ); } return result; diff --git a/TaikoWebUI/Pages/PlayResults.razor b/TaikoWebUI/Pages/PlayResults.razor index df385fe..dc82e47 100644 --- a/TaikoWebUI/Pages/PlayResults.razor +++ b/TaikoWebUI/Pages/PlayResults.razor @@ -2,6 +2,7 @@ @using SharedProject.Models.Responses @using SharedProject.Models @using SharedProject.Models.Requests +@using SharedProject.Enums @inject IGameDataService GameDataService @inject HttpClient Client @@ -42,13 +43,19 @@ else - + @(context.Item.BestCrown) + + + + + + "Fail", - "Clear" => "Cleared", - "Gold" => "Full Combo", - "Dondaful" => "Donderful Combo", + CrownType.None => "Fail", + CrownType.Clear => "Cleared", + CrownType.Gold => "Full Combo", + CrownType.Dondaful => "Donderful Combo", _ => "" }; } diff --git a/TaikoWebUI/wwwroot/appsettings.Development.json b/TaikoWebUI/wwwroot/appsettings.Development.json new file mode 100644 index 0000000..cbe7f7d --- /dev/null +++ b/TaikoWebUI/wwwroot/appsettings.Development.json @@ -0,0 +1,3 @@ +{ + "DataBaseUrl": "https://localhost:44398" +} \ No newline at end of file diff --git a/TaikoWebUI/wwwroot/appsettings.json b/TaikoWebUI/wwwroot/appsettings.json index 44139dc..e575e49 100644 --- a/TaikoWebUI/wwwroot/appsettings.json +++ b/TaikoWebUI/wwwroot/appsettings.json @@ -1,4 +1,3 @@ { - "BaseUrl": "http://localhost:5000", - "DataBaseUrl": "https://localhost:44398" + "BaseUrl": "http://localhost:5000" } \ No newline at end of file