Refactor reward tracking
This commit is contained in:
parent
0fa5dcc2b4
commit
fafb353bdb
2
TaikoLocalServer/.gitignore
vendored
2
TaikoLocalServer/.gitignore
vendored
@ -1 +1 @@
|
||||
wwwroot/music_attribute.json
|
||||
wwwroot/data/music_attribute.json
|
@ -35,4 +35,6 @@ public static class Constants
|
||||
public const int COSTUME_FLAG_3_ARRAY_SIZE = 156;
|
||||
public const int COSTUME_FLAG_4_ARRAY_SIZE = 58;
|
||||
public const int COSTUME_FLAG_5_ARRAY_SIZE = 129;
|
||||
|
||||
public static readonly int[] CostumeFlagArraySizes = {154, 140, 156, 58, 129};
|
||||
}
|
@ -1,4 +1,5 @@
|
||||
using System.Collections.Specialized;
|
||||
using System.Collections;
|
||||
using System.Collections.Specialized;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace TaikoLocalServer.Common.Utils;
|
||||
@ -106,4 +107,22 @@ public static class FlagCalculator
|
||||
gotDanFlagList.Add(gotDanFlag.Data);
|
||||
return MemoryMarshal.AsBytes(new ReadOnlySpan<int>(gotDanFlagList.ToArray())).ToArray();
|
||||
}
|
||||
|
||||
public static byte[] GetBitArrayFromIds(IEnumerable<uint> idArray, int bitArraySize, ILogger logger)
|
||||
{
|
||||
var result = new byte[bitArraySize / 8 + 1];
|
||||
var bitSet = new BitArray(bitArraySize + 1);
|
||||
foreach (var id in idArray)
|
||||
{
|
||||
if (id >= bitArraySize)
|
||||
{
|
||||
logger.LogWarning("Id out of range!");
|
||||
continue;
|
||||
}
|
||||
bitSet.Set((int)id, true);
|
||||
}
|
||||
bitSet.CopyTo(result, 0);
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
@ -14,6 +14,6 @@ public static class PathHelper
|
||||
{
|
||||
throw new ApplicationException();
|
||||
}
|
||||
return Path.Combine(parentPath.ToString(), "wwwroot");
|
||||
return Path.Combine(parentPath.ToString(), "wwwroot", "data");
|
||||
}
|
||||
}
|
@ -1,6 +1,4 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Collections;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json;
|
||||
using TaikoLocalServer.Services.Interfaces;
|
||||
using Throw;
|
||||
|
||||
@ -76,23 +74,9 @@ public class BaidController : BaseController<BaidController>
|
||||
datum.Difficulty == achievementDisplayDifficulty :
|
||||
datum.Difficulty is Difficulty.Oni or Difficulty.UraOni).ToList();
|
||||
|
||||
var crownCount = new uint[3];
|
||||
foreach (var crownType in Enum.GetValues<CrownType>())
|
||||
{
|
||||
if (crownType != CrownType.None)
|
||||
{
|
||||
crownCount[(int)crownType - 1] = (uint)songCountData.Count(datum => datum.BestCrown == crownType);
|
||||
}
|
||||
}
|
||||
var crownCount = CalculateCrownCount(songCountData);
|
||||
|
||||
var scoreRankCount = new uint[7];
|
||||
foreach (var scoreRankType in Enum.GetValues<ScoreRank>())
|
||||
{
|
||||
if (scoreRankType != ScoreRank.None)
|
||||
{
|
||||
scoreRankCount[(int)scoreRankType - 2] = (uint)songCountData.Count(datum => datum.BestScoreRank == scoreRankType);
|
||||
}
|
||||
}
|
||||
var scoreRankCount = CalculateScoreRankCount(songCountData);
|
||||
|
||||
|
||||
var costumeData = new List<uint>{ 0, 0, 0, 0, 0 };
|
||||
@ -124,45 +108,9 @@ public class BaidController : BaseController<BaidController>
|
||||
// which means database content need to be fixed, so better throw
|
||||
costumeArrays.ThrowIfNull("Costume flg should never be null!");
|
||||
|
||||
var costumeFlg1 = new byte[Constants.COSTUME_FLAG_1_ARRAY_SIZE];
|
||||
var bitSet = new BitArray(Constants.COSTUME_FLAG_1_ARRAY_SIZE);
|
||||
foreach (var costume in costumeArrays[0])
|
||||
{
|
||||
bitSet.Set((int)costume, true);
|
||||
}
|
||||
bitSet.CopyTo(costumeFlg1, 0);
|
||||
|
||||
var costumeFlg2 = new byte[Constants.COSTUME_FLAG_2_ARRAY_SIZE];
|
||||
bitSet = new BitArray(Constants.COSTUME_FLAG_2_ARRAY_SIZE);
|
||||
foreach (var costume in costumeArrays[1])
|
||||
{
|
||||
bitSet.Set((int)costume, true);
|
||||
}
|
||||
bitSet.CopyTo(costumeFlg2, 0);
|
||||
|
||||
var costumeFlg3 = new byte[Constants.COSTUME_FLAG_3_ARRAY_SIZE];
|
||||
bitSet = new BitArray(Constants.COSTUME_FLAG_3_ARRAY_SIZE);
|
||||
foreach (var costume in costumeArrays[2])
|
||||
{
|
||||
bitSet.Set((int)costume, true);
|
||||
}
|
||||
bitSet.CopyTo(costumeFlg3, 0);
|
||||
|
||||
var costumeFlg4 = new byte[Constants.COSTUME_FLAG_4_ARRAY_SIZE];
|
||||
bitSet = new BitArray(Constants.COSTUME_FLAG_4_ARRAY_SIZE);
|
||||
foreach (var costume in costumeArrays[3])
|
||||
{
|
||||
bitSet.Set((int)costume, true);
|
||||
}
|
||||
bitSet.CopyTo(costumeFlg4, 0);
|
||||
|
||||
var costumeFlg5 = new byte[Constants.COSTUME_FLAG_5_ARRAY_SIZE];
|
||||
bitSet = new BitArray(Constants.COSTUME_FLAG_5_ARRAY_SIZE);
|
||||
foreach (var costume in costumeArrays[4])
|
||||
{
|
||||
bitSet.Set((int)costume, true);
|
||||
}
|
||||
bitSet.CopyTo(costumeFlg5, 0);
|
||||
var costumeFlagArrays = Constants.CostumeFlagArraySizes
|
||||
.Select((size, index) => FlagCalculator.GetBitArrayFromIds(costumeArrays[index], size, Logger))
|
||||
.ToList();
|
||||
|
||||
var danData = await danScoreDatumService.GetDanScoreDatumByBaid(baid);
|
||||
|
||||
@ -199,11 +147,11 @@ public class BaidController : BaseController<BaidController>
|
||||
Costume4 = costumeData[3],
|
||||
Costume5 = costumeData[4]
|
||||
},
|
||||
CostumeFlg1 = costumeFlg1,
|
||||
CostumeFlg2 = costumeFlg2,
|
||||
CostumeFlg3 = costumeFlg3,
|
||||
CostumeFlg4 = costumeFlg4,
|
||||
CostumeFlg5 = costumeFlg5,
|
||||
CostumeFlg1 = costumeFlagArrays[0],
|
||||
CostumeFlg2 = costumeFlagArrays[1],
|
||||
CostumeFlg3 = costumeFlagArrays[2],
|
||||
CostumeFlg4 = costumeFlagArrays[3],
|
||||
CostumeFlg5 = costumeFlagArrays[4],
|
||||
LastPlayDatetime = userData.LastPlayDatetime.ToString(Constants.DATE_TIME_FORMAT),
|
||||
IsDispDanOn = userData.DisplayDan,
|
||||
GotDanMax = maxDan,
|
||||
@ -227,4 +175,32 @@ public class BaidController : BaseController<BaidController>
|
||||
return Ok(response);
|
||||
}
|
||||
|
||||
private static uint[] CalculateScoreRankCount(IReadOnlyCollection<SongBestDatum> songCountData)
|
||||
{
|
||||
var scoreRankCount = new uint[7];
|
||||
foreach (var scoreRankType in Enum.GetValues<ScoreRank>())
|
||||
{
|
||||
if (scoreRankType != ScoreRank.None)
|
||||
{
|
||||
scoreRankCount[(int)scoreRankType - 2] =
|
||||
(uint)songCountData.Count(datum => datum.BestScoreRank == scoreRankType);
|
||||
}
|
||||
}
|
||||
|
||||
return scoreRankCount;
|
||||
}
|
||||
|
||||
private static uint[] CalculateCrownCount(IReadOnlyCollection<SongBestDatum> songCountData)
|
||||
{
|
||||
var crownCount = new uint[3];
|
||||
foreach (var crownType in Enum.GetValues<CrownType>())
|
||||
{
|
||||
if (crownType != CrownType.None)
|
||||
{
|
||||
crownCount[(int)crownType - 1] = (uint)songCountData.Count(datum => datum.BestCrown == crownType);
|
||||
}
|
||||
}
|
||||
|
||||
return crownCount;
|
||||
}
|
||||
}
|
@ -1,7 +1,6 @@
|
||||
using System.Buffers.Binary;
|
||||
using System.Globalization;
|
||||
using System.Text.Json;
|
||||
using TaikoLocalServer.Entities;
|
||||
using TaikoLocalServer.Services.Interfaces;
|
||||
using Throw;
|
||||
|
||||
@ -66,7 +65,7 @@ public class PlayResultController : BaseController<PlayResultController>
|
||||
|
||||
if (playMode == PlayMode.AiBattle)
|
||||
{
|
||||
await UpdateAiBattleData(request, stageData);
|
||||
// await UpdateAiBattleData(request, stageData);
|
||||
// Update AI win count here somewhere, or in UpdatePlayData?
|
||||
// I have no clue how to update input median or variance
|
||||
}
|
||||
@ -75,7 +74,7 @@ public class PlayResultController : BaseController<PlayResultController>
|
||||
|
||||
await UpdatePlayData(request, songNumber, stageData, lastPlayDatetime);
|
||||
}
|
||||
|
||||
|
||||
return Ok(response);
|
||||
}
|
||||
|
||||
@ -193,23 +192,80 @@ public class PlayResultController : BaseController<PlayResultController>
|
||||
userdata.LastPlayDatetime = lastPlayDatetime;
|
||||
userdata.LastPlayMode = playResultData.PlayMode;
|
||||
|
||||
var toneFlgData = JsonSerializer.Deserialize<List<uint>>(userdata.ToneFlgArray);
|
||||
toneFlgData?.AddRange(playResultData.GetToneNoes ?? new uint[0]);
|
||||
userdata.ToneFlgArray = JsonSerializer.Serialize(toneFlgData);
|
||||
var titleFlgData = JsonSerializer.Deserialize<List<uint>>(userdata.TitleFlgArray);
|
||||
titleFlgData?.AddRange(playResultData.GetTitleNoes ?? new uint[0]);
|
||||
userdata.TitleFlgArray = JsonSerializer.Serialize(titleFlgData);
|
||||
var costumeFlgData = JsonSerializer.Deserialize<List<List<uint>>>(userdata.CostumeFlgArray);
|
||||
costumeFlgData?[0].AddRange(playResultData.GetCostumeNo1s ?? new uint[0]);
|
||||
costumeFlgData?[1].AddRange(playResultData.GetCostumeNo2s ?? new uint[0]);
|
||||
costumeFlgData?[2].AddRange(playResultData.GetCostumeNo3s ?? new uint[0]);
|
||||
costumeFlgData?[3].AddRange(playResultData.GetCostumeNo4s ?? new uint[0]);
|
||||
costumeFlgData?[4].AddRange(playResultData.GetCostumeNo5s ?? new uint[0]);
|
||||
userdata.CostumeFlgArray = JsonSerializer.Serialize(costumeFlgData);
|
||||
userdata.ToneFlgArray =
|
||||
UpdateJsonUintFlagArray(userdata.ToneFlgArray, playResultData.GetToneNoes, nameof(userdata.ToneFlgArray));
|
||||
|
||||
userdata.TitleFlgArray =
|
||||
UpdateJsonUintFlagArray(userdata.TitleFlgArray, playResultData.GetTitleNoes,
|
||||
nameof(userdata.TitleFlgArray));
|
||||
|
||||
userdata.CostumeFlgArray = UpdateJsonCostumeFlagArray(userdata.CostumeFlgArray,
|
||||
new[]
|
||||
{
|
||||
playResultData.GetCostumeNo1s,
|
||||
playResultData.GetCostumeNo2s,
|
||||
playResultData.GetCostumeNo3s,
|
||||
playResultData.GetCostumeNo4s,
|
||||
playResultData.GetCostumeNo5s
|
||||
});
|
||||
|
||||
await userDatumService.UpdateUserDatum(userdata);
|
||||
}
|
||||
|
||||
private string UpdateJsonUintFlagArray(string originalValue, IReadOnlyCollection<uint>? newValue, string fieldName)
|
||||
{
|
||||
var flgData = new List<uint>();
|
||||
try
|
||||
{
|
||||
flgData = JsonSerializer.Deserialize<List<uint>>(originalValue);
|
||||
}
|
||||
catch (JsonException e)
|
||||
{
|
||||
Logger.LogError(e, "Parsing {FieldName} json data failed", fieldName);
|
||||
}
|
||||
|
||||
flgData?.AddRange(newValue ?? Array.Empty<uint>());
|
||||
var flgArray = flgData ?? new List<uint>();
|
||||
return JsonSerializer.Serialize(flgArray);
|
||||
}
|
||||
|
||||
private string UpdateJsonCostumeFlagArray(string originalValue, IReadOnlyList<IReadOnlyCollection<uint>?>? newValue)
|
||||
{
|
||||
var flgData = new List<List<uint>>();
|
||||
try
|
||||
{
|
||||
flgData = JsonSerializer.Deserialize<List<List<uint>>>(originalValue);
|
||||
}
|
||||
catch (JsonException e)
|
||||
{
|
||||
Logger.LogError(e, "Parsing Costume flag json data failed");
|
||||
}
|
||||
|
||||
if (flgData is null)
|
||||
{
|
||||
flgData = new List<List<uint>>();
|
||||
}
|
||||
|
||||
for (var index = 0; index < flgData.Count; index++)
|
||||
{
|
||||
var subFlgData = flgData[index];
|
||||
subFlgData.AddRange(newValue?[index] ?? Array.Empty<uint>());
|
||||
}
|
||||
|
||||
if (flgData.Count >= 5)
|
||||
{
|
||||
return JsonSerializer.Serialize(flgData);
|
||||
}
|
||||
|
||||
Logger.LogWarning("Costume flag array count less than 5!");
|
||||
flgData = new List<List<uint>>
|
||||
{
|
||||
new(), new(), new(), new(), new()
|
||||
};
|
||||
|
||||
return JsonSerializer.Serialize(flgData);
|
||||
}
|
||||
|
||||
private async Task UpdateBestData(PlayResultRequest request, StageData stageData,
|
||||
IEnumerable<SongBestDatum> bestData)
|
||||
{
|
||||
@ -231,7 +287,8 @@ public class PlayResultController : BaseController<PlayResultController>
|
||||
await songBestDatumService.UpdateOrInsertSongBestDatum(bestDatum);
|
||||
}
|
||||
|
||||
private async Task UpdateAiBattleData(PlayResultRequest request, StageData stageData)
|
||||
// TODO: AI battle
|
||||
/*private async Task UpdateAiBattleData(PlayResultRequest request, StageData stageData)
|
||||
{
|
||||
for (int i = 0; i < stageData.ArySectionDatas.Count; i++)
|
||||
{
|
||||
@ -242,7 +299,7 @@ public class PlayResultController : BaseController<PlayResultController>
|
||||
// if any aspect of the section is higher than the previous best, update it
|
||||
// Similar to Dan best play updates
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
private static CrownType PlayResultToCrown(StageData stageData)
|
||||
{
|
||||
|
@ -1,5 +1,4 @@
|
||||
using System.Buffers.Binary;
|
||||
using System.Collections;
|
||||
using System.Text.Json;
|
||||
using TaikoLocalServer.Services.Interfaces;
|
||||
using Throw;
|
||||
@ -28,21 +27,11 @@ public class UserDataController : BaseController<UserDataController>
|
||||
|
||||
var musicAttributeManager = MusicAttributeManager.Instance;
|
||||
|
||||
var releaseSongArray = new byte[Constants.MUSIC_FLAG_ARRAY_SIZE];
|
||||
var bitSet = new BitArray(Constants.MUSIC_ID_MAX);
|
||||
foreach (var music in musicAttributeManager.Musics)
|
||||
{
|
||||
bitSet.Set((int)music, true);
|
||||
}
|
||||
bitSet.CopyTo(releaseSongArray, 0);
|
||||
|
||||
var uraSongArray = new byte[Constants.MUSIC_FLAG_ARRAY_SIZE];
|
||||
bitSet.SetAll(false);
|
||||
foreach (var music in musicAttributeManager.MusicsWithUra)
|
||||
{
|
||||
bitSet.Set((int)music, true);
|
||||
}
|
||||
bitSet.CopyTo(uraSongArray, 0);
|
||||
var releaseSongArray =
|
||||
FlagCalculator.GetBitArrayFromIds(musicAttributeManager.Musics, Constants.MUSIC_ID_MAX, Logger);
|
||||
|
||||
var uraSongArray =
|
||||
FlagCalculator.GetBitArrayFromIds(musicAttributeManager.MusicsWithUra, Constants.MUSIC_ID_MAX, Logger);
|
||||
|
||||
var userData = await userDatumService.GetFirstUserDatumOrDefault(request.Baid);
|
||||
|
||||
@ -60,13 +49,7 @@ public class UserDataController : BaseController<UserDataController>
|
||||
// which means database content need to be fixed, so better throw
|
||||
toneFlg.ThrowIfNull("Tone flg should never be null!");
|
||||
|
||||
var toneArray = new byte[Constants.TONE_UID_MAX];
|
||||
bitSet = new BitArray(Constants.TONE_UID_MAX);
|
||||
foreach (var tone in toneFlg)
|
||||
{
|
||||
bitSet.Set((int)tone, true);
|
||||
}
|
||||
bitSet.CopyTo(toneArray, 0);
|
||||
var toneArray = FlagCalculator.GetBitArrayFromIds(toneFlg, Constants.TONE_UID_MAX, Logger);
|
||||
|
||||
var titleFlg = Array.Empty<uint>();
|
||||
try
|
||||
@ -82,13 +65,7 @@ public class UserDataController : BaseController<UserDataController>
|
||||
// which means database content need to be fixed, so better throw
|
||||
titleFlg.ThrowIfNull("Title flg should never be null!");
|
||||
|
||||
var titleArray = new byte[Constants.TITLE_UID_MAX];
|
||||
bitSet = new BitArray(Constants.TITLE_UID_MAX);
|
||||
foreach (var title in titleFlg)
|
||||
{
|
||||
bitSet.Set((int)title, true);
|
||||
}
|
||||
bitSet.CopyTo(titleArray, 0);
|
||||
var titleArray = FlagCalculator.GetBitArrayFromIds(titleFlg, Constants.TITLE_UID_MAX, Logger);
|
||||
|
||||
var recentSongs = (await songPlayDatumService.GetSongPlayDatumByBaid(request.Baid))
|
||||
.AsEnumerable()
|
||||
|
@ -38,7 +38,7 @@
|
||||
<Content Update="wwwroot\dan_data.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="wwwroot\music_attribute.json">
|
||||
<Content Update="wwwroot\data\music_attribute.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
|
Loading…
Reference in New Issue
Block a user