← Tất cả docs

Avatar Creator

Avatar Creator có hai surface độc lập: CMS quản lý catalog trực tiếp qua REST; game client đọc catalog snapshot và mua/chọn avatar qua RPC AES.

1. Tổng quan flow

  1. CMS tạo/sửa/xóa avatar element.
  2. User mở màn avatar: game gọi list một lần trong phiên để đồng bộ catalog và trạng thái unlock.
  3. User bấm mua một element: gọi buy với một element_id.
  4. Sau khi mua thành công, user mới được chọn element đó trong request set avatar.

Catalog game là snapshot in-memory refresh tối đa mỗi 2 giây. CMS list luôn đọc Mongo trực tiếp.

2. CMS REST

Base: /api/v1/avatar-elements. Header bắt buộc: Authorization: Bearer <cms_jwt>.

MethodPathRoleMô tả
GET/api/v1/avatar-elementsAvatar Element ReadDanh sách đầy đủ, gồm inactive và chưa đến thời gian mở bán.
POST/api/v1/avatar-elementsAvatar Element WriteTạo element.
PUT/api/v1/avatar-elements/:idAvatar Element WriteCập nhật element.
DELETE/api/v1/avatar-elements/:idAvatar Element WriteXóa element.

Payload create / update

{
  "id": "hair_neon_01",
  "type": "hair",
  "gender": "male",
  "url": "https://cdn.example.com/avatar/hair_neon_01.png",
  "filter": { "vip_min": 0, "start_time": 0, "end_time": 0 },
  "price": 50000,
  "active": true
}

id là khóa catalog. type chỉ nhận: background, body, clothes, hair, hat_back, hat_front, eye, beard, glasses, earring. Giá không âm; price=0 là free.

Response CMS theo chuẩn gateway: {"code":0,"msg":...}. Sau thay đổi, game node nhận catalog mới trong tối đa 2 giây.

3. Game RPC

Gateway: POST /api/v2/rpc, Game JWT và envelope AES-CBC chuẩn. Ví dụ bên dưới là JSON sau khi decrypt.

POST /api/v2/rpc
Authorization: Bearer <game_jwt>

decrypt → { "method": "/user/avatar/elements", "data": {} }
success → HTTP 200 encrypted { "code": 0, "msg": ... }
error   → HTTP 500 encrypted { "code": ..., "msg": ... }

3.1 Đồng bộ catalog — /user/avatar/elements

Gọi một lần khi user vào màn avatar trong mỗi session. Không gửi user_id; gateway lấy từ JWT. Server chỉ trả element active, đủ VIP và đang trong thời gian mở bán.

{ "method": "/user/avatar/elements", "data": {} }

{
  "elements": [{
    "id": "hair_neon_01",
    "type": "hair",
    "gender": "male",
    "url": "https://cdn.example.com/avatar/hair_neon_01.png",
    "filter": { "vip_min": 0, "start_time": 0, "end_time": 0 },
    "price": 50000,
    "active": true
  }]
}

Nếu user đã unlock một element thì server trả price: 0. Client dùng điều này để đánh dấu đã sở hữu, không tự suy diễn ownership từ giá catalog.

3.2 Mua một element — /user/avatar/buy

{ "method": "/user/avatar/buy", "data": { "element_id": "hair_neon_01" } }

Chỉ mua một element mỗi request. Server xác minh element đang khả dụng theo active/VIP/time; nếu chưa sở hữu, trừ chip đúng một lần rồi unlock. Mua lại element đã sở hữu trả thành công và không trừ chip.

3.3 Chọn avatar — /user/avatar/create

{
  "method": "/user/avatar/create",
  "data": { "element_ids": ["bg_01", "body_01", "hair_neon_01", "glasses_01"] }
}

Request set không mua và không trừ chip. Tất cả ID phải đã unlock; mỗi type chỉ được xuất hiện một lần. Response là object avatars đang được lưu cho user.

4. Lỗi và client handling

Tình huốngHành vi client
ID không tồn tại, inactive, chưa tới thời điểm bán, hoặc không đủ VIPHiển thị lỗi; refresh catalog nếu UI có thể đã cũ.
Không đủ chip khi buyHiển thị luồng nạp chip; không đánh dấu unlocked.
Set ID chưa unlock / trùng typeKhông cập nhật UI đã chọn; gọi lại list nếu ownership có thể vừa đổi.

Không gọi CMS API từ game client. Không cho client gửi user ID trong mọi game method.