fix(tk2): rewards array uses ReceivedReward shape (reward_detail_id/item_type/is_usable)
The /retire and /finish responses carry two reward arrays with DIFFERENT
key schemas:
rewards[] → ReceivedReward(JsonData) parser
{reward_type, reward_detail_id, item_type, reward_count?, is_usable}
reward_list[] → PlayerStaticData.UpdateHaveUserGoodsNumByJsonData
{reward_type, reward_id, reward_num}
We were emitting both with reward_list's schema, so the client threw
KeyNotFoundException on `data["reward_detail_id"]` while parsing each
delta entry — observed live as the retire-screen failure.
- New TwoPickRewardReceivedDto mirrors the existing Achievement/
TotalReceiveCountDto shape.
- FinishResponseDto.Rewards switched from List<RewardEntryDto>
to List<TwoPickRewardReceivedDto>.
- GrantRunRewardsAndDeleteAsync pre-loads ItemEntry.Type for any
Item-typed reward so item_type ships correctly (0 for currencies).
- Existing tests renamed RewardNum→RewardCount on the deltas list.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -297,13 +297,31 @@ public class ArenaTwoPickService : IArenaTwoPickService
|
||||
var rewardRows = await _rewards.GetRewardsByWinCountAsync(run.WinCount);
|
||||
var viewer = await LoadViewerForGrantsAsync(viewerId);
|
||||
|
||||
var deltas = new List<RewardEntryDto>();
|
||||
// Pre-load item_type for any Item-typed reward so we can populate it on the
|
||||
// per-grant delta entries. Currencies don't need a lookup (item_type stays 0).
|
||||
var itemRewardIds = rewardRows
|
||||
.Where(r => r.RewardType == (int)SVSim.Database.Enums.UserGoodsType.Item)
|
||||
.Select(r => (int)r.RewardId)
|
||||
.Distinct()
|
||||
.ToList();
|
||||
var itemTypeById = itemRewardIds.Count == 0
|
||||
? new Dictionary<int, int>()
|
||||
: await _db.Items.Where(i => itemRewardIds.Contains(i.Id))
|
||||
.ToDictionaryAsync(i => i.Id, i => i.Type);
|
||||
|
||||
var deltas = new List<TwoPickRewardReceivedDto>();
|
||||
foreach (var r in rewardRows)
|
||||
{
|
||||
var goodsType = (SVSim.Database.Enums.UserGoodsType)r.RewardType;
|
||||
await _grants.ApplyAsync(viewer, goodsType, r.RewardId, r.RewardNum);
|
||||
// Rewards = deltas (per-grant amounts), not post-state totals.
|
||||
deltas.Add(new RewardEntryDto { RewardType = r.RewardType, RewardId = r.RewardId, RewardNum = r.RewardNum });
|
||||
deltas.Add(new TwoPickRewardReceivedDto
|
||||
{
|
||||
RewardType = r.RewardType,
|
||||
RewardDetailId = r.RewardId,
|
||||
RewardCount = r.RewardNum,
|
||||
ItemType = itemTypeById.TryGetValue((int)r.RewardId, out var t) ? t : 0,
|
||||
IsUsable = true,
|
||||
});
|
||||
}
|
||||
await _db.SaveChangesAsync();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user