1
0
mirror of synced 2024-11-28 00:20:53 +01:00

Added unlocking/locking ura charts and selling ura chart in don medal shop

This commit is contained in:
S-Sebb 2024-11-07 01:46:27 +08:00
parent e2becc6231
commit 463f832b31
12 changed files with 646 additions and 8 deletions

View File

@ -51,6 +51,7 @@ namespace GameDatabase.Entities
public int AiWinCount { get; set; }
public List<Token> Tokens { get; set; } = new();
public List<uint> UnlockedSongIdList { get; set; } = [];
public List<uint> UnlockedUraSongIdList { get; set; } = [];
public bool IsAdmin { get; set; }
}
}

View File

@ -0,0 +1,576 @@
// <auto-generated />
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("20241106173142_AddUnlockedUraSongIdListToUserDatum")]
partial class AddUnlockedUraSongIdListToUserDatum
{
/// <inheritdoc />
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<uint>("Baid")
.HasColumnType("INTEGER");
b.Property<uint>("SongId")
.HasColumnType("INTEGER");
b.Property<uint>("Difficulty")
.HasColumnType("INTEGER");
b.Property<bool>("IsWin")
.HasColumnType("INTEGER");
b.HasKey("Baid", "SongId", "Difficulty");
b.ToTable("AiScoreData");
});
modelBuilder.Entity("GameDatabase.Entities.AiSectionScoreDatum", b =>
{
b.Property<uint>("Baid")
.HasColumnType("INTEGER");
b.Property<uint>("SongId")
.HasColumnType("INTEGER");
b.Property<uint>("Difficulty")
.HasColumnType("INTEGER");
b.Property<int>("SectionIndex")
.HasColumnType("INTEGER");
b.Property<int>("Crown")
.HasColumnType("INTEGER");
b.Property<uint>("DrumrollCount")
.HasColumnType("INTEGER");
b.Property<uint>("GoodCount")
.HasColumnType("INTEGER");
b.Property<bool>("IsWin")
.HasColumnType("INTEGER");
b.Property<uint>("MissCount")
.HasColumnType("INTEGER");
b.Property<uint>("OkCount")
.HasColumnType("INTEGER");
b.Property<uint>("Score")
.HasColumnType("INTEGER");
b.HasKey("Baid", "SongId", "Difficulty", "SectionIndex");
b.ToTable("AiSectionScoreData");
});
modelBuilder.Entity("GameDatabase.Entities.Card", b =>
{
b.Property<string>("AccessCode")
.HasColumnType("TEXT");
b.Property<uint>("Baid")
.HasColumnType("INTEGER");
b.HasKey("AccessCode");
b.HasIndex("Baid");
b.ToTable("Card", (string)null);
});
modelBuilder.Entity("GameDatabase.Entities.Credential", b =>
{
b.Property<uint>("Baid")
.HasColumnType("INTEGER");
b.Property<string>("Password")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("Salt")
.IsRequired()
.HasColumnType("TEXT");
b.HasKey("Baid");
b.ToTable("Credential", (string)null);
});
modelBuilder.Entity("GameDatabase.Entities.DanScoreDatum", b =>
{
b.Property<uint>("Baid")
.HasColumnType("INTEGER");
b.Property<uint>("DanId")
.HasColumnType("INTEGER");
b.Property<int>("DanType")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER")
.HasDefaultValue(1);
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", "DanType");
b.ToTable("DanScoreData");
});
modelBuilder.Entity("GameDatabase.Entities.DanStageScoreDatum", b =>
{
b.Property<uint>("Baid")
.HasColumnType("INTEGER");
b.Property<uint>("DanId")
.HasColumnType("INTEGER");
b.Property<int>("DanType")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER")
.HasDefaultValue(1);
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", "DanType", "SongNumber");
b.ToTable("DanStageScoreData");
});
modelBuilder.Entity("GameDatabase.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("GameDatabase.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("GameDatabase.Entities.Token", b =>
{
b.Property<uint>("Baid")
.HasColumnType("INTEGER");
b.Property<int>("Id")
.HasColumnType("INTEGER");
b.Property<int>("Count")
.HasColumnType("INTEGER");
b.HasKey("Baid", "Id");
b.ToTable("Tokens");
});
modelBuilder.Entity("GameDatabase.Entities.UserDatum", b =>
{
b.Property<uint>("Baid")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<uint>("AchievementDisplayDifficulty")
.HasColumnType("INTEGER");
b.Property<int>("AiWinCount")
.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<string>("CostumeFlgArray")
.IsRequired()
.HasColumnType("TEXT");
b.Property<uint>("CurrentBody")
.HasColumnType("INTEGER");
b.Property<uint>("CurrentFace")
.HasColumnType("INTEGER");
b.Property<uint>("CurrentHead")
.HasColumnType("INTEGER");
b.Property<uint>("CurrentKigurumi")
.HasColumnType("INTEGER");
b.Property<uint>("CurrentPuchi")
.HasColumnType("INTEGER");
b.Property<string>("DifficultyPlayedArray")
.IsRequired()
.HasColumnType("TEXT");
b.Property<uint>("DifficultyPlayedCourse")
.HasColumnType("INTEGER");
b.Property<uint>("DifficultyPlayedSort")
.HasColumnType("INTEGER");
b.Property<uint>("DifficultyPlayedStar")
.HasColumnType("INTEGER");
b.Property<string>("DifficultySettingArray")
.IsRequired()
.HasColumnType("TEXT");
b.Property<uint>("DifficultySettingCourse")
.HasColumnType("INTEGER");
b.Property<uint>("DifficultySettingSort")
.HasColumnType("INTEGER");
b.Property<uint>("DifficultySettingStar")
.HasColumnType("INTEGER");
b.Property<bool>("DisplayAchievement")
.HasColumnType("INTEGER");
b.Property<bool>("DisplayDan")
.HasColumnType("INTEGER");
b.Property<string>("FavoriteSongsArray")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("GenericInfoFlgArray")
.IsRequired()
.HasColumnType("TEXT");
b.Property<bool>("IsAdmin")
.HasColumnType("INTEGER");
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<uint>("MyDonNameLanguage")
.HasColumnType("INTEGER");
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<string>("TitleFlgArray")
.IsRequired()
.HasColumnType("TEXT");
b.Property<uint>("TitlePlateId")
.HasColumnType("INTEGER");
b.Property<string>("ToneFlgArray")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("UnlockedBody")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("UnlockedFace")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("UnlockedHead")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("UnlockedKigurumi")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("UnlockedPuchi")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("UnlockedSongIdList")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("UnlockedUraSongIdList")
.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
}
}
}

