# VersionManifestService `versionmanifestservice.h`, `versionmanifestservice.cpp` Каталог версий Mojang. Скачивает `version_manifest_v2.json`, хранит его копию в папке лаунчера и отвечает из неё, пока копия свежая. Экземпляр держит [LauncherBackend](LauncherBackend.md): из каталога он строит список для окна выбора версии. [VersionInstaller](VersionInstaller.md) берёт из каталога ссылку на описание версии через `find()`. ## RemoteVersionEntry | Поле | Что это | |------|---------| | `id` | `1.21.8`, `25w33a`, `b1.7.3` | | `type` | `release`, `snapshot`, `old_beta`, `old_alpha` | | `url` | адрес `.json` | | `sha1` | хеш этого json | | `releaseTime` | | Записи без `id` или с адресом не по `https` отбрасываются. Список отсортирован по `releaseTime`, новые сверху. При одинаковом времени сортировка идёт по `id`. ## ensureLoaded(callback, forceRefresh = false) Через этот метод сервис получает данные; других способов нет. 1. При первом вызове читается кэш `/cache/version_manifest.json`. Если он разобрался, сразу испускается `versionsChanged`, и окно показывает список ещё до ответа сети. 2. Если данные моложе 6 часов и `forceRefresh` не задан, колбэк вызывается через `QTimer::singleShot(0)` с `ok = true`. Сеть не трогается. 3. Иначе колбэк встаёт в очередь. Если запрос уже идёт, второй не отправляется. Ответ сети разбирается, кэш перезаписывается через `QSaveFile`, испускается `versionsChanged`, и все колбэки из очереди получают результат. Если сеть не ответила, но старые данные есть, колбэк получит `ok = true` и непустой `warning`: работать можно, просто список, возможно, неполный. Если данных нет совсем, придёт `ok = false`. Бэкенд показывает `warning` пользователю только во втором случае. Таймаут запроса 20 секунд. ## Остальное - `versions()` — весь список. - `find(id)` — запись по id (через хеш-таблицу, а не перебором). - `hasData()`, `isRefreshing()`, `fetchedAt()`. - `refreshingChanged` испускается в начале и в конце запроса. Бэкенд превращает его в `catalogLoading`. ## Формат кэша ```json { "fetchedAt": "2026-10-11T08:00:00Z", "versions": [ { "id": "1.21.8", "type": "release", "url": "https://...", "sha1": "...", "releaseTime": "..." } ] } ``` Хранится только то, что нужно лаунчеру, а не весь манифест Mojang. --- При создании этого документа использовался ИИ.