Stage Changes
This commit is contained in:
parent
a88965bdd1
commit
adb101261a
@ -35,7 +35,7 @@ namespace GameDatabase.Entities
|
||||
public Difficulty AchievementDisplayDifficulty { get; set; }
|
||||
public int AiWinCount { get; set; }
|
||||
public List<Token> Tokens { get; set; } = new();
|
||||
public uint[] UnlockedSongIdList { get; set; } = Array.Empty<uint>();
|
||||
public List<uint> UnlockedSongIdList { get; set; } = [];
|
||||
public bool IsAdmin { get; set; }
|
||||
}
|
||||
}
|
@ -4,7 +4,7 @@
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<LangVersion>11</LangVersion>
|
||||
<LangVersion>12</LangVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
@ -1,57 +1,30 @@
|
||||
using System.Text.Json;
|
||||
using Throw;
|
||||
using TaikoLocalServer.Mappers;
|
||||
|
||||
namespace TaikoLocalServer.Controllers.Game;
|
||||
|
||||
[Route("/v12r08_ww/chassis/songpurchase_wm2fh5bl.php")]
|
||||
[ApiController]
|
||||
public class SongPurchaseController : BaseController<SongPurchaseController>
|
||||
{
|
||||
private readonly IUserDatumService userDatumService;
|
||||
|
||||
public SongPurchaseController(IUserDatumService userDatumService)
|
||||
{
|
||||
this.userDatumService = userDatumService;
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[HttpPost("/v12r08_ww/chassis/songpurchase_wm2fh5bl.php")]
|
||||
[Produces("application/protobuf")]
|
||||
public async Task<IActionResult> 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!");
|
||||
|
||||
Logger.LogInformation("Original UnlockedSongIdList: {UnlockedSongIdList}", user.UnlockedSongIdList);
|
||||
|
||||
var unlockedSongIdList = user.UnlockedSongIdList.ToList();
|
||||
|
||||
var token = user.Tokens.FirstOrDefault(t => t.Id == request.TokenId);
|
||||
if (token is not null && token.Count >= request.Price)
|
||||
{
|
||||
token.Count -= (int)request.Price;
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.LogError("User with baid {Baid} does not have enough tokens to purchase song with id {SongNo}!", request.Baid, request.SongNo);
|
||||
return Ok(new SongPurchaseResponse { Result = 0 });
|
||||
}
|
||||
|
||||
if (!unlockedSongIdList.Contains(request.SongNo)) unlockedSongIdList.Add(request.SongNo);
|
||||
|
||||
user.UnlockedSongIdList = unlockedSongIdList.ToArray();
|
||||
|
||||
Logger.LogInformation("Updated UnlockedSongIdList: {UnlockedSongIdList}", user.UnlockedSongIdList);
|
||||
|
||||
await userDatumService.UpdateUserDatum(user);
|
||||
|
||||
var response = new SongPurchaseResponse
|
||||
{
|
||||
Result = 1,
|
||||
TokenCount = token.Count
|
||||
};
|
||||
var commonResponse = await Mediator.Send(SongPurchaseMappers.MapToCommand(request));
|
||||
var response = SongPurchaseMappers.MapTo3906(commonResponse);
|
||||
|
||||
return Ok(response);
|
||||
}
|
||||
|
||||
[HttpPost("/v12r00_cn/chassis/songpurchase.php")]
|
||||
[Produces("application/protobuf")]
|
||||
public async Task<IActionResult> SongPurchase3209([FromBody] Models.v3209.SongPurchaseRequest request)
|
||||
{
|
||||
Logger.LogInformation("SongPurchase request : {Request}", request.Stringify());
|
||||
|
||||
var commonResponse = await Mediator.Send(SongPurchaseMappers.MapToCommand(request));
|
||||
var response = SongPurchaseMappers.MapTo3209(commonResponse);
|
||||
return Ok(response);
|
||||
}
|
||||
}
|
@ -1,178 +1,36 @@
|
||||
using Microsoft.Extensions.Options;
|
||||
using System.Buffers.Binary;
|
||||
using System.Text.Json;
|
||||
using TaikoLocalServer.Handlers;
|
||||
using TaikoLocalServer.Mappers;
|
||||
using TaikoLocalServer.Settings;
|
||||
using Throw;
|
||||
|
||||
namespace TaikoLocalServer.Controllers.Game;
|
||||
|
||||
[Route("/v12r08_ww/chassis/userdata_gc6x17o8.php")]
|
||||
[ApiController]
|
||||
public class UserDataController : BaseController<UserDataController>
|
||||
{
|
||||
private readonly IUserDatumService userDatumService;
|
||||
|
||||
private readonly ISongPlayDatumService songPlayDatumService;
|
||||
|
||||
private readonly IGameDataService gameDataService;
|
||||
|
||||
private readonly ServerSettings settings;
|
||||
|
||||
public UserDataController(IUserDatumService userDatumService, ISongPlayDatumService songPlayDatumService,
|
||||
IGameDataService gameDataService, IOptions<ServerSettings> settings)
|
||||
{
|
||||
this.userDatumService = userDatumService;
|
||||
this.songPlayDatumService = songPlayDatumService;
|
||||
this.gameDataService = gameDataService;
|
||||
this.settings = settings.Value;
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[HttpPost("/v12r08_ww/chassis/userdata_gc6x17o8.php")]
|
||||
[Produces("application/protobuf")]
|
||||
public async Task<IActionResult> GetUserData([FromBody] UserDataRequest request)
|
||||
{
|
||||
Logger.LogInformation("UserData request : {Request}", request.Stringify());
|
||||
|
||||
var songIdMax = settings.EnableMoreSongs ? Constants.MUSIC_ID_MAX_EXPANDED : Constants.MUSIC_ID_MAX;
|
||||
var commonResponse = await Mediator.Send(new UserDataQuery(request.Baid));
|
||||
var response = UserDataMappers.MapTo3906(commonResponse);
|
||||
|
||||
var userData = await userDatumService.GetFirstUserDatumOrDefault(request.Baid);
|
||||
return Ok(response);
|
||||
}
|
||||
|
||||
[HttpPost("/v12r00_cn/chassis/userdata.php")]
|
||||
[Produces("application/protobuf")]
|
||||
public async Task<IActionResult> GetUserData3209([FromBody] Models.v3209.UserDataRequest request)
|
||||
{
|
||||
Logger.LogInformation("UserData request : {Request}", request.Stringify());
|
||||
|
||||
var unlockedSongIdList = userData.UnlockedSongIdList;/*new List<uint>();
|
||||
try
|
||||
{
|
||||
unlockedSongIdList = !string.IsNullOrEmpty(userData.UnlockedSongIdList)
|
||||
? JsonSerializer.Deserialize<List<uint>>(userData.UnlockedSongIdList)
|
||||
: new List<uint>();
|
||||
}
|
||||
catch (JsonException e)
|
||||
{
|
||||
Logger.LogError(e, "Parsing UnlockedSongIdList data for user with baid {Request} failed!", request.Baid);
|
||||
}
|
||||
|
||||
unlockedSongIdList.ThrowIfNull("UnlockedSongIdList should never be null");*/
|
||||
|
||||
var musicList = gameDataService.GetMusicList();
|
||||
var lockedSongsList = gameDataService.GetLockedSongsList();
|
||||
lockedSongsList = lockedSongsList.Except(unlockedSongIdList).ToList();
|
||||
var enabledMusicList = musicList.Except(lockedSongsList);
|
||||
var releaseSongArray =
|
||||
FlagCalculator.GetBitArrayFromIds(enabledMusicList, songIdMax, Logger);
|
||||
|
||||
var defaultSongWithUraList = gameDataService.GetMusicWithUraList();
|
||||
var enabledUraMusicList = defaultSongWithUraList.Except(lockedSongsList);
|
||||
var uraSongArray =
|
||||
FlagCalculator.GetBitArrayFromIds(enabledUraMusicList, songIdMax, Logger);
|
||||
|
||||
var toneFlg = userData.ToneFlgArray;/*Array.Empty<uint>();
|
||||
try
|
||||
{
|
||||
toneFlg = JsonSerializer.Deserialize<uint[]>(userData.ToneFlgArray);
|
||||
}
|
||||
catch (JsonException e)
|
||||
{
|
||||
Logger.LogError(e, "Parsing tone flg json data failed");
|
||||
}
|
||||
|
||||
// The only way to get a null is provide string "null" as input,
|
||||
// which means database content need to be fixed, so better throw
|
||||
toneFlg.ThrowIfNull("Tone flg should never be null!");*/
|
||||
|
||||
// If toneFlg is empty, add 0 to it
|
||||
if (toneFlg.Length == 0)
|
||||
{
|
||||
toneFlg = new uint[] { 0 };
|
||||
userData.ToneFlgArray = toneFlg;//JsonSerializer.Serialize(toneFlg);
|
||||
await userDatumService.UpdateUserDatum(userData);
|
||||
}
|
||||
|
||||
var toneArray = FlagCalculator.GetBitArrayFromIds(toneFlg, gameDataService.GetToneFlagArraySize(), Logger);
|
||||
|
||||
var titleFlg = userData.TitleFlgArray;/*Array.Empty<uint>();
|
||||
try
|
||||
{
|
||||
titleFlg = JsonSerializer.Deserialize<uint[]>(userData.TitleFlgArray);
|
||||
}
|
||||
catch (JsonException e)
|
||||
{
|
||||
Logger.LogError(e, "Parsing title flg json data failed");
|
||||
}
|
||||
|
||||
// The only way to get a null is provide string "null" as input,
|
||||
// which means database content need to be fixed, so better throw
|
||||
titleFlg.ThrowIfNull("Title flg should never be null!");*/
|
||||
|
||||
var titleArray = FlagCalculator.GetBitArrayFromIds(titleFlg, gameDataService.GetTitleFlagArraySize(), Logger);
|
||||
|
||||
var recentSongs = (await songPlayDatumService.GetSongPlayDatumByBaid(request.Baid))
|
||||
.AsEnumerable()
|
||||
.OrderByDescending(datum => datum.PlayTime)
|
||||
.ThenByDescending(datum => datum.SongNumber)
|
||||
.Select(datum => datum.SongId)
|
||||
.ToArray();
|
||||
|
||||
// Use custom implementation as distinctby cannot guarantee preserved element
|
||||
var recentSet = new OrderedSet<uint>();
|
||||
foreach (var id in recentSongs)
|
||||
{
|
||||
recentSet.Add(id);
|
||||
if (recentSet.Count == 10)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
recentSongs = recentSet.ToArray();
|
||||
|
||||
var favoriteSongs = userData.FavoriteSongsArray;/*Array.Empty<uint>();
|
||||
try
|
||||
{
|
||||
favoriteSongs = JsonSerializer.Deserialize<uint[]>(userData.FavoriteSongsArray);
|
||||
}
|
||||
catch (JsonException e)
|
||||
{
|
||||
Logger.LogError(e, "Parsing favorite songs json data failed");
|
||||
}
|
||||
|
||||
// The only way to get a null is provide string "null" as input,
|
||||
// which means database content need to be fixed, so better throw
|
||||
favoriteSongs.ThrowIfNull("Favorite song should never be null!");*/
|
||||
|
||||
var defaultOptions = new byte[2];
|
||||
BinaryPrimitives.WriteInt16LittleEndian(defaultOptions, userData.OptionSetting);
|
||||
|
||||
var difficultySettingArray = JsonHelper.GetUIntArrayFromJson(userData.DifficultySettingArray, 3, Logger, nameof(userData.DifficultySettingArray));
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
if (difficultySettingArray[i] >= 2)
|
||||
{
|
||||
difficultySettingArray[i] -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
var difficultyPlayedArray = JsonHelper.GetUIntArrayFromJson(userData.DifficultyPlayedArray, 3, Logger, nameof(userData.DifficultyPlayedArray));
|
||||
|
||||
var response = new UserDataResponse
|
||||
{
|
||||
Result = 1,
|
||||
ToneFlg = toneArray,
|
||||
TitleFlg = titleArray,
|
||||
ReleaseSongFlg = releaseSongArray,
|
||||
UraReleaseSongFlg = uraSongArray,
|
||||
AryFavoriteSongNoes = favoriteSongs,
|
||||
AryRecentSongNoes = recentSongs,
|
||||
DefaultOptionSetting = defaultOptions,
|
||||
NotesPosition = userData.NotesPosition,
|
||||
IsVoiceOn = userData.IsVoiceOn,
|
||||
IsSkipOn = userData.IsSkipOn,
|
||||
DifficultySettingCourse = difficultySettingArray[0],
|
||||
DifficultySettingStar = difficultySettingArray[1],
|
||||
DifficultySettingSort = difficultySettingArray[2],
|
||||
DifficultyPlayedCourse = difficultyPlayedArray[0],
|
||||
DifficultyPlayedStar = difficultyPlayedArray[1],
|
||||
DifficultyPlayedSort = difficultyPlayedArray[2],
|
||||
IsChallengecompe = false,
|
||||
SongRecentCnt = (uint)recentSongs.Length
|
||||
};
|
||||
var commonResponse = await Mediator.Send(new UserDataQuery((uint)request.Baid));
|
||||
var response = UserDataMappers.MapTo3209(commonResponse);
|
||||
|
||||
return Ok(response);
|
||||
}
|
||||
|
@ -30,6 +30,27 @@ public class VerifyQrCodeController : BaseController<VerifyQrCodeController>
|
||||
|
||||
return Ok(response);
|
||||
}
|
||||
|
||||
[HttpPost("/v12r00_cn/chassis/verifyqrcode.php")]
|
||||
[Produces("application/protobuf")]
|
||||
public IActionResult VerifyQrCode3209([FromBody] Models.v3209.VerifyQrcodeRequest request)
|
||||
{
|
||||
Logger.LogInformation("VerifyQrCode request : {Request}", request.Stringify());
|
||||
|
||||
var qrCodeId = VerifyQr(request.QrcodeSerial);
|
||||
var response = new Models.v3209.VerifyQrcodeResponse
|
||||
{
|
||||
Result = 1,
|
||||
QrcodeId = (uint)qrCodeId
|
||||
};
|
||||
|
||||
if (qrCodeId == -1)
|
||||
{
|
||||
response.Result = 51;
|
||||
}
|
||||
|
||||
return Ok(response);
|
||||
}
|
||||
|
||||
private int VerifyQr(string serial)
|
||||
{
|
||||
|
41
TaikoLocalServer/Handlers/PurchaseSongCommand.cs
Normal file
41
TaikoLocalServer/Handlers/PurchaseSongCommand.cs
Normal file
@ -0,0 +1,41 @@
|
||||
using GameDatabase.Context;
|
||||
using TaikoLocalServer.Models.Application;
|
||||
using Throw;
|
||||
|
||||
namespace TaikoLocalServer.Handlers;
|
||||
|
||||
public record PurchaseSongCommand(uint Baid, uint SongNo, uint TokenId, uint Price) : IRequest<CommonSongPurchaseResponse>;
|
||||
|
||||
public class PurchaseSongCommandHandler(TaikoDbContext context, ILogger<PurchaseSongCommandHandler> logger)
|
||||
: IRequestHandler<PurchaseSongCommand, CommonSongPurchaseResponse>
|
||||
{
|
||||
|
||||
public async Task<CommonSongPurchaseResponse> Handle(PurchaseSongCommand request, CancellationToken cancellationToken)
|
||||
{
|
||||
var user = await context.UserData
|
||||
.Include(u => u.Tokens)
|
||||
.FirstOrDefaultAsync(u => u.Baid == request.Baid, cancellationToken);
|
||||
user.ThrowIfNull($"User with baid {request.Baid} does not exist!");
|
||||
if (user.UnlockedSongIdList.Contains(request.SongNo))
|
||||
{
|
||||
logger.LogWarning("User with baid {Baid} already has song with id {SongNo} unlocked!", request.Baid, request.SongNo);
|
||||
return new CommonSongPurchaseResponse { Result = 0 };
|
||||
}
|
||||
|
||||
var token = user.Tokens.FirstOrDefault(t => t.Id == request.TokenId);
|
||||
if (token is not null && token.Count >= request.Price)
|
||||
{
|
||||
token.Count -= (int)request.Price;
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.LogError("User with baid {Baid} does not have enough tokens to purchase song with id {SongNo}!", request.Baid, request.SongNo);
|
||||
return new CommonSongPurchaseResponse { Result = 0 };
|
||||
}
|
||||
|
||||
user.UnlockedSongIdList.Add(request.SongNo);
|
||||
context.UserData.Update(user);
|
||||
await context.SaveChangesAsync(cancellationToken);
|
||||
return new CommonSongPurchaseResponse { Result = 1, TokenCount = token.Count };
|
||||
}
|
||||
}
|
104
TaikoLocalServer/Handlers/UserDataQuery.cs
Normal file
104
TaikoLocalServer/Handlers/UserDataQuery.cs
Normal file
@ -0,0 +1,104 @@
|
||||
using System.Buffers.Binary;
|
||||
using GameDatabase.Context;
|
||||
using TaikoLocalServer.Models.Application;
|
||||
using Throw;
|
||||
|
||||
namespace TaikoLocalServer.Handlers;
|
||||
|
||||
public record UserDataQuery(uint Baid) : IRequest<CommonUserDataResponse>;
|
||||
|
||||
public class UserDataQueryHandler(TaikoDbContext context, IGameDataService gameDataService, ILogger<UserDataQueryHandler> logger)
|
||||
: IRequestHandler<UserDataQuery, CommonUserDataResponse>
|
||||
{
|
||||
|
||||
public async Task<CommonUserDataResponse> Handle(UserDataQuery request, CancellationToken cancellationToken)
|
||||
{
|
||||
var userData = await context.UserData.FindAsync(request.Baid, cancellationToken);
|
||||
userData.ThrowIfNull($"User not found for Baid {request.Baid}!");
|
||||
|
||||
var unlockedSongIdList = userData.UnlockedSongIdList;
|
||||
|
||||
var musicList = gameDataService.GetMusicList();
|
||||
var lockedSongsList = gameDataService.GetLockedSongsList();
|
||||
lockedSongsList = lockedSongsList.Except(unlockedSongIdList).ToList();
|
||||
var enabledMusicList = musicList.Except(lockedSongsList);
|
||||
var releaseSongArray =
|
||||
FlagCalculator.GetBitArrayFromIds(enabledMusicList, Constants.MUSIC_ID_MAX, logger);
|
||||
|
||||
var defaultSongWithUraList = gameDataService.GetMusicWithUraList();
|
||||
var enabledUraMusicList = defaultSongWithUraList.Except(lockedSongsList);
|
||||
var uraSongArray =
|
||||
FlagCalculator.GetBitArrayFromIds(enabledUraMusicList, Constants.MUSIC_ID_MAX, logger);
|
||||
|
||||
if (userData.ToneFlgArray.Length == 0)
|
||||
{
|
||||
userData.ToneFlgArray = [0];
|
||||
context.UserData.Update(userData);
|
||||
await context.SaveChangesAsync(cancellationToken);
|
||||
}
|
||||
|
||||
var toneArray = FlagCalculator.GetBitArrayFromIds(userData.ToneFlgArray, gameDataService.GetToneFlagArraySize(), logger);
|
||||
|
||||
var titleArray = FlagCalculator.GetBitArrayFromIds(userData.TitleFlgArray, gameDataService.GetTitleFlagArraySize(), logger);
|
||||
|
||||
var recentSongs = await context.SongPlayData
|
||||
.Where(datum => datum.Baid == request.Baid)
|
||||
.OrderByDescending(datum => datum.PlayTime)
|
||||
.ThenByDescending(datum => datum.SongNumber)
|
||||
.Select(datum => datum.SongId)
|
||||
.ToArrayAsync(cancellationToken);
|
||||
|
||||
// Use custom implementation as distinctby cannot guarantee preserved element
|
||||
var recentSet = new OrderedSet<uint>();
|
||||
foreach (var id in recentSongs)
|
||||
{
|
||||
recentSet.Add(id);
|
||||
if (recentSet.Count == 10)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
recentSongs = recentSet.ToArray();
|
||||
|
||||
var defaultOptions = new byte[2];
|
||||
BinaryPrimitives.WriteInt16LittleEndian(defaultOptions, userData.OptionSetting);
|
||||
|
||||
var difficultySettingArray = JsonHelper.GetUIntArrayFromJson(userData.DifficultySettingArray, 3, logger, nameof(userData.DifficultySettingArray));
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
if (difficultySettingArray[i] >= 2)
|
||||
{
|
||||
difficultySettingArray[i] -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
var difficultyPlayedArray = JsonHelper.GetUIntArrayFromJson(userData.DifficultyPlayedArray, 3, logger, nameof(userData.DifficultyPlayedArray));
|
||||
|
||||
var response = new CommonUserDataResponse
|
||||
{
|
||||
Result = 1,
|
||||
ToneFlg = toneArray,
|
||||
TitleFlg = titleArray,
|
||||
ReleaseSongFlg = releaseSongArray,
|
||||
UraReleaseSongFlg = uraSongArray,
|
||||
AryFavoriteSongNoes = userData.FavoriteSongsArray,
|
||||
AryRecentSongNoes = recentSongs,
|
||||
DefaultOptionSetting = defaultOptions,
|
||||
NotesPosition = userData.NotesPosition,
|
||||
IsVoiceOn = userData.IsVoiceOn,
|
||||
IsSkipOn = userData.IsSkipOn,
|
||||
DifficultySettingCourse = difficultySettingArray[0],
|
||||
DifficultySettingStar = difficultySettingArray[1],
|
||||
DifficultySettingSort = difficultySettingArray[2],
|
||||
DifficultyPlayedCourse = difficultyPlayedArray[0],
|
||||
DifficultyPlayedStar = difficultyPlayedArray[1],
|
||||
DifficultyPlayedSort = difficultyPlayedArray[2],
|
||||
SongRecentCnt = (uint)recentSongs.Length,
|
||||
IsChallengecompe = false,
|
||||
// TODO: Other fields
|
||||
};
|
||||
|
||||
return response;
|
||||
}
|
||||
}
|
17
TaikoLocalServer/Mappers/SongPurchaseMappers.cs
Normal file
17
TaikoLocalServer/Mappers/SongPurchaseMappers.cs
Normal file
@ -0,0 +1,17 @@
|
||||
using Riok.Mapperly.Abstractions;
|
||||
using TaikoLocalServer.Handlers;
|
||||
using TaikoLocalServer.Models.Application;
|
||||
|
||||
namespace TaikoLocalServer.Mappers;
|
||||
|
||||
[Mapper]
|
||||
public static partial class SongPurchaseMappers
|
||||
{
|
||||
public static partial SongPurchaseResponse MapTo3906(CommonSongPurchaseResponse response);
|
||||
|
||||
public static partial Models.v3209.SongPurchaseResponse MapTo3209(CommonSongPurchaseResponse response);
|
||||
|
||||
public static partial PurchaseSongCommand MapToCommand(SongPurchaseRequest request);
|
||||
|
||||
public static partial PurchaseSongCommand MapToCommand(Models.v3209.SongPurchaseRequest request);
|
||||
}
|
12
TaikoLocalServer/Mappers/UserDataMappers.cs
Normal file
12
TaikoLocalServer/Mappers/UserDataMappers.cs
Normal file
@ -0,0 +1,12 @@
|
||||
using Riok.Mapperly.Abstractions;
|
||||
using TaikoLocalServer.Models.Application;
|
||||
|
||||
namespace TaikoLocalServer.Mappers;
|
||||
|
||||
[Mapper]
|
||||
public static partial class UserDataMappers
|
||||
{
|
||||
public static partial UserDataResponse MapTo3906(CommonUserDataResponse response);
|
||||
|
||||
public static partial Models.v3209.UserDataResponse MapTo3209(CommonUserDataResponse response);
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
namespace TaikoLocalServer.Models.Application;
|
||||
|
||||
public class CommonSongPurchaseResponse
|
||||
{
|
||||
public uint Result { get; set; }
|
||||
|
||||
public int TokenCount { get; set; }
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
namespace TaikoLocalServer.Models.Application;
|
||||
|
||||
public class CommonUserDataResponse
|
||||
{
|
||||
public uint Result { get; set; }
|
||||
public byte[] ToneFlg { get; set; } = [];
|
||||
public byte[] TitleFlg { get; set; } = [];
|
||||
public byte[] ReleaseSongFlg { get; set; } = [];
|
||||
public byte[] UraReleaseSongFlg { get; set; } = [];
|
||||
public uint[] AryFavoriteSongNoes { get; set; } = [];
|
||||
public uint[] AryRecentSongNoes { get; set; } = [];
|
||||
public uint DispScoreType { get; set; }
|
||||
public uint DispLevelChassis { get; set; }
|
||||
public uint DispLevelSelf { get; set; }
|
||||
public bool IsDispTojiruOn { get; set; }
|
||||
public byte[] DefaultOptionSetting { get; set; } = [];
|
||||
public int NotesPosition { get; set; }
|
||||
public bool IsVoiceOn { get; set; }
|
||||
public bool IsSkipOn { get; set; }
|
||||
public uint DifficultySettingCourse { get; set; }
|
||||
public uint DifficultySettingStar { get; set; }
|
||||
public uint DifficultySettingSort { get; set; }
|
||||
public uint DifficultyPlayedCourse { get; set; }
|
||||
public uint DifficultyPlayedStar { get; set; }
|
||||
public uint DifficultyPlayedSort { get; set; }
|
||||
public uint TotalCreditCnt { get; set; }
|
||||
public uint SongRecentCnt { get; set; }
|
||||
public bool IsChallengecompe { get; set; }
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user