1
0
mirror of synced 2024-11-27 16:10:53 +01:00

Refactor reward tracking

This commit is contained in:
asesidaa 2022-09-14 16:50:06 +08:00
parent 0fa5dcc2b4
commit fafb353bdb
8 changed files with 146 additions and 115 deletions

View File

@ -1 +1 @@
wwwroot/music_attribute.json
wwwroot/data/music_attribute.json

View File

@ -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};
}

View File

@ -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;
}
}

View File

@ -14,6 +14,6 @@ public static class PathHelper
{
throw new ApplicationException();
}
return Path.Combine(parentPath.ToString(), "wwwroot");
return Path.Combine(parentPath.ToString(), "wwwroot", "data");
}
}

View File

@ -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;
}
}

View File

@ -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)
{

View File

@ -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()

View File

@ -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>