1
0
mirror of synced 2024-11-24 06:50:15 +01:00

Add missing drum roll count to play log

Display play detail, update related api
This commit is contained in:
asesidaa 2022-09-10 14:35:17 +08:00
parent fdc7a18e8e
commit d2797097be
10 changed files with 417 additions and 18 deletions

View File

@ -19,4 +19,16 @@ public class SongBestData
public DateTime LastPlayTime { get; set; } public DateTime LastPlayTime { get; set; }
public bool IsFavorite { 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; }
} }

View File

@ -141,6 +141,7 @@ public class PlayResultController : BaseController<PlayResultController>
MissCount = stageData.NgCnt, MissCount = stageData.NgCnt,
ComboCount = stageData.ComboCnt, ComboCount = stageData.ComboCnt,
HitCount = stageData.HitCnt, HitCount = stageData.HitCnt,
DrumrollCount = stageData.PoundCnt,
Crown = PlayResultToCrown(stageData), Crown = PlayResultToCrown(stageData),
Score = stageData.PlayScore, Score = stageData.PlayScore,
ScoreRate = stageData.ScoreRate, ScoreRate = stageData.ScoreRate,

View File

@ -18,6 +18,7 @@
public uint MissCount { get; set; } public uint MissCount { get; set; }
public uint ComboCount { get; set; } public uint ComboCount { get; set; }
public uint HitCount { get; set; } public uint HitCount { get; set; }
public uint DrumrollCount { get; set; }
public bool Skipped { get; set; } public bool Skipped { get; set; }
public DateTime PlayTime { get; set; } public DateTime PlayTime { get; set; }

View File

@ -0,0 +1,329 @@
// <auto-generated />
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
{
/// <inheritdoc />
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<string>("AccessCode")
.HasColumnType("TEXT");
b.Property<uint>("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<uint>("Baid")
.HasColumnType("INTEGER");
b.Property<uint>("DanId")
.HasColumnType("INTEGER");
b.Property<uint>("ArrivalSongCount")
.HasColumnType("INTEGER");
b.Property<uint>("ClearState")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER")
.HasDefaultValue(0u);
b.Property<uint>("ComboCountTotal")
.HasColumnType("INTEGER");
b.Property<uint>("SoulGaugeTotal")
.HasColumnType("INTEGER");
b.HasKey("Baid", "DanId");
b.ToTable("DanScoreData");
});
modelBuilder.Entity("TaikoLocalServer.Entities.DanStageScoreDatum", b =>
{
b.Property<uint>("Baid")
.HasColumnType("INTEGER");
b.Property<uint>("DanId")
.HasColumnType("INTEGER");
b.Property<uint>("SongNumber")
.HasColumnType("INTEGER");
b.Property<uint>("BadCount")
.HasColumnType("INTEGER");
b.Property<uint>("ComboCount")
.HasColumnType("INTEGER");
b.Property<uint>("DrumrollCount")
.HasColumnType("INTEGER");
b.Property<uint>("GoodCount")
.HasColumnType("INTEGER");
b.Property<uint>("HighScore")
.HasColumnType("INTEGER");
b.Property<uint>("OkCount")
.HasColumnType("INTEGER");
b.Property<uint>("PlayScore")
.HasColumnType("INTEGER");
b.Property<uint>("TotalHitCount")
.HasColumnType("INTEGER");
b.HasKey("Baid", "DanId", "SongNumber");
b.ToTable("DanStageScoreData");
});
modelBuilder.Entity("TaikoLocalServer.Entities.SongBestDatum", b =>
{
b.Property<uint>("Baid")
.HasColumnType("INTEGER");
b.Property<uint>("SongId")
.HasColumnType("INTEGER");
b.Property<uint>("Difficulty")
.HasColumnType("INTEGER");
b.Property<uint>("BestCrown")
.HasColumnType("INTEGER");
b.Property<uint>("BestRate")
.HasColumnType("INTEGER");
b.Property<uint>("BestScore")
.HasColumnType("INTEGER");
b.Property<uint>("BestScoreRank")
.HasColumnType("INTEGER");
b.HasKey("Baid", "SongId", "Difficulty");
b.ToTable("SongBestData");
});
modelBuilder.Entity("TaikoLocalServer.Entities.SongPlayDatum", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<uint>("Baid")
.HasColumnType("INTEGER");
b.Property<uint>("ComboCount")
.HasColumnType("INTEGER");
b.Property<uint>("Crown")
.HasColumnType("INTEGER");
b.Property<uint>("Difficulty")
.HasColumnType("INTEGER");
b.Property<uint>("DrumrollCount")
.HasColumnType("INTEGER");
b.Property<uint>("GoodCount")
.HasColumnType("INTEGER");
b.Property<uint>("HitCount")
.HasColumnType("INTEGER");
b.Property<uint>("MissCount")
.HasColumnType("INTEGER");
b.Property<uint>("OkCount")
.HasColumnType("INTEGER");
b.Property<DateTime>("PlayTime")
.HasColumnType("datetime");
b.Property<uint>("Score")
.HasColumnType("INTEGER");
b.Property<uint>("ScoreRank")
.HasColumnType("INTEGER");
b.Property<uint>("ScoreRate")
.HasColumnType("INTEGER");
b.Property<bool>("Skipped")
.HasColumnType("INTEGER");
b.Property<uint>("SongId")
.HasColumnType("INTEGER");
b.Property<uint>("SongNumber")
.HasColumnType("INTEGER");
b.HasKey("Id");
b.HasIndex("Baid");
b.ToTable("SongPlayData");
});
modelBuilder.Entity("TaikoLocalServer.Entities.UserDatum", b =>
{
b.Property<uint>("Baid")
.HasColumnType("INTEGER");
b.Property<uint>("AchievementDisplayDifficulty")
.HasColumnType("INTEGER");
b.Property<uint>("ColorBody")
.HasColumnType("INTEGER");
b.Property<uint>("ColorFace")
.HasColumnType("INTEGER");
b.Property<uint>("ColorLimb")
.HasColumnType("INTEGER");
b.Property<string>("CostumeData")
.IsRequired()
.HasColumnType("TEXT");
b.Property<bool>("DisplayAchievement")
.HasColumnType("INTEGER");
b.Property<bool>("DisplayDan")
.HasColumnType("INTEGER");
b.Property<string>("FavoriteSongsArray")
.IsRequired()
.HasColumnType("TEXT");
b.Property<bool>("IsSkipOn")
.HasColumnType("INTEGER");
b.Property<bool>("IsVoiceOn")
.HasColumnType("INTEGER");
b.Property<DateTime>("LastPlayDatetime")
.HasColumnType("datetime");
b.Property<uint>("LastPlayMode")
.HasColumnType("INTEGER");
b.Property<string>("MyDonName")
.IsRequired()
.HasColumnType("TEXT");
b.Property<int>("NotesPosition")
.HasColumnType("INTEGER");
b.Property<short>("OptionSetting")
.HasColumnType("INTEGER");
b.Property<uint>("SelectedToneId")
.HasColumnType("INTEGER");
b.Property<string>("Title")
.IsRequired()
.HasColumnType("TEXT");
b.Property<uint>("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
}
}
}

