Files
BiLauncher/doc/cpp/AuthService.md
T
2026-10-11 22:32:13 +03:00

5.6 KiB
Raw Permalink Blame History

AuthService

authservice.h, authservice.cpp

Вход через Ely.by, офлайн-профиль и загрузка authlib-injector. Вход через Microsoft живёт отдельно, в MsaAuthService, но отдаёт результат в той же структуре AuthResult. Поэтому запуск игры дальше идёт одинаково, как бы игрок ни вошёл.

Экземпляр создаёт и держит LauncherBackend. Сервис ничего не пишет на диск, кроме скачанного jar: токены между запусками сохраняет бэкенд в profiles.json.

AuthResult

Каждое поле соответствует подстановке в аргументах запуска.

Поле Подстановка / смысл
ok вход удался
twoFactorRequired Ely.by требует одноразовый код
licenseMissing Microsoft: вход прошёл, но игры на аккаунте нет. Отдельный флаг, потому что повторный вход тут не поможет
error текст ошибки, если ok == false
playerName ${auth_player_name}
uuid ${auth_uuid}, hex без дефисов
accessToken ${auth_access_token}
clientToken ${clientid}
userType ${user_type}: legacy (офлайн), ELYBY, msa
refreshToken только Microsoft: продление сессии без пароля
xuid только Microsoft: ${auth_xuid}
expiresAt только Microsoft: когда истекает accessToken, UTC

Офлайн

static AuthResult offline(nickname) работает без сети. UUID считается так же, как в самом Minecraft: MD5 от OfflinePlayer:<ник>, после чего выставляются биты версии 3 и варианта RFC 4122. Значит, у одного ника всегда один UUID, и на офлайн-сервере игрок не теряет инвентарь. В accessToken и clientToken записывается "0".

Пустой ник — ошибка.

Ely.by

Сервер — https://authserver.ely.by, протокол Yggdrasil, JSON по HTTPS.

loginElyBy(login, password, clientToken, accessToken, callback) старается не спрашивать пароль:

  1. Если сохранённого accessToken нет, сразу /auth/authenticate с паролем.
  2. Если есть, /auth/validate. Ответ 200 — токен рабочий, вход закончен.
  3. Иначе /auth/refresh. Если продлить удалось, приходят новый токен, ник и UUID.
  4. Если и это не вышло, /auth/authenticate с паролем.

Если сервер недоступен (статус 0 и сетевая ошибка), цепочка обрывается с ошибкой, без попытки войти по паролю.

Второй фактор Ely.by не сообщает отдельным кодом. Сервис ищет в тексте ошибки подстроку two factor и выставляет twoFactorRequired. Тогда бэкенд спрашивает код у игрока и вызывает loginElyByWithTotp(login, password, totp, clientToken, callback), который отправляет пароль в виде пароль:код, как требует Ely.by.

clientToken генерируется один раз на профиль (generateClientToken(), случайный UUID) и хранится вместе с ним: Yggdrasil привязывает выданный accessToken к этому значению.

По ходу работы испускается progress(message). Бэкенд пересылает его в launchProgress.

authlib-injector

Без него игра пойдёт проверять сессию на серверы Mojang, и токен Ely.by окажется недействительным. Jar подключается к JVM через -javaagent (см. GameLauncher).

ensureAuthlibInjector(targetDir, callback):

  • если <targetDir>/authlib-injector.jar уже есть, сразу отдаёт путь. Версия не проверяется, и обновить файл можно, только удалив его;
  • иначе читает https://authlib-injector.yushi.moe/artifact/latest.json, скачивает jar по download_url и, если в манифесте есть checksums.sha256, сверяет хеш.

Колбэк получает либо путь, либо текст ошибки. targetDir — это <root>/runtime.

Как вызываются колбэки

Все сетевые методы асинхронные, колбэк вызывается один раз в GUI-потоке. Если сервис удалить во время запроса, менеджер сети уйдёт вместе с ним, и колбэк не вызовется вообще. Бэкенд к тому же проверяет в каждом колбэке, не отменили ли запуск, пока шёл запрос.

Повторных попыток при сетевых ошибках нет.


При создании этого документа использовался ИИ.