View File

@ -0,0 +1,29 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace GameDatabase.Migrations
{
/// <inheritdoc />
public partial class AddUnlockedUraSongIdListToUserDatum : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<string>(
name: "UnlockedUraSongIdList",
table: "UserData",
type: "TEXT",
nullable: false,
defaultValue: "");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "UnlockedUraSongIdList",
table: "UserData");
}
}
}

View File

@ -15,7 +15,7 @@ namespace TaikoLocalServer.Migrations
protected override void BuildModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder.HasAnnotation("ProductVersion", "8.0.4");
modelBuilder.HasAnnotation("ProductVersion", "8.0.3");
modelBuilder.Entity("GameDatabase.Entities.AiScoreDatum", b =>
{
@ -445,6 +445,10 @@ namespace TaikoLocalServer.Migrations
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("UnlockedUraSongIdList")
.IsRequired()
.HasColumnType("TEXT");
b.HasKey("Baid");
b.ToTable("UserData");

View File

@ -211,6 +211,9 @@ There are various data json files under wwwroot/data that can be customized.
100,
200,
300
],
"uraSongNo": [
// Fill in the uniqueId of songs whose ura chart you wish to lock
]
}
```
@ -241,10 +244,12 @@ There are various data json files under wwwroot/data that can be customized.
[
{
"songNo": 100, // The uniqueId of the song
"type": 0, // 0 indicates the shop is selling the song itself
"price": 20 // How many don coins buying this song costs, the type of don coin is specified by token_data.json
},
{
"songNo": 200,
"type": 1, // And 1 indicates the shop is selling the song's ura chart
"price": 20
}
]

View File

@ -6,6 +6,7 @@ public class ShopFolderData
{
[JsonPropertyName("songNo")] public uint SongNo { get; set; }
public uint Type { get; set; }
[JsonPropertyName("type")] public uint Type { get; set; }
[JsonPropertyName("price")] public uint Price { get; set; }
}

View File

@ -21,6 +21,7 @@ public class GetInitialDataQueryHandler(IGameDataService gameDataService,
var musicList = gameDataService.GetMusicList();
var lockedSongsList = gameDataService.GetLockedSongsList();
var lockedUraSongsList = gameDataService.GetLockedUraSongsList();
var enabledArray =
FlagCalculator.GetBitArrayFromIds(musicList, songIdMax, logger);
@ -29,7 +30,7 @@ public class GetInitialDataQueryHandler(IGameDataService gameDataService,
var defaultSongFlg =
FlagCalculator.GetBitArrayFromIds(defaultSongList, songIdMax, logger);
var defaultSongWithUraList = gameDataService.GetMusicWithUraList();
var defaultSongWithUraList = gameDataService.GetMusicWithUraList().Except(lockedUraSongsList);
var uraReleaseBit =
FlagCalculator.GetBitArrayFromIds(defaultSongWithUraList, songIdMax, logger);

View File

@ -16,16 +16,17 @@ public class UserDataQueryHandler(TaikoDbContext context, IGameDataService gameD
userData.ThrowIfNull($"User not found for Baid {request.Baid}!");
var unlockedSongIdList = userData.UnlockedSongIdList;
var unlockedUraSongIdList = userData.UnlockedUraSongIdList;
var musicList = gameDataService.GetMusicList();
var lockedSongsList = gameDataService.GetLockedSongsList();
lockedSongsList = lockedSongsList.Except(unlockedSongIdList).ToList();
var lockedSongsList = gameDataService.GetLockedSongsList().Except(unlockedSongIdList).ToList();
var lockedUraSongsList = gameDataService.GetLockedUraSongsList().Except(unlockedUraSongIdList).ToList();
var enabledMusicList = musicList.Except(lockedSongsList);
var releaseSongArray =
FlagCalculator.GetBitArrayFromIds(enabledMusicList, Constants.MusicIdMax, logger);
var defaultSongWithUraList = gameDataService.GetMusicWithUraList();
var enabledUraMusicList = defaultSongWithUraList.Except(lockedSongsList);
var enabledUraMusicList = defaultSongWithUraList.Except(lockedUraSongsList);
var uraSongArray =
FlagCalculator.GetBitArrayFromIds(enabledUraMusicList, Constants.MusicIdMax, logger);

View File

@ -41,6 +41,8 @@ public class GameDataService(IOptions<DataSettings> dataSettings) : IGameDataSer
private List<uint> lockedSongsList = [];
private List<uint> lockedUraSongsList = [];
private readonly Dictionary<uint, MusicDetail> musicDetailDictionary = new();
private readonly List<Costume> costumeList = [];
@ -111,6 +113,11 @@ public class GameDataService(IOptions<DataSettings> dataSettings) : IGameDataSer
return lockedSongsList;
}
public List<uint> GetLockedUraSongsList()
{
return lockedUraSongsList;
}
public Dictionary<uint, MusicDetail> GetMusicDetailDictionary()
{
return musicDetailDictionary;
@ -376,6 +383,7 @@ public class GameDataService(IOptions<DataSettings> dataSettings) : IGameDataSer
{
lockedSongsData.ThrowIfNull("Shouldn't happen!");
lockedSongsList = lockedSongsData["songNo"].ToList();
lockedUraSongsList = lockedSongsData["uraSongNo"].ToList();
}
private void InitializeMusicDetails(MusicInfos? musicInfoData, MusicOrder? musicOrderData, WordList? wordlistData)

View File

@ -27,6 +27,8 @@ public interface IGameDataService
public List<uint> GetLockedSongsList();
public List<uint> GetLockedUraSongsList();
public Dictionary<uint, MusicDetail> GetMusicDetailDictionary();
public List<Costume> GetCostumeList();

View File

@ -1,4 +1,8 @@
{
"songNo": [
],
"uraSongNo": [
]
}

View File

@ -1,6 +1,12 @@
[
{
"songNo": 2,
"songNo": 1,
"type": 0,
"price": 0
},
{
"songNo": 9,
"type": 1,
"price": 0
}
]