diff --git a/GameDatabase/Entities/UserDatum.cs b/GameDatabase/Entities/UserDatum.cs index 4b4d741..f9a81c0 100644 --- a/GameDatabase/Entities/UserDatum.cs +++ b/GameDatabase/Entities/UserDatum.cs @@ -27,8 +27,9 @@ namespace GameDatabase.Entities public bool DisplayDan { get; set; } public bool DisplayAchievement { get; set; } public Difficulty AchievementDisplayDifficulty { get; set; } - public int AiWinCount { get; set; } + public string TokenCountDict { get; set; } = "{}"; + public string UnlockedSongIdList { get; set; } = "[]"; public virtual Card? Ba { get; set; } } } \ No newline at end of file diff --git a/GameDatabase/GameDatabase.csproj b/GameDatabase/GameDatabase.csproj index 7030e6a..79420dd 100644 --- a/GameDatabase/GameDatabase.csproj +++ b/GameDatabase/GameDatabase.csproj @@ -1,7 +1,7 @@ - net8.0 + net6.0 enable enable diff --git a/GameDatabase/Migrations/20230916161613_AddTokenCountDictAndUnlockedSongIdListToUserdata.Designer.cs b/GameDatabase/Migrations/20230916161613_AddTokenCountDictAndUnlockedSongIdListToUserdata.Designer.cs new file mode 100644 index 0000000..767f34d --- /dev/null +++ b/GameDatabase/Migrations/20230916161613_AddTokenCountDictAndUnlockedSongIdListToUserdata.Designer.cs @@ -0,0 +1,443 @@ +// +using System; +using GameDatabase.Context; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace TaikoLocalServer.Migrations +{ + [DbContext(typeof(TaikoDbContext))] + [Migration("20230916161613_AddTokenCountDictAndUnlockedSongIdListToUserdata")] + partial class AddTokenCountDictAndUnlockedSongIdListToUserdata + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder.HasAnnotation("ProductVersion", "7.0.0-rc.1.22426.7"); + + 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(new[] { "Baid" }, "IX_Card_Baid") + .IsUnique(); + + b.ToTable("Card", (string)null); + }); + + modelBuilder.Entity("GameDatabase.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("GameDatabase.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("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.UserDatum", b => + { + b.Property("Baid") + .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("DisplayAchievement") + .HasColumnType("INTEGER"); + + b.Property("DisplayDan") + .HasColumnType("INTEGER"); + + b.Property("FavoriteSongsArray") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("GenericInfoFlgArray") + .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("TitleFlgArray") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("TitlePlateId") + .HasColumnType("INTEGER"); + + b.Property("TokenCountDict") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("ToneFlgArray") + .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.Card", "Ba") + .WithMany() + .HasForeignKey("Baid") + .HasPrincipalKey("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.DanScoreDatum", b => + { + b.HasOne("GameDatabase.Entities.Card", "Ba") + .WithMany() + .HasForeignKey("Baid") + .HasPrincipalKey("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") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Parent"); + }); + + modelBuilder.Entity("GameDatabase.Entities.SongBestDatum", b => + { + b.HasOne("GameDatabase.Entities.Card", "Ba") + .WithMany() + .HasForeignKey("Baid") + .HasPrincipalKey("Baid") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Ba"); + }); + + modelBuilder.Entity("GameDatabase.Entities.SongPlayDatum", b => + { + b.HasOne("GameDatabase.Entities.Card", "Ba") + .WithMany() + .HasForeignKey("Baid") + .HasPrincipalKey("Baid") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Ba"); + }); + + modelBuilder.Entity("GameDatabase.Entities.UserDatum", b => + { + b.HasOne("GameDatabase.Entities.Card", "Ba") + .WithMany() + .HasForeignKey("Baid") + .HasPrincipalKey("Baid") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Ba"); + }); + + modelBuilder.Entity("GameDatabase.Entities.AiScoreDatum", b => + { + b.Navigation("AiSectionScoreData"); + }); + + modelBuilder.Entity("GameDatabase.Entities.DanScoreDatum", b => + { + b.Navigation("DanStageScoreData"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/GameDatabase/Migrations/20230916161613_AddTokenCountDictAndUnlockedSongIdListToUserdata.cs b/GameDatabase/Migrations/20230916161613_AddTokenCountDictAndUnlockedSongIdListToUserdata.cs new file mode 100644 index 0000000..816aee1 --- /dev/null +++ b/GameDatabase/Migrations/20230916161613_AddTokenCountDictAndUnlockedSongIdListToUserdata.cs @@ -0,0 +1,40 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace TaikoLocalServer.Migrations +{ + /// + public partial class AddTokenCountDictAndUnlockedSongIdListToUserdata : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "TokenCountDict", + table: "UserData", + type: "TEXT", + nullable: false, + defaultValue: ""); + + migrationBuilder.AddColumn( + name: "UnlockedSongIdList", + table: "UserData", + type: "TEXT", + nullable: false, + defaultValue: ""); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "TokenCountDict", + table: "UserData"); + + migrationBuilder.DropColumn( + name: "UnlockedSongIdList", + table: "UserData"); + } + } +} diff --git a/GameDatabase/Migrations/TaikoDbContextModelSnapshot.cs b/GameDatabase/Migrations/TaikoDbContextModelSnapshot.cs index d3fa35d..0c04119 100644 --- a/GameDatabase/Migrations/TaikoDbContextModelSnapshot.cs +++ b/GameDatabase/Migrations/TaikoDbContextModelSnapshot.cs @@ -15,11 +15,11 @@ namespace TaikoLocalServer.Migrations protected override void BuildModel(ModelBuilder modelBuilder) { #pragma warning disable 612, 618 - modelBuilder.HasAnnotation("ProductVersion", "7.0.0-preview.7.22376.2"); + modelBuilder.HasAnnotation("ProductVersion", "7.0.0-rc.1.22426.7"); - modelBuilder.Entity("TaikoLocalServer.Entities.AiScoreDatum", b => + modelBuilder.Entity("GameDatabase.Entities.AiScoreDatum", b => { - b.Property("Baid") + b.Property("Baid") .HasColumnType("INTEGER"); b.Property("SongId") @@ -36,9 +36,9 @@ namespace TaikoLocalServer.Migrations b.ToTable("AiScoreData"); }); - modelBuilder.Entity("TaikoLocalServer.Entities.AiSectionScoreDatum", b => + modelBuilder.Entity("GameDatabase.Entities.AiSectionScoreDatum", b => { - b.Property("Baid") + b.Property("Baid") .HasColumnType("INTEGER"); b.Property("SongId") @@ -76,12 +76,12 @@ namespace TaikoLocalServer.Migrations b.ToTable("AiSectionScoreData"); }); - modelBuilder.Entity("TaikoLocalServer.Entities.Card", b => + modelBuilder.Entity("GameDatabase.Entities.Card", b => { b.Property("AccessCode") .HasColumnType("TEXT"); - b.Property("Baid") + b.Property("Baid") .HasColumnType("INTEGER"); b.HasKey("AccessCode"); @@ -92,9 +92,9 @@ namespace TaikoLocalServer.Migrations b.ToTable("Card", (string)null); }); - modelBuilder.Entity("TaikoLocalServer.Entities.DanScoreDatum", b => + modelBuilder.Entity("GameDatabase.Entities.DanScoreDatum", b => { - b.Property("Baid") + b.Property("Baid") .HasColumnType("INTEGER"); b.Property("DanId") @@ -119,9 +119,9 @@ namespace TaikoLocalServer.Migrations b.ToTable("DanScoreData"); }); - modelBuilder.Entity("TaikoLocalServer.Entities.DanStageScoreDatum", b => + modelBuilder.Entity("GameDatabase.Entities.DanStageScoreDatum", b => { - b.Property("Baid") + b.Property("Baid") .HasColumnType("INTEGER"); b.Property("DanId") @@ -159,9 +159,9 @@ namespace TaikoLocalServer.Migrations b.ToTable("DanStageScoreData"); }); - modelBuilder.Entity("TaikoLocalServer.Entities.SongBestDatum", b => + modelBuilder.Entity("GameDatabase.Entities.SongBestDatum", b => { - b.Property("Baid") + b.Property("Baid") .HasColumnType("INTEGER"); b.Property("SongId") @@ -187,13 +187,13 @@ namespace TaikoLocalServer.Migrations b.ToTable("SongBestData"); }); - modelBuilder.Entity("TaikoLocalServer.Entities.SongPlayDatum", b => + modelBuilder.Entity("GameDatabase.Entities.SongPlayDatum", b => { b.Property("Id") .ValueGeneratedOnAdd() .HasColumnType("INTEGER"); - b.Property("Baid") + b.Property("Baid") .HasColumnType("INTEGER"); b.Property("ComboCount") @@ -248,9 +248,9 @@ namespace TaikoLocalServer.Migrations b.ToTable("SongPlayData"); }); - modelBuilder.Entity("TaikoLocalServer.Entities.UserDatum", b => + modelBuilder.Entity("GameDatabase.Entities.UserDatum", b => { - b.Property("Baid") + b.Property("Baid") .HasColumnType("INTEGER"); b.Property("AchievementDisplayDifficulty") @@ -326,18 +326,26 @@ namespace TaikoLocalServer.Migrations b.Property("TitlePlateId") .HasColumnType("INTEGER"); + b.Property("TokenCountDict") + .IsRequired() + .HasColumnType("TEXT"); + b.Property("ToneFlgArray") .IsRequired() .HasColumnType("TEXT"); + b.Property("UnlockedSongIdList") + .IsRequired() + .HasColumnType("TEXT"); + b.HasKey("Baid"); b.ToTable("UserData"); }); - modelBuilder.Entity("TaikoLocalServer.Entities.AiScoreDatum", b => + modelBuilder.Entity("GameDatabase.Entities.AiScoreDatum", b => { - b.HasOne("TaikoLocalServer.Entities.Card", "Ba") + b.HasOne("GameDatabase.Entities.Card", "Ba") .WithMany() .HasForeignKey("Baid") .HasPrincipalKey("Baid") @@ -347,9 +355,9 @@ namespace TaikoLocalServer.Migrations b.Navigation("Ba"); }); - modelBuilder.Entity("TaikoLocalServer.Entities.AiSectionScoreDatum", b => + modelBuilder.Entity("GameDatabase.Entities.AiSectionScoreDatum", b => { - b.HasOne("TaikoLocalServer.Entities.AiScoreDatum", "Parent") + b.HasOne("GameDatabase.Entities.AiScoreDatum", "Parent") .WithMany("AiSectionScoreData") .HasForeignKey("Baid", "SongId", "Difficulty") .OnDelete(DeleteBehavior.Cascade) @@ -358,9 +366,9 @@ namespace TaikoLocalServer.Migrations b.Navigation("Parent"); }); - modelBuilder.Entity("TaikoLocalServer.Entities.DanScoreDatum", b => + modelBuilder.Entity("GameDatabase.Entities.DanScoreDatum", b => { - b.HasOne("TaikoLocalServer.Entities.Card", "Ba") + b.HasOne("GameDatabase.Entities.Card", "Ba") .WithMany() .HasForeignKey("Baid") .HasPrincipalKey("Baid") @@ -370,9 +378,9 @@ namespace TaikoLocalServer.Migrations b.Navigation("Ba"); }); - modelBuilder.Entity("TaikoLocalServer.Entities.DanStageScoreDatum", b => + modelBuilder.Entity("GameDatabase.Entities.DanStageScoreDatum", b => { - b.HasOne("TaikoLocalServer.Entities.DanScoreDatum", "Parent") + b.HasOne("GameDatabase.Entities.DanScoreDatum", "Parent") .WithMany("DanStageScoreData") .HasForeignKey("Baid", "DanId") .OnDelete(DeleteBehavior.Cascade) @@ -381,9 +389,9 @@ namespace TaikoLocalServer.Migrations b.Navigation("Parent"); }); - modelBuilder.Entity("TaikoLocalServer.Entities.SongBestDatum", b => + modelBuilder.Entity("GameDatabase.Entities.SongBestDatum", b => { - b.HasOne("TaikoLocalServer.Entities.Card", "Ba") + b.HasOne("GameDatabase.Entities.Card", "Ba") .WithMany() .HasForeignKey("Baid") .HasPrincipalKey("Baid") @@ -393,9 +401,9 @@ namespace TaikoLocalServer.Migrations b.Navigation("Ba"); }); - modelBuilder.Entity("TaikoLocalServer.Entities.SongPlayDatum", b => + modelBuilder.Entity("GameDatabase.Entities.SongPlayDatum", b => { - b.HasOne("TaikoLocalServer.Entities.Card", "Ba") + b.HasOne("GameDatabase.Entities.Card", "Ba") .WithMany() .HasForeignKey("Baid") .HasPrincipalKey("Baid") @@ -405,9 +413,9 @@ namespace TaikoLocalServer.Migrations b.Navigation("Ba"); }); - modelBuilder.Entity("TaikoLocalServer.Entities.UserDatum", b => + modelBuilder.Entity("GameDatabase.Entities.UserDatum", b => { - b.HasOne("TaikoLocalServer.Entities.Card", "Ba") + b.HasOne("GameDatabase.Entities.Card", "Ba") .WithMany() .HasForeignKey("Baid") .HasPrincipalKey("Baid") @@ -417,12 +425,12 @@ namespace TaikoLocalServer.Migrations b.Navigation("Ba"); }); - modelBuilder.Entity("TaikoLocalServer.Entities.AiScoreDatum", b => + modelBuilder.Entity("GameDatabase.Entities.AiScoreDatum", b => { b.Navigation("AiSectionScoreData"); }); - modelBuilder.Entity("TaikoLocalServer.Entities.DanScoreDatum", b => + modelBuilder.Entity("GameDatabase.Entities.DanScoreDatum", b => { b.Navigation("DanStageScoreData"); }); diff --git a/LocalSaveModScoreMigrator/LocalSaveModScoreMigrator.csproj b/LocalSaveModScoreMigrator/LocalSaveModScoreMigrator.csproj index 41b84d1..ce03ddd 100644 --- a/LocalSaveModScoreMigrator/LocalSaveModScoreMigrator.csproj +++ b/LocalSaveModScoreMigrator/LocalSaveModScoreMigrator.csproj @@ -2,7 +2,7 @@ Exe - net8.0 + net6.0 enable enable 1.0.0-beta1 diff --git a/SharedProject/SharedProject.csproj b/SharedProject/SharedProject.csproj index 4841f53..f6af8be 100644 --- a/SharedProject/SharedProject.csproj +++ b/SharedProject/SharedProject.csproj @@ -1,7 +1,7 @@ - net8.0 + net6.0 enable enable diff --git a/TaikoLocalServer/Controllers/Game/GetTokenCountController.cs b/TaikoLocalServer/Controllers/Game/GetTokenCountController.cs index 2dc3a9e..a85b739 100644 --- a/TaikoLocalServer/Controllers/Game/GetTokenCountController.cs +++ b/TaikoLocalServer/Controllers/Game/GetTokenCountController.cs @@ -1,15 +1,56 @@ -namespace TaikoLocalServer.Controllers.Game; +using System.Text.Json; +using Throw; + +namespace TaikoLocalServer.Controllers.Game; [Route("/v12r00_cn/chassis/gettokencount.php")] [ApiController] public class GetTokenCountController : BaseController { + private readonly IGameDataService gameDataService; + private readonly IUserDatumService userDatumService; + + public GetTokenCountController(IUserDatumService userDatumService, IGameDataService gameDataService) + { + this.userDatumService = userDatumService; + this.gameDataService = gameDataService; + } + [HttpPost] [Produces("application/protobuf")] - public IActionResult GetTokenCount([FromBody] GetTokenCountRequest request) + public async Task GetTokenCount([FromBody] GetTokenCountRequest request) { Logger.LogInformation("GetTokenCount request : {Request}", request.Stringify()); + var user = await userDatumService.GetFirstUserDatumOrNull(request.Baid); + var tokenDataDictionary = gameDataService.GetTokenDataDictionary(); + tokenDataDictionary.TryGetValue("shopTokenId", out var shopTokenId); + tokenDataDictionary.TryGetValue("kaTokenId", out var kaTokenId); + user.ThrowIfNull($"User with baid {request.Baid} does not exist!"); + + var tokenCountDict = new Dictionary(); + try + { + tokenCountDict = !string.IsNullOrEmpty(user.TokenCountDict) + ? JsonSerializer.Deserialize>(user.TokenCountDict) + : new Dictionary(); + } + catch (JsonException e) + { + Logger.LogError(e, "Parsing TokenCountDict data for user with baid {Request} failed!", request.Baid); + } + + tokenCountDict.ThrowIfNull("TokenCountDict should never be null"); + + if (tokenCountDict.Count == 0) tokenCountDict.Add(shopTokenId, 0); + + tokenCountDict.TryAdd(shopTokenId, 0); + + tokenCountDict.TryAdd(kaTokenId, 0); + + user.TokenCountDict = JsonSerializer.Serialize(tokenCountDict); + await userDatumService.UpdateUserDatum(user); + var response = new GetTokenCountResponse { Result = 1 @@ -17,10 +58,16 @@ public class GetTokenCountController : BaseController response.AryTokenCountDatas.Add(new GetTokenCountResponse.TokenCountData { - TokenCount = 10, - TokenId = 1 + TokenCount = tokenCountDict[shopTokenId], + TokenId = shopTokenId }); + response.AryTokenCountDatas.Add(new GetTokenCountResponse.TokenCountData + { + TokenCount = tokenCountDict[kaTokenId], + TokenId = kaTokenId + }); + return Ok(response); } } \ No newline at end of file diff --git a/TaikoLocalServer/Controllers/Game/SongPurchaseController.cs b/TaikoLocalServer/Controllers/Game/SongPurchaseController.cs index b26850c..2240b54 100644 --- a/TaikoLocalServer/Controllers/Game/SongPurchaseController.cs +++ b/TaikoLocalServer/Controllers/Game/SongPurchaseController.cs @@ -1,19 +1,73 @@ -namespace TaikoLocalServer.Controllers.Game; +using System.Text.Json; +using Throw; + +namespace TaikoLocalServer.Controllers.Game; [Route("/v12r00_cn/chassis/songpurchase.php")] [ApiController] public class SongPurchaseController : BaseController { + private readonly IUserDatumService userDatumService; + + public SongPurchaseController(IUserDatumService userDatumService) + { + this.userDatumService = userDatumService; + } + [HttpPost] [Produces("application/protobuf")] - public IActionResult SongPurchase([FromBody] SongPurchaseRequest request) + public async Task SongPurchase([FromBody] SongPurchaseRequest request) { Logger.LogInformation("SongPurchase request : {Request}", request.Stringify()); + var user = await userDatumService.GetFirstUserDatumOrNull(request.Baid); + user.ThrowIfNull($"User with baid {request.Baid} does not exist!"); + + var tokenCountDict = new Dictionary(); + try + { + tokenCountDict = !string.IsNullOrEmpty(user.TokenCountDict) + ? JsonSerializer.Deserialize>(user.TokenCountDict) + : new Dictionary(); + } + catch (JsonException e) + { + Logger.LogError(e, "Parsing TokenCountDict data for user with baid {Request} failed!", request.Baid); + } + + tokenCountDict.ThrowIfNull("TokenCountDict should never be null"); + + Logger.LogInformation("Original UnlockedSongIdList: {UnlockedSongIdList}", user.UnlockedSongIdList); + + var unlockedSongIdList = new List(); + try + { + unlockedSongIdList = !string.IsNullOrEmpty(user.UnlockedSongIdList) + ? JsonSerializer.Deserialize>(user.UnlockedSongIdList) + : new List(); + } + catch (JsonException e) + { + Logger.LogError(e, "Parsing UnlockedSongIdList data for user with baid {Request} failed!", request.Baid); + } + + unlockedSongIdList.ThrowIfNull("UnlockedSongIdList should never be null"); + + if (tokenCountDict.ContainsKey(request.TokenId)) tokenCountDict[request.TokenId] -= (int)request.Price; + + if (!unlockedSongIdList.Contains(request.SongNo)) unlockedSongIdList.Add(request.SongNo); + + user.TokenCountDict = JsonSerializer.Serialize(tokenCountDict); + user.UnlockedSongIdList = JsonSerializer.Serialize(unlockedSongIdList); + + Logger.LogInformation("Updated UnlockedSongIdList: {UnlockedSongIdList}", user.UnlockedSongIdList); + + await userDatumService.UpdateUserDatum(user); + var response = new SongPurchaseResponse { Result = 1, - TokenCount = (int)(10 - request.Price) + TokenCount = tokenCountDict[request.TokenId] }; return Ok(response); diff --git a/TaikoLocalServer/Controllers/Game/UserDataController.cs b/TaikoLocalServer/Controllers/Game/UserDataController.cs index cca201a..eea2302 100644 --- a/TaikoLocalServer/Controllers/Game/UserDataController.cs +++ b/TaikoLocalServer/Controllers/Game/UserDataController.cs @@ -118,14 +118,15 @@ public class UserDataController : BaseController TitleFlg = titleArray, ReleaseSongFlg = releaseSongArray, UraReleaseSongFlg = uraSongArray, + AryFavoriteSongNoes = favoriteSongs, + AryRecentSongNoes = recentSongs, DefaultOptionSetting = defaultOptions, + NotesPosition = userData.NotesPosition, IsVoiceOn = userData.IsVoiceOn, IsSkipOn = userData.IsSkipOn, IsChallengecompe = false, SongRecentCnt = (uint)recentSongs.Length, - AryFavoriteSongNoes = favoriteSongs, - AryRecentSongNoes = recentSongs, - NotesPosition = userData.NotesPosition + TotalCreditCnt = 99 }; return Ok(response); diff --git a/TaikoWebUI/TaikoWebUI.csproj b/TaikoWebUI/TaikoWebUI.csproj index a7e3096..b39c692 100644 --- a/TaikoWebUI/TaikoWebUI.csproj +++ b/TaikoWebUI/TaikoWebUI.csproj @@ -1,7 +1,7 @@ - net8.0 + net6.0 enable enable