Основные понятия
Проекты, ключи, сессии игроков и то, как SDK сообщают о результатах и ошибках.
Комментарии в коде и имена API оставлены на английском, чтобы совпадать с SDK.
Проекты и ключи#
Каждая игра — это проект. Его ключи идентифицируют проект, а не игрока.
| Учётные данные | Где используется |
|---|---|
| Base URL | Адрес этой установки. API находится по пути /v1. |
| Project ID | В каждом запросе, как X-Project-ID. Публичный. |
Клиентский ключ pk_live_… | В сборках игр и на веб-страницах, как X-Client-Key. Публичный: действует только от имени вошедших игроков. |
Секретный ключ sk_live_… | Только на ваших собственных серверах, как X-Secret-Key. Показывается один раз и хранится в виде хеша; открывает доступ к серверным эндпоинтам. |
sk_live_…) в сборку игры или на веб-страницу. Всё, что попадает к игрокам, можно прочитать.Игроки и сессии#
Для вызовов от имени игрока нужен токен доступа. При входе он выдаётся (действует один час) вместе с токеном обновления (действует 30 дней).
- SDK хранят сессию на устройстве и обновляют её до истечения срока, поэтому игрокам не нужно входить заново после перезапуска.
- Токен обновления меняется при каждом использовании. Повторное использование старого токена завершает эту сессию на всех устройствах (защита от кражи).
- Каждый игрок начинает как гость и позже может привязать email или аккаунт Google; прогресс гостя переносится. См. Игроки.
Результаты вместо исключений#
Вызовы SDK никогда не выбрасывают исключений при ошибках сети или сервера. Они возвращают результат с ok, значением и ошибкой, у которой есть постоянный код, сообщение и ID запроса.
var top = await Majacloud.Leaderboards.GetTopAsync("coins", 10);
if (top.Ok)
{
foreach (var entry in top.Value.Entries)
Debug.Log($"#{entry.Rank} {entry.PlayerName} {entry.Score}");
}
else if (top.Error.IsRetryable)
{
// Network, timeout, 5xx or rate limit: try again later
Debug.Log("Retry in " + top.Error.RetryAfterSeconds + " s");
}
else
{
Debug.LogWarning(top.Error.Code + ": " + top.Error.Message + " (" + top.Error.RequestId + ")");
}var top := await Majacloud.leaderboards.get_top("coins", 10)
if top.ok:
for entry in top.value.entries:
print("#%d %s %d" % [entry.rank, entry.player_name, entry.score])
elif top.is_retryable():
# Network, timeout, 5xx or rate limit: try again later
print("Retry in ", top.retry_after, " s")
else:
push_warning("%s: %s (%s)" % [top.error, top.message, top.request_id])const top = await mc.leaderboards.getTop('coins', { limit: 10 });
if (top.ok) {
for (const entry of top.value.entries) {
console.log(`#${entry.rank} ${entry.player_name} ${entry.score}`);
}
} else if (top.error.retryable) {
// Network, timeout, 5xx or rate limit: try again later
console.log('Retry in', top.error.retryAfter, 's');
} else {
console.warn(`${top.error.code}: ${top.error.message} (${top.error.requestId})`);
}// Success
{ "ok": true, "entries": [ … ], "total": 42 }
// Error (HTTP 4xx/5xx)
{
"ok": false,
"error": {
"code": "rate_limited",
"message": "Project rate limit reached. Try again in a minute.",
"request_id": "6f1c2a9e-…",
"details": { "limit": 120, "window": "minute" }
}
}Повторы и ограничения частоты#
SDK повторяют безопасные запросы при сетевых ошибках и ответах 5xx с экспоненциальной задержкой, а при ответе 429 выжидают время из Retry-After.
- Каждый проект может отправлять до 120 запросов в минуту; сверх этого API отвечает
rate_limited. - У каждого аккаунта есть дневная квота запросов, которая зависит от тарифа (см. Лимиты); сверх неё API отвечает
quota_exceededдо 00:00 UTC. - Ответы содержат
X-RateLimit-Limit,X-RateLimit-Remaining, а при приближении к квоте —X-RateLimit-Daily-Remaining.
ID запросов и логи#
В каждом ответе есть заголовок X-Request-ID, а каждая ошибка содержит request_id. Найдите его на странице Логи вашего проекта, чтобы увидеть эндпоинт, статус, задержку и игрока.