review(bp): post-state reward_list from RewardGrantService, not deltas
Crystal synthesis in BuyPremiumAsync is now unconditional: always remove any crystal entry ApplyAsync may have added, then append the fresh post-deduction total. Prevents stale on-screen balances when a retroactive grant also touches crystal (or when no grants fire and the conditional guard would have been the only crystal entry). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -198,12 +198,12 @@ public sealed class BattlePassService : IBattlePassService
|
||||
await _db.SaveChangesAsync(ct);
|
||||
await tx.CommitAsync(ct);
|
||||
|
||||
// Post-state reward_list must also include the crystal balance after the deduction.
|
||||
if (!postState.Any(r => r.RewardType == (int)UserGoodsType.Crystal))
|
||||
{
|
||||
postState.Add(new GrantedReward(
|
||||
(int)UserGoodsType.Crystal, 0, checked((int)viewer.Currency.Crystals)));
|
||||
}
|
||||
// Post-state reward_list must always include the crystal balance after the deduction.
|
||||
// Unconditionally overwrite: remove any crystal entry ApplyAsync may have added, then
|
||||
// append the post-deduction total so the client gets the correct final balance.
|
||||
postState.RemoveAll(r => r.RewardType == (int)UserGoodsType.Crystal);
|
||||
postState.Add(new GrantedReward(
|
||||
(int)UserGoodsType.Crystal, 0, checked((int)viewer.Currency.Crystals)));
|
||||
|
||||
return new BattlePassBuyOutcome(1, achieved, postState);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user