diff --git a/DorkNet.Server.Tests/WatchShop2023Tests.cs b/DorkNet.Server.Tests/WatchShop2023Tests.cs index 5acc114..0ac264d 100644 --- a/DorkNet.Server.Tests/WatchShop2023Tests.cs +++ b/DorkNet.Server.Tests/WatchShop2023Tests.cs @@ -42,6 +42,12 @@ public sealed class WatchShop2023Tests : IClassFixture Assert.Equal(JsonValueKind.String, giftDrop.GetProperty("TagList").ValueKind); var rarity = giftDrop.GetProperty("Rarity").GetInt32(); Assert.Contains(rarity, new[] { 0, 10, 20, 30, 50 }); + + // Int32 on the 2023 wire — a descriptor STRING here makes the + // strict Utf8Json reader throw "Malformed Response" for the + // whole storefront payload (expected:'Number Token'). + Assert.Equal(JsonValueKind.Number, giftDrop.GetProperty("AvatarItemId").ValueKind); + Assert.Equal(JsonValueKind.String, giftDrop.GetProperty("AvatarItemDesc").ValueKind); } // Featured strip: bare int ids, every one resolvable in the rows. diff --git a/DorkNet.Server/Services/StoreService.cs b/DorkNet.Server/Services/StoreService.cs index 1321617..e337859 100644 --- a/DorkNet.Server/Services/StoreService.cs +++ b/DorkNet.Server/Services/StoreService.cs @@ -985,15 +985,13 @@ public class StoreService(DorkNetDbContext db, LevelService level, IConfiguratio Tooltip = i.Description, AvatarItemDesc = avatarItemDesc, AvatarItemDescOrHairDyeDesc = avatarItemDesc, - // AvatarItemId is the field the 2023 client's StoreItemListModel - // actually reads (store-item +0x38) to resolve the card to a baked - // AvatarItem and read its OutfitType for tab placement — verified - // vs 2023 ISIL (EMBCEDNHFLB/CLIANCNHNIE, AvatarItem.GIJPCPDKHPO). - // AvatarItemDesc alone is NOT the join key, so clothing cards - // resolved to OutfitType=-1 and the Shop rendered empty. Ship the - // same {guid},,, descriptor (GIJPCPDKHPO accepts bare {guid} or the - // composite and falls back to parsing it to the immutable Guid). - AvatarItemId = avatarItemDesc, + // AvatarItemId is an Int32 on the 2023 wire (EMBCEDNHFLB + // serialiser writes field +0x60 with the same int writer as + // GiftDropId; the descriptor string lives in AvatarItemDesc + // +0x38). Shipping the {guid},,, descriptor here made the + // strict Utf8Json reader throw "Malformed Response" on the + // whole giftdropstore payload, so the Shop tab loaded nothing. + AvatarItemId = itemId, AvatarItemType = string.IsNullOrEmpty(avatarItemDesc) ? (int?)null : avatarItemType, ConsumableItemDesc = consumableItemDesc, EquipmentPrefabName = equipmentPrefabName,