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
- CMS tạo/sửa/xóa avatar element.
- 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.
- User bấm mua một element: gọi buy với một
element_id. - 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>.
| Method | Path | Role | Mô tả |
|---|---|---|---|
| GET | /api/v1/avatar-elements | Avatar Element Read | Danh sách đầy đủ, gồm inactive và chưa đến thời gian mở bán. |
| POST | /api/v1/avatar-elements | Avatar Element Write | Tạo element. |
| PUT | /api/v1/avatar-elements/:id | Avatar Element Write | Cập nhật element. |
| DELETE | /api/v1/avatar-elements/:id | Avatar Element Write | Xó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ống | Hà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 đủ VIP | Hiển thị lỗi; refresh catalog nếu UI có thể đã cũ. |
| Không đủ chip khi buy | Hiển thị luồng nạp chip; không đánh dấu unlocked. |
| Set ID chưa unlock / trùng type | Khô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.