fix(gateway): expose mic seat animation appearance
This commit is contained in:
parent
152bdf232e
commit
55770ce23b
@ -62,6 +62,18 @@ GET /api/v1/users/me/appearance
|
||||
"entitlement_id": "ent-vehicle",
|
||||
"expires_at_ms": 1999999999999
|
||||
},
|
||||
"mic_seat_animation": {
|
||||
"resource_id": 8106,
|
||||
"resource_code": "mic_seat_wave_gold",
|
||||
"resource_type": "mic_seat_animation",
|
||||
"name": "Gold Mic Wave",
|
||||
"asset_url": "https://cdn.example/mic-seat.png",
|
||||
"preview_url": "",
|
||||
"animation_url": "https://cdn.example/mic-seat.svga",
|
||||
"metadata_json": "{}",
|
||||
"entitlement_id": "ent-mic-seat-wave",
|
||||
"expires_at_ms": 1999999999999
|
||||
},
|
||||
"equipped_badges": [],
|
||||
"badges": [
|
||||
{
|
||||
@ -94,7 +106,20 @@ GET /api/v1/users/me/appearance
|
||||
"honor_badges": [],
|
||||
"server_time_ms": 1778256000000
|
||||
},
|
||||
"resources": [],
|
||||
"resources": [
|
||||
{
|
||||
"resource_id": 8106,
|
||||
"resource_code": "mic_seat_wave_gold",
|
||||
"resource_type": "mic_seat_animation",
|
||||
"name": "Gold Mic Wave",
|
||||
"asset_url": "https://cdn.example/mic-seat.png",
|
||||
"preview_url": "",
|
||||
"animation_url": "https://cdn.example/mic-seat.svga",
|
||||
"metadata_json": "{}",
|
||||
"entitlement_id": "ent-mic-seat-wave",
|
||||
"expires_at_ms": 1999999999999
|
||||
}
|
||||
],
|
||||
"server_time_ms": 1778256000000
|
||||
}
|
||||
```
|
||||
@ -107,6 +132,7 @@ GET /api/v1/users/me/appearance
|
||||
| avatar_frame | 当前佩戴头像框,未佩戴时为 `{}` |
|
||||
| profile_card | 当前佩戴背景卡,未佩戴时为 `{}` |
|
||||
| vehicle | 当前佩戴入场座驾,未佩戴时为 `{}` |
|
||||
| mic_seat_animation | 当前佩戴麦位声波,未佩戴时为 `{}` |
|
||||
| equipped_badges | wallet 当前佩戴的 badge 权益 |
|
||||
| badges | 房间、公屏等高频展示用徽章,取 `strip_badges` |
|
||||
| badge_profile | 完整徽章展示配置 |
|
||||
@ -116,7 +142,7 @@ GET /api/v1/users/me/appearance
|
||||
说明:
|
||||
|
||||
- 过期佩戴不会返回。
|
||||
- 头像框、背景卡、入场座驾来自 wallet 当前佩戴。
|
||||
- 头像框、背景卡、入场座驾、麦位声波来自 wallet 当前佩戴。
|
||||
- 徽章展示配置来自 activity。
|
||||
- 客户端渲染动画优先使用 `animation_url`,没有动画时用 `asset_url` 或 `preview_url` 兜底。
|
||||
|
||||
@ -345,6 +371,18 @@ GET /api/v1/users/room-display-profiles:batch?user_ids=42,43
|
||||
"entitlement_id": "ent-vehicle",
|
||||
"expires_at_ms": 1999999999999
|
||||
},
|
||||
"mic_seat_animation": {
|
||||
"resource_id": 8106,
|
||||
"resource_code": "mic_seat_wave_gold",
|
||||
"resource_type": "mic_seat_animation",
|
||||
"name": "Gold Mic Wave",
|
||||
"asset_url": "https://cdn.example/mic-seat.png",
|
||||
"preview_url": "",
|
||||
"animation_url": "https://cdn.example/mic-seat.svga",
|
||||
"metadata_json": "{}",
|
||||
"entitlement_id": "ent-mic-seat-wave",
|
||||
"expires_at_ms": 1999999999999
|
||||
},
|
||||
"charm": 0
|
||||
}
|
||||
]
|
||||
@ -356,6 +394,7 @@ GET /api/v1/users/room-display-profiles:batch?user_ids=42,43
|
||||
- 房间、公屏、在线列表展示头像框用 `avatar_frame`。
|
||||
- 房间资料卡展示用 `profile_card`,从 `metadata_json.profile_card_layout` 解析 `content_top` 和 `content_height`。
|
||||
- 入场座驾展示用 `vehicle`。
|
||||
- 麦位声波展示用 `mic_seat_animation`。
|
||||
- 徽章条展示用 `badges`。
|
||||
- 过期佩戴不会返回。
|
||||
|
||||
|
||||
@ -2440,6 +2440,17 @@ func TestJoinRoomReturnsInitialDataWithIMGroupRTCTokenAndProfiles(t *testing.T)
|
||||
GrantStrategy: "extend_expiry",
|
||||
Status: "active",
|
||||
}
|
||||
micSeatResource := &walletv1.Resource{
|
||||
ResourceId: 8106,
|
||||
ResourceCode: "mic_seat_wave_gold",
|
||||
ResourceType: "mic_seat_animation",
|
||||
Name: "Gold Mic Wave",
|
||||
AssetUrl: "https://cdn.example/mic-seat.png",
|
||||
AnimationUrl: "https://cdn.example/mic-seat.svga",
|
||||
MetadataJson: `{"usage":"mic_seat"}`,
|
||||
GrantStrategy: "set_active_flag",
|
||||
Status: "active",
|
||||
}
|
||||
shortBadgeResource := &walletv1.Resource{
|
||||
ResourceId: 8105,
|
||||
ResourceCode: "badge_tile_gold",
|
||||
@ -2471,6 +2482,14 @@ func TestJoinRoomReturnsInitialDataWithIMGroupRTCTokenAndProfiles(t *testing.T)
|
||||
Equipped: true,
|
||||
ExpiresAtMs: 1999999999999,
|
||||
},
|
||||
{
|
||||
UserId: 42,
|
||||
EntitlementId: "ent-mic-seat-wave",
|
||||
ResourceId: 8106,
|
||||
Resource: micSeatResource,
|
||||
Equipped: true,
|
||||
ExpiresAtMs: 1999999999999,
|
||||
},
|
||||
},
|
||||
}},
|
||||
},
|
||||
@ -2531,13 +2550,13 @@ func TestJoinRoomReturnsInitialDataWithIMGroupRTCTokenAndProfiles(t *testing.T)
|
||||
}
|
||||
hasRoomDisplayResourceQuery := false
|
||||
for _, req := range walletClient.batchEquippedRequests {
|
||||
if strings.Join(req.GetResourceTypes(), ",") == "avatar_frame,profile_card,vehicle,badge" {
|
||||
if strings.Join(req.GetResourceTypes(), ",") == "avatar_frame,profile_card,vehicle,badge,mic_seat_animation" {
|
||||
hasRoomDisplayResourceQuery = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !hasRoomDisplayResourceQuery {
|
||||
t.Fatalf("join response must batch room wearable resources including profile_card: %+v", walletClient.batchEquippedRequests)
|
||||
t.Fatalf("join response must batch room wearable resources including mic_seat_animation: %+v", walletClient.batchEquippedRequests)
|
||||
}
|
||||
profiles, profilesOK := data["profiles"].([]any)
|
||||
if !profilesOK || len(profiles) == 0 {
|
||||
@ -2557,6 +2576,10 @@ func TestJoinRoomReturnsInitialDataWithIMGroupRTCTokenAndProfiles(t *testing.T)
|
||||
if !profileCardOK || profileCard["resource_id"] != float64(8104) || !strings.Contains(metadataJSON, `"content_top":143`) {
|
||||
t.Fatalf("join profile must include profile_card metadata_json: %+v", currentProfile)
|
||||
}
|
||||
micSeatAnimation, micSeatAnimationOK := currentProfile["mic_seat_animation"].(map[string]any)
|
||||
if !micSeatAnimationOK || micSeatAnimation["resource_id"] != float64(8106) || micSeatAnimation["animation_url"] != "https://cdn.example/mic-seat.svga" {
|
||||
t.Fatalf("join profile must include mic_seat_animation resource: %+v", currentProfile)
|
||||
}
|
||||
badges, badgesOK := currentProfile["badges"].([]any)
|
||||
if !badgesOK || len(badges) != 1 {
|
||||
t.Fatalf("join profile must include equipped badge list: %+v", currentProfile["badges"])
|
||||
@ -5928,6 +5951,17 @@ func TestAppearanceAggregatesEquippedResourcesAndBadges(t *testing.T) {
|
||||
GrantStrategy: "set_active_flag",
|
||||
Status: "active",
|
||||
}
|
||||
micSeatResource := &walletv1.Resource{
|
||||
ResourceId: 8106,
|
||||
ResourceCode: "mic_seat_wave_gold",
|
||||
ResourceType: "mic_seat_animation",
|
||||
Name: "Gold Mic Wave",
|
||||
AssetUrl: "https://cdn.example/mic-seat.png",
|
||||
AnimationUrl: "https://cdn.example/mic-seat.svga",
|
||||
MetadataJson: `{"usage":"mic_seat"}`,
|
||||
GrantStrategy: "set_active_flag",
|
||||
Status: "active",
|
||||
}
|
||||
walletClient := &fakeWalletClient{
|
||||
batchEquippedResp: &walletv1.BatchGetUserEquippedResourcesResponse{
|
||||
Users: []*walletv1.UserEquippedResources{{
|
||||
@ -5937,6 +5971,7 @@ func TestAppearanceAggregatesEquippedResourcesAndBadges(t *testing.T) {
|
||||
{UserId: 42, EntitlementId: "ent-vehicle", ResourceId: 8102, Resource: vehicleResource, Equipped: true, ExpiresAtMs: 1999999999999},
|
||||
{UserId: 42, EntitlementId: "ent-profile-card", ResourceId: 8104, Resource: profileCardResource, Equipped: true, ExpiresAtMs: 1999999999999},
|
||||
{UserId: 42, EntitlementId: "ent-badge", ResourceId: 8103, Resource: badgeResource, Equipped: true, ExpiresAtMs: 1999999999999},
|
||||
{UserId: 42, EntitlementId: "ent-mic-seat-wave", ResourceId: 8106, Resource: micSeatResource, Equipped: true, ExpiresAtMs: 1999999999999},
|
||||
},
|
||||
}},
|
||||
},
|
||||
@ -5986,6 +6021,11 @@ func TestAppearanceAggregatesEquippedResourcesAndBadges(t *testing.T) {
|
||||
ResourceID int64 `json:"resource_id"`
|
||||
MetadataJSON string `json:"metadata_json"`
|
||||
} `json:"profile_card"`
|
||||
MicSeatAnimation struct {
|
||||
ResourceID int64 `json:"resource_id"`
|
||||
AnimationURL string `json:"animation_url"`
|
||||
EntitlementID string `json:"entitlement_id"`
|
||||
} `json:"mic_seat_animation"`
|
||||
EquippedBadges []struct {
|
||||
ResourceID int64 `json:"resource_id"`
|
||||
} `json:"equipped_badges"`
|
||||
@ -5995,6 +6035,10 @@ func TestAppearanceAggregatesEquippedResourcesAndBadges(t *testing.T) {
|
||||
AssetURL string `json:"asset_url"`
|
||||
} `json:"resource"`
|
||||
} `json:"badges"`
|
||||
Resources []struct {
|
||||
ResourceID int64 `json:"resource_id"`
|
||||
ResourceType string `json:"resource_type"`
|
||||
} `json:"resources"`
|
||||
} `json:"data"`
|
||||
}
|
||||
if err := json.NewDecoder(recorder.Body).Decode(&envelope); err != nil {
|
||||
@ -6003,12 +6047,25 @@ func TestAppearanceAggregatesEquippedResourcesAndBadges(t *testing.T) {
|
||||
if walletClient.lastBatchEquipped == nil || walletClient.lastBatchEquipped.GetUserIds()[0] != 42 {
|
||||
t.Fatalf("appearance should batch query equipped resources: %+v", walletClient.lastBatchEquipped)
|
||||
}
|
||||
if strings.Join(walletClient.lastBatchEquipped.GetResourceTypes(), ",") != "avatar_frame,profile_card,vehicle,badge,mic_seat_animation" {
|
||||
t.Fatalf("appearance should query mic_seat_animation with wearable resources: %+v", walletClient.lastBatchEquipped.GetResourceTypes())
|
||||
}
|
||||
if achievementClient.lastBadges == nil || achievementClient.lastBadges.GetUserId() != 42 {
|
||||
t.Fatalf("appearance should query displayed badges: %+v", achievementClient.lastBadges)
|
||||
}
|
||||
if envelope.Code != httpkit.CodeOK || envelope.Data.UserID != "42" || envelope.Data.AvatarFrame.AnimationURL != "https://cdn.example/frame.svga" || envelope.Data.Vehicle.ResourceID != 8102 || envelope.Data.ProfileCard.ResourceID != 8104 || !strings.Contains(envelope.Data.ProfileCard.MetadataJSON, `"content_top":117`) || len(envelope.Data.EquippedBadges) != 1 || len(envelope.Data.Badges) != 1 || envelope.Data.Badges[0].Resource.AssetURL != "https://cdn.example/badge.png" {
|
||||
if envelope.Code != httpkit.CodeOK || envelope.Data.UserID != "42" || envelope.Data.AvatarFrame.AnimationURL != "https://cdn.example/frame.svga" || envelope.Data.Vehicle.ResourceID != 8102 || envelope.Data.ProfileCard.ResourceID != 8104 || !strings.Contains(envelope.Data.ProfileCard.MetadataJSON, `"content_top":117`) || envelope.Data.MicSeatAnimation.ResourceID != 8106 || envelope.Data.MicSeatAnimation.AnimationURL != "https://cdn.example/mic-seat.svga" || envelope.Data.MicSeatAnimation.EntitlementID != "ent-mic-seat-wave" || len(envelope.Data.EquippedBadges) != 1 || len(envelope.Data.Badges) != 1 || envelope.Data.Badges[0].Resource.AssetURL != "https://cdn.example/badge.png" {
|
||||
t.Fatalf("appearance response mismatch: %+v", envelope)
|
||||
}
|
||||
hasMicSeatResource := false
|
||||
for _, resource := range envelope.Data.Resources {
|
||||
if resource.ResourceID == 8106 && resource.ResourceType == "mic_seat_animation" {
|
||||
hasMicSeatResource = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !hasMicSeatResource {
|
||||
t.Fatalf("appearance resources must include equipped mic_seat_animation: %+v", envelope.Data.Resources)
|
||||
}
|
||||
}
|
||||
|
||||
func TestListEmojiPacksFiltersRegionAndReturnsAssets(t *testing.T) {
|
||||
|
||||
@ -24,6 +24,13 @@ import (
|
||||
const (
|
||||
defaultRoomFeedRelationPageSize = 100
|
||||
maxRoomFeedRelationScanCount = 500
|
||||
|
||||
// 房间展示资料只读取客户端能在首屏、公屏或资料卡直接渲染的当前佩戴资源。
|
||||
roomAppearanceResourceAvatarFrame = "avatar_frame"
|
||||
roomAppearanceResourceProfileCard = "profile_card"
|
||||
roomAppearanceResourceVehicle = "vehicle"
|
||||
roomAppearanceResourceBadge = "badge"
|
||||
roomAppearanceResourceMicSeatAnimation = "mic_seat_animation"
|
||||
)
|
||||
|
||||
type flexibleInt64 int64
|
||||
@ -1649,6 +1656,7 @@ func (h *Handler) roomDisplayProfileMap(request *http.Request, userIDs []int64)
|
||||
AvatarFrame: appearance.AvatarFrame,
|
||||
ProfileCard: appearance.ProfileCard,
|
||||
Vehicle: appearance.Vehicle,
|
||||
MicSeatAnimation: appearance.MicSeatAnimation,
|
||||
Charm: 0,
|
||||
}
|
||||
// 显式补空对象/空数组,避免客户端在房间资料中同时处理 null 和空值。
|
||||
@ -1677,6 +1685,11 @@ func (h *Handler) roomDisplayProfileMap(request *http.Request, userIDs []int64)
|
||||
profile.Vehicle = map[string]any{}
|
||||
profiles[userID] = profile
|
||||
}
|
||||
if profiles[userID].MicSeatAnimation == nil {
|
||||
profile := profiles[userID]
|
||||
profile.MicSeatAnimation = map[string]any{}
|
||||
profiles[userID] = profile
|
||||
}
|
||||
if profiles[userID].ProfileCard == nil {
|
||||
profile := profiles[userID]
|
||||
profile.ProfileCard = map[string]any{}
|
||||
@ -1687,10 +1700,11 @@ func (h *Handler) roomDisplayProfileMap(request *http.Request, userIDs []int64)
|
||||
}
|
||||
|
||||
type roomAppearanceResources struct {
|
||||
AvatarFrame map[string]any
|
||||
ProfileCard map[string]any
|
||||
Vehicle map[string]any
|
||||
Badges []map[string]any
|
||||
AvatarFrame map[string]any
|
||||
ProfileCard map[string]any
|
||||
Vehicle map[string]any
|
||||
MicSeatAnimation map[string]any
|
||||
Badges []map[string]any
|
||||
}
|
||||
|
||||
func (h *Handler) roomAppearanceResourceMap(request *http.Request, userIDs []int64) map[int64]roomAppearanceResources {
|
||||
@ -1703,7 +1717,7 @@ func (h *Handler) roomAppearanceResourceMap(request *http.Request, userIDs []int
|
||||
RequestId: httpkit.RequestIDFromContext(request.Context()),
|
||||
AppCode: appcode.FromContext(request.Context()),
|
||||
UserIds: userIDs,
|
||||
ResourceTypes: []string{"avatar_frame", "profile_card", "vehicle", "badge"},
|
||||
ResourceTypes: []string{roomAppearanceResourceAvatarFrame, roomAppearanceResourceProfileCard, roomAppearanceResourceVehicle, roomAppearanceResourceBadge, roomAppearanceResourceMicSeatAnimation},
|
||||
})
|
||||
if err != nil {
|
||||
// 装扮是展示增强,失败不影响房间主数据返回。
|
||||
@ -1718,14 +1732,16 @@ func (h *Handler) roomAppearanceResourceMap(request *http.Request, userIDs []int
|
||||
// 同一资源类型只保留当前佩戴的一个权益;wallet equipment 主键保证唯一性。
|
||||
resource := roomAppearanceResourceFromEntitlement(item)
|
||||
switch item.GetResource().GetResourceType() {
|
||||
case "avatar_frame":
|
||||
case roomAppearanceResourceAvatarFrame:
|
||||
current.AvatarFrame = resource
|
||||
case "profile_card":
|
||||
case roomAppearanceResourceProfileCard:
|
||||
current.ProfileCard = resource
|
||||
case "vehicle":
|
||||
case roomAppearanceResourceVehicle:
|
||||
current.Vehicle = resource
|
||||
case "badge":
|
||||
case roomAppearanceResourceBadge:
|
||||
current.Badges = append(current.Badges, roomBadgeItemFromEquippedResource(resource))
|
||||
case roomAppearanceResourceMicSeatAnimation:
|
||||
current.MicSeatAnimation = resource
|
||||
}
|
||||
}
|
||||
result[user.GetUserId()] = current
|
||||
|
||||
@ -172,6 +172,7 @@ type roomDisplayProfileData struct {
|
||||
AvatarFrame map[string]any `json:"avatar_frame"`
|
||||
ProfileCard map[string]any `json:"profile_card"`
|
||||
Vehicle map[string]any `json:"vehicle"`
|
||||
MicSeatAnimation map[string]any `json:"mic_seat_animation"`
|
||||
Charm int64 `json:"charm"`
|
||||
}
|
||||
|
||||
|
||||
@ -17,26 +17,28 @@ import (
|
||||
|
||||
const (
|
||||
// /appearance 只暴露客户端能直接佩戴或展示的装扮维度;类型值保持和 wallet resource_type 一致。
|
||||
appearanceResourceAvatarFrame = "avatar_frame"
|
||||
appearanceResourceProfileCard = "profile_card"
|
||||
appearanceResourceVehicle = "vehicle"
|
||||
appearanceResourceBadge = "badge"
|
||||
appearanceResourceAvatarFrame = "avatar_frame"
|
||||
appearanceResourceProfileCard = "profile_card"
|
||||
appearanceResourceVehicle = "vehicle"
|
||||
appearanceResourceBadge = "badge"
|
||||
appearanceResourceMicSeatAnimation = "mic_seat_animation"
|
||||
)
|
||||
|
||||
var errAppearanceUpstream = errors.New("upstream service error")
|
||||
|
||||
type appearanceData struct {
|
||||
UserID string `json:"user_id"`
|
||||
AvatarFrame map[string]any `json:"avatar_frame"`
|
||||
ProfileCard map[string]any `json:"profile_card"`
|
||||
Vehicle map[string]any `json:"vehicle"`
|
||||
Level map[string]any `json:"level"`
|
||||
LevelBadges map[string]any `json:"level_badges"`
|
||||
EquippedBadges []map[string]any `json:"equipped_badges"`
|
||||
Badges []map[string]any `json:"badges"`
|
||||
BadgeProfile appearanceBadgeData `json:"badge_profile"`
|
||||
Resources []map[string]any `json:"resources"`
|
||||
ServerTimeMS int64 `json:"server_time_ms"`
|
||||
UserID string `json:"user_id"`
|
||||
AvatarFrame map[string]any `json:"avatar_frame"`
|
||||
ProfileCard map[string]any `json:"profile_card"`
|
||||
Vehicle map[string]any `json:"vehicle"`
|
||||
MicSeatAnimation map[string]any `json:"mic_seat_animation"`
|
||||
Level map[string]any `json:"level"`
|
||||
LevelBadges map[string]any `json:"level_badges"`
|
||||
EquippedBadges []map[string]any `json:"equipped_badges"`
|
||||
Badges []map[string]any `json:"badges"`
|
||||
BadgeProfile appearanceBadgeData `json:"badge_profile"`
|
||||
Resources []map[string]any `json:"resources"`
|
||||
ServerTimeMS int64 `json:"server_time_ms"`
|
||||
}
|
||||
|
||||
type appearanceBadgeData struct {
|
||||
@ -80,15 +82,16 @@ func (h *Handler) writeAppearance(writer http.ResponseWriter, request *http.Requ
|
||||
func (h *Handler) appearanceForUser(request *http.Request, userID int64) (appearanceData, error) {
|
||||
// 先初始化为空对象/数组,保证客户端不需要处理 null 和字段缺失两套形态。
|
||||
data := appearanceData{
|
||||
UserID: strconv.FormatInt(userID, 10),
|
||||
AvatarFrame: map[string]any{},
|
||||
ProfileCard: map[string]any{},
|
||||
Vehicle: map[string]any{},
|
||||
Level: defaultAppearanceLevelDisplay(),
|
||||
LevelBadges: map[string]any{},
|
||||
EquippedBadges: []map[string]any{},
|
||||
Badges: []map[string]any{},
|
||||
Resources: []map[string]any{},
|
||||
UserID: strconv.FormatInt(userID, 10),
|
||||
AvatarFrame: map[string]any{},
|
||||
ProfileCard: map[string]any{},
|
||||
Vehicle: map[string]any{},
|
||||
MicSeatAnimation: map[string]any{},
|
||||
Level: defaultAppearanceLevelDisplay(),
|
||||
LevelBadges: map[string]any{},
|
||||
EquippedBadges: []map[string]any{},
|
||||
Badges: []map[string]any{},
|
||||
Resources: []map[string]any{},
|
||||
}
|
||||
// 当前佩戴只走 BatchGetUserEquippedResources:
|
||||
// 1. wallet 内部会过滤过期佩戴;
|
||||
@ -97,7 +100,7 @@ func (h *Handler) appearanceForUser(request *http.Request, userID int64) (appear
|
||||
RequestId: httpkit.RequestIDFromContext(request.Context()),
|
||||
AppCode: appcode.FromContext(request.Context()),
|
||||
UserIds: []int64{userID},
|
||||
ResourceTypes: []string{appearanceResourceAvatarFrame, appearanceResourceProfileCard, appearanceResourceVehicle, appearanceResourceBadge},
|
||||
ResourceTypes: []string{appearanceResourceAvatarFrame, appearanceResourceProfileCard, appearanceResourceVehicle, appearanceResourceBadge, appearanceResourceMicSeatAnimation},
|
||||
})
|
||||
if err != nil {
|
||||
return data, err
|
||||
@ -120,6 +123,8 @@ func (h *Handler) appearanceForUser(request *http.Request, userID int64) (appear
|
||||
data.Vehicle = resource
|
||||
case appearanceResourceBadge:
|
||||
data.EquippedBadges = append(data.EquippedBadges, resource)
|
||||
case appearanceResourceMicSeatAnimation:
|
||||
data.MicSeatAnimation = resource
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user