Stage Changes
This commit is contained in:
parent
a88965bdd1
commit
adb101261a
@ -35,7 +35,7 @@ namespace GameDatabase.Entities
|
|||||||
public Difficulty AchievementDisplayDifficulty { get; set; }
|
public Difficulty AchievementDisplayDifficulty { get; set; }
|
||||||
public int AiWinCount { get; set; }
|
public int AiWinCount { get; set; }
|
||||||
public List<Token> Tokens { get; set; } = new();
|
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; }
|
public bool IsAdmin { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -4,7 +4,7 @@
|
|||||||
<TargetFramework>net8.0</TargetFramework>
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
<LangVersion>11</LangVersion>
|
<LangVersion>12</LangVersion>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
@ -1,57 +1,30 @@
|
|||||||
using System.Text.Json;
|
using TaikoLocalServer.Mappers;
|
||||||
using Throw;
|
|
||||||
|
|
||||||
namespace TaikoLocalServer.Controllers.Game;
|
namespace TaikoLocalServer.Controllers.Game;
|
||||||
|
|
||||||
[Route("/v12r08_ww/chassis/songpurchase_wm2fh5bl.php")]
|
|
||||||
[ApiController]
|
[ApiController]
|
||||||
public class SongPurchaseController : BaseController<SongPurchaseController>
|
public class SongPurchaseController : BaseController<SongPurchaseController>
|
||||||
{
|
{
|
||||||
private readonly IUserDatumService userDatumService;
|
[HttpPost("/v12r08_ww/chassis/songpurchase_wm2fh5bl.php")]
|
||||||
|
|
||||||
public SongPurchaseController(IUserDatumService userDatumService)
|
|
||||||
{
|
|
||||||
this.userDatumService = userDatumService;
|
|
||||||
}
|
|
||||||
|
|
||||||
[HttpPost]
|
|
||||||
[Produces("application/protobuf")]
|
[Produces("application/protobuf")]
|
||||||
public async Task<IActionResult> SongPurchase([FromBody] SongPurchaseRequest request)
|
public async Task<IActionResult> SongPurchase([FromBody] SongPurchaseRequest request)
|
||||||
{
|
{
|
||||||
Logger.LogInformation("SongPurchase request : {Request}", request.Stringify());
|
Logger.LogInformation("SongPurchase request : {Request}", request.Stringify());
|
||||||
|
|
||||||
var user = await userDatumService.GetFirstUserDatumOrNull(request.Baid);
|
var commonResponse = await Mediator.Send(SongPurchaseMappers.MapToCommand(request));
|
||||||
user.ThrowIfNull($"User with baid {request.Baid} does not exist!");
|
var response = SongPurchaseMappers.MapTo3906(commonResponse);
|
||||||
|
|
||||||
Logger.LogInformation("Original UnlockedSongIdList: {UnlockedSongIdList}", user.UnlockedSongIdList);
|
return Ok(response);
|
||||||
|
}
|
||||||
var unlockedSongIdList = user.UnlockedSongIdList.ToList();
|
|
||||||
|
[HttpPost("/v12r00_cn/chassis/songpurchase.php")]
|
||||||
var token = user.Tokens.FirstOrDefault(t => t.Id == request.TokenId);
|
[Produces("application/protobuf")]
|
||||||
if (token is not null && token.Count >= request.Price)
|
public async Task<IActionResult> SongPurchase3209([FromBody] Models.v3209.SongPurchaseRequest request)
|
||||||
{
|
{
|
||||||
token.Count -= (int)request.Price;
|
Logger.LogInformation("SongPurchase request : {Request}", request.Stringify());
|
||||||
}
|
|
||||||
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.MapTo3209(commonResponse);
|
||||||
return Ok(response);
|
return Ok(response);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,178 +1,36 @@
|
|||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
using System.Buffers.Binary;
|
using System.Buffers.Binary;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
|
using TaikoLocalServer.Handlers;
|
||||||
|
using TaikoLocalServer.Mappers;
|
||||||
using TaikoLocalServer.Settings;
|
using TaikoLocalServer.Settings;
|
||||||
using Throw;
|
using Throw;
|
||||||
|
|
||||||
namespace TaikoLocalServer.Controllers.Game;
|
namespace TaikoLocalServer.Controllers.Game;
|
||||||
|
|
||||||
[Route("/v12r08_ww/chassis/userdata_gc6x17o8.php")]
|
|
||||||
[ApiController]
|
[ApiController]
|
||||||
public class UserDataController : BaseController<UserDataController>
|
public class UserDataController : BaseController<UserDataController>
|
||||||
{
|
{
|
||||||
private readonly IUserDatumService userDatumService;
|
[HttpPost("/v12r08_ww/chassis/userdata_gc6x17o8.php")]
|
||||||
|
|
||||||
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]
|
|
||||||
[Produces("application/protobuf")]
|
[Produces("application/protobuf")]
|
||||||
public async Task<IActionResult> GetUserData([FromBody] UserDataRequest request)
|
public async Task<IActionResult> GetUserData([FromBody] UserDataRequest request)
|
||||||
{
|
{
|
||||||
Logger.LogInformation("UserData request : {Request}", request.Stringify());
|
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>();
|
var commonResponse = await Mediator.Send(new UserDataQuery((uint)request.Baid));
|
||||||
try
|
var response = UserDataMappers.MapTo3209(commonResponse);
|
||||||
{
|
|
||||||
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
|
|
||||||
};
|
|
||||||
|
|
||||||
return Ok(response);
|
return Ok(response);
|
||||||
}
|
}
|
||||||
|
@ -30,6 +30,27 @@ public class VerifyQrCodeController : BaseController<VerifyQrCodeController>
|
|||||||
|
|
||||||
return Ok(response);
|
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)
|
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