diff --git a/SVSim.EmulatedEntrypoint/Services/BattlePassService.cs b/SVSim.EmulatedEntrypoint/Services/BattlePassService.cs index db097cd..0707e94 100644 --- a/SVSim.EmulatedEntrypoint/Services/BattlePassService.cs +++ b/SVSim.EmulatedEntrypoint/Services/BattlePassService.cs @@ -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); }