View File

@ -0,0 +1,29 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace TaikoLocalServer.Migrations
{
/// <inheritdoc />
public partial class AddDrumrollCount : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<uint>(
name: "DrumrollCount",
table: "SongPlayData",
type: "INTEGER",
nullable: false,
defaultValue: 0u);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "DrumrollCount",
table: "SongPlayData");
}
}
}

View File

@ -57,7 +57,7 @@ namespace TaikoLocalServer.Migrations
b.HasKey("Baid", "DanId"); b.HasKey("Baid", "DanId");
b.ToTable("DanScoreData"); b.ToTable("DanScoreData", (string)null);
}); });
modelBuilder.Entity("TaikoLocalServer.Entities.DanStageScoreDatum", b => modelBuilder.Entity("TaikoLocalServer.Entities.DanStageScoreDatum", b =>
@ -97,7 +97,7 @@ namespace TaikoLocalServer.Migrations
b.HasKey("Baid", "DanId", "SongNumber"); b.HasKey("Baid", "DanId", "SongNumber");
b.ToTable("DanStageScoreData"); b.ToTable("DanStageScoreData", (string)null);
}); });
modelBuilder.Entity("TaikoLocalServer.Entities.SongBestDatum", b => modelBuilder.Entity("TaikoLocalServer.Entities.SongBestDatum", b =>
@ -125,7 +125,7 @@ namespace TaikoLocalServer.Migrations
b.HasKey("Baid", "SongId", "Difficulty"); b.HasKey("Baid", "SongId", "Difficulty");
b.ToTable("SongBestData"); b.ToTable("SongBestData", (string)null);
}); });
modelBuilder.Entity("TaikoLocalServer.Entities.SongPlayDatum", b => modelBuilder.Entity("TaikoLocalServer.Entities.SongPlayDatum", b =>
@ -146,6 +146,9 @@ namespace TaikoLocalServer.Migrations
b.Property<uint>("Difficulty") b.Property<uint>("Difficulty")
.HasColumnType("INTEGER"); .HasColumnType("INTEGER");
b.Property<uint>("DrumrollCount")
.HasColumnType("INTEGER");
b.Property<uint>("GoodCount") b.Property<uint>("GoodCount")
.HasColumnType("INTEGER"); .HasColumnType("INTEGER");
@ -183,7 +186,7 @@ namespace TaikoLocalServer.Migrations
b.HasIndex("Baid"); b.HasIndex("Baid");
b.ToTable("SongPlayData"); b.ToTable("SongPlayData", (string)null);
}); });
modelBuilder.Entity("TaikoLocalServer.Entities.UserDatum", b => modelBuilder.Entity("TaikoLocalServer.Entities.UserDatum", b =>
@ -251,7 +254,7 @@ namespace TaikoLocalServer.Migrations
b.HasKey("Baid"); b.HasKey("Baid");
b.ToTable("UserData"); b.ToTable("UserData", (string)null);
}); });
modelBuilder.Entity("TaikoLocalServer.Entities.DanScoreDatum", b => modelBuilder.Entity("TaikoLocalServer.Entities.DanScoreDatum", b =>

View File

@ -38,18 +38,33 @@ public class SongBestDatumService : ISongBestDatumService
public async Task<List<SongBestData>> GetAllSongBestAsModel(uint baid) public async Task<List<SongBestData>> 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<SongBestData>()).ToList(); var result = songbestDbData.Select(datum => datum.CopyPropertiesToNew<SongBestData>()).ToList();
var playLogs = await context.SongPlayData.Where(datum => datum.Baid == baid).ToListAsync(); var playLogs = await context.SongPlayData.Where(datum => datum.Baid == baid).ToListAsync();
foreach (var bestData in result) foreach (var bestData in result)
{ {
var lastPlayLog = playLogs.Where(datum => datum.Difficulty == bestData.Difficulty && var songPlayDatums = playLogs.Where(datum => datum.Difficulty == bestData.Difficulty &&
datum.SongId == bestData.SongId) 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); .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; return result;

View File

@ -2,6 +2,7 @@
@using SharedProject.Models.Responses @using SharedProject.Models.Responses
@using SharedProject.Models @using SharedProject.Models
@using SharedProject.Models.Requests @using SharedProject.Models.Requests
@using SharedProject.Enums
@inject IGameDataService GameDataService @inject IGameDataService GameDataService
@inject HttpClient Client @inject HttpClient Client
@ -42,13 +43,19 @@ else
<Column T="SongBestData" Field="@nameof(SongBestData.BestScore)" Title="Best Score"/> <Column T="SongBestData" Field="@nameof(SongBestData.BestScore)" Title="Best Score"/>
<Column T="SongBestData" Field="@nameof(SongBestData.BestCrown)" Title="Best Crown"> <Column T="SongBestData" Field="@nameof(SongBestData.BestCrown)" Title="Best Crown">
<CellTemplate> <CellTemplate>
<MudTooltip Text="@(getCrownText(context.Item.BestCrown.ToString()))" Arrow="true" Placement="Placement.Top"> <MudTooltip Text="@(GetCrownText(context.Item.BestCrown))" Arrow="true" Placement="Placement.Top">
<img src="@($"/images/crown_{context.Item.BestCrown}.png")" alt="@(context.Item.BestCrown)" style="width:25px;height:25px;" /> <img src="@($"/images/crown_{context.Item.BestCrown}.png")" alt="@(context.Item.BestCrown)" style="width:25px;height:25px;" />
</MudTooltip> </MudTooltip>
</CellTemplate> </CellTemplate>
</Column> </Column>
<Column T="SongBestData" Field="@nameof(SongBestData.BestScoreRank)" Title="Best Rank" /> <Column T="SongBestData" Field="@nameof(SongBestData.BestScoreRank)" Title="Best Rank" />
<Column T="SongBestData" Field="@nameof(SongBestData.BestRate)" Title="Best Rate"/> <Column T="SongBestData" Field="@nameof(SongBestData.BestRate)" Title="Best Rate"/>
<Column T="SongBestData" Field="@nameof(SongBestData.GoodCount)" Title="Good"/>
<Column T="SongBestData" Field="@nameof(SongBestData.OkCount)" Title="Ok"/>
<Column T="SongBestData" Field="@nameof(SongBestData.MissCount)" Title="Miss"/>
<Column T="SongBestData" Field="@nameof(SongBestData.ComboCount)" Title="Max Combo"/>
<Column T="SongBestData" Field="@nameof(SongBestData.DrumrollCount)" Title="Drum Rolls"/>
<Column T="SongBestData" Field="@nameof(SongBestData.HitCount)" Title="Hit"/>
<Column T="SongBestData" Field="@nameof(SongBestData.IsFavorite)" Title="Favorite"> <Column T="SongBestData" Field="@nameof(SongBestData.IsFavorite)" Title="Favorite">
<CellTemplate> <CellTemplate>
<MudToggleIconButton Toggled="@context.Item.IsFavorite" <MudToggleIconButton Toggled="@context.Item.IsFavorite"
@ -105,14 +112,14 @@ else
} }
} }
private string getCrownText(String crown) private static string GetCrownText(CrownType crown)
{ {
return crown switch return crown switch
{ {
"None" => "Fail", CrownType.None => "Fail",
"Clear" => "Cleared", CrownType.Clear => "Cleared",
"Gold" => "Full Combo", CrownType.Gold => "Full Combo",
"Dondaful" => "Donderful Combo", CrownType.Dondaful => "Donderful Combo",
_ => "" _ => ""
}; };
} }

View File

@ -0,0 +1,3 @@
{
"DataBaseUrl": "https://localhost:44398"
}

View File

@ -1,4 +1,3 @@
{ {
"BaseUrl": "http://localhost:5000", "BaseUrl": "http://localhost:5000"
"DataBaseUrl": "https://localhost:44398"
} }