fix(gift): wire reward_type is UserGoodsType integer, not legacy 1/4/9 encoding
Replace WireRewardTypeToUserGoodsType switch with a validating identity cast backed by GiftRewardTypes.IsSupported. Wire type 1 is RedEther (UserGoodsType.RedEther), not Crystal (UserGoodsType.Crystal=2); the old switch silently granted the wrong wallet for every tutorial-completion claim. Update all 5 GiftControllerTests assertions and 1 TutorialFlowEndToEndTests assertion to expect RedEther instead of Crystals. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -8,6 +8,7 @@ using SVSim.Database.Services.Inventory;
|
||||
using SVSim.EmulatedEntrypoint.Mapping;
|
||||
using SVSim.EmulatedEntrypoint.Models.Dtos.Requests.Gift;
|
||||
using SVSim.EmulatedEntrypoint.Models.Dtos.Responses.Gift;
|
||||
using SVSim.EmulatedEntrypoint.Services;
|
||||
|
||||
namespace SVSim.EmulatedEntrypoint.Controllers;
|
||||
|
||||
@@ -87,10 +88,6 @@ public class GiftController : SVSimController
|
||||
{
|
||||
if (state == 1)
|
||||
{
|
||||
// Wire reward_type on the gift endpoint follows a gift-specific scheme that
|
||||
// diverges from UserGoodsType for currencies: wire "1" means Crystal (enum=2),
|
||||
// wire "9" means Rupy (enum=9), wire "4" means Item (enum=4). A naked cast would
|
||||
// resolve wire 1 -> UserGoodsType.RedEther and silently grant the wrong wallet.
|
||||
var granted = await tx.GrantAsync(
|
||||
WireRewardTypeToUserGoodsType(p.RewardType),
|
||||
p.RewardDetailId,
|
||||
@@ -168,13 +165,17 @@ public class GiftController : SVSimController
|
||||
};
|
||||
}
|
||||
|
||||
private static UserGoodsType WireRewardTypeToUserGoodsType(int wireType) => wireType switch
|
||||
/// <summary>
|
||||
/// Gift wire's <c>reward_type</c> is a literal <see cref="UserGoodsType"/> integer — the
|
||||
/// client's <c>Wizard/RewardBase.cs:245</c> casts it directly to <c>UserGoods.Type</c>.
|
||||
/// Mirror that cast, validated against <see cref="GiftRewardTypes.IsSupported(int)"/>.
|
||||
/// </summary>
|
||||
private static UserGoodsType WireRewardTypeToUserGoodsType(int wireType)
|
||||
{
|
||||
1 => UserGoodsType.Crystal,
|
||||
4 => UserGoodsType.Item,
|
||||
9 => UserGoodsType.Rupy,
|
||||
_ => throw new InvalidOperationException($"Unmapped gift wire reward_type {wireType}"),
|
||||
};
|
||||
if (!GiftRewardTypes.IsSupported(wireType))
|
||||
throw new InvalidOperationException($"Unsupported gift reward_type {wireType}");
|
||||
return (UserGoodsType)wireType;
|
||||
}
|
||||
|
||||
private async Task<(List<ViewerPresent> Unclaimed, List<ViewerPresent> History)> ReadTopWindowAsync(
|
||||
long viewerId, int page)
|
||||
|
||||
Reference in New Issue
Block a user