fix #23 by adding validating on first startup and close #30 by adding
tests / package-smoke-linux (push) Skipped
tests / package-smoke-windows (push) Skipped
tests / package-smoke-macos (push) Skipped
tests / macos (push) Successful in 1m20s
tests / linux (push) Successful in 2m14s
tests / windows (push) Failing after 23m21s
tests / package-smoke-linux (push) Skipped
tests / package-smoke-windows (push) Skipped
tests / package-smoke-macos (push) Skipped
tests / macos (push) Successful in 1m20s
tests / linux (push) Successful in 2m14s
tests / windows (push) Failing after 23m21s
version number Signed-off-by: galeon <dertiellis@gmail.com>
This commit is contained in:
1 parent
bc205fa2e7
commit
1d781b5324
19 files changed
+805
-10
No files matched your search
@@ -46,16 +46,34 @@
|
||||
3. `migrateLegacyBuildsFile()` переносит старый `versions.json` в `customBuilds.json`. Это должно
|
||||
случиться до следующего шага, иначе поверх старых данных появится пустой файл.
|
||||
4. `loadData()` читает профили и сборки и сортирует их по `id`.
|
||||
5. `ensureDataFiles()` создаёт недостающие файлы.
|
||||
6. Если `BuildSwitcher` нашёл журнал оборванного переключения, бэкенд сразу продолжает его через
|
||||
5. Если это первый запуск, `importGameDir()` заводит сборку под то, что уже лежит в папке игры
|
||||
(см. ниже).
|
||||
6. `ensureDataFiles()` создаёт недостающие файлы.
|
||||
7. Если `BuildSwitcher` нашёл журнал оборванного переключения, бэкенд сразу продолжает его через
|
||||
`resumeInterrupted()`. Пользователю ничего не предлагается. Если начать переключение заново,
|
||||
оно сначала заархивирует полуразобранную `.minecraft` поверх целого архива прежней сборки.
|
||||
7. Подписка на сигналы сервисов.
|
||||
8. Подписка на сигналы сервисов.
|
||||
|
||||
Все проблемы, найденные по пути (битый JSON, папка без права записи, пропущенные записи сборок),
|
||||
копятся в `m_storageIssues` и уходят одним `launchError` через `QTimer::singleShot(0)`: к этому
|
||||
моменту QML уже подписан на сигнал.
|
||||
|
||||
### Сборка из папки игры
|
||||
|
||||
Первым запуском считается старт, когда нет ни `settings.json`, ни `customBuilds.json`, ни
|
||||
старого `versions.json`. Проверка делается до `loadData()`: битый файл она отводит в `.bak`, а
|
||||
`ensureDataFiles()` потом создаёт пустой. Существующий пустой `customBuilds.json` — это решение
|
||||
пользователя «сборок нет», и импорта тогда нет.
|
||||
|
||||
Если [GameDirImport::detect()](gamedirimport.md) что-то нашёл, запись сборки добавляется сразу,
|
||||
минуя `addCustomBuild()` (тот начал бы установку), становится активной и сохраняется вместе с
|
||||
`activeBuildId`. `BuildSwitcher` не вызывается: сборка описывает то, что уже разложено в папке
|
||||
игры, а активная сборка без архива — штатное состояние. Сама папка игры только читается.
|
||||
|
||||
Имя: `<loaderTitle> <версия>` или `Minecraft <версия>`, а без версии — `build.title.fromGameDir`.
|
||||
Через `QTimer::singleShot(0)` приходит `gameDirImported(buildName)`, раньше сообщения об ошибках
|
||||
хранилища, чтобы оно их не перекрыло. Main.qml показывает по нему зелёную плашку.
|
||||
|
||||
## Файлы на диске
|
||||
|
||||
Все пути берутся из [launcherpaths.h](launcherpaths.md).
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
# gamedirimport.h
|
||||
|
||||
`gamedirimport.h`, `gamedirimport.cpp`
|
||||
|
||||
Пространство имён `GameDirImport`: что уже лежит в папке игры, когда лаунчер запускают впервые.
|
||||
Состояния нет, сеть не нужна, файлы только читаются. Вызывает его
|
||||
[LauncherBackend](LauncherBackend.md) при первом запуске, решение описано в
|
||||
[ADR-0001](../adr/0001-import-existing-minecraft.md).
|
||||
|
||||
## detect(gameDir)
|
||||
|
||||
Возвращает `std::optional<Detected>`: `minecraftVersion`, `resolvedVersionId`, `loader`,
|
||||
`loaderVersion` и `source` — откуда взята версия (`launcher_profiles`, `versions` или `content`).
|
||||
|
||||
`nullopt` — импортировать нечего: в `versions/` нет ни одной установленной версии и нет признаков
|
||||
того, что в папке играли. Признаки — непустые `mods`, `saves`, `resourcepacks`, `shaderpacks`,
|
||||
`config` или файлы `options.txt`, `servers.dat`. Служебные файлы других лаунчеров
|
||||
(`launcher_log.txt`, `webcache2`) не считаются: иначе пустая папка официального лаунчера давала
|
||||
бы сборку без версии.
|
||||
|
||||
Версия выбирается так:
|
||||
|
||||
1. профили из `launcher_profiles.json`, у которых `lastVersionId` установлен, по убыванию
|
||||
`lastUsed` (профиль без даты считается самым старым). `latest-release` и `latest-snapshot` без
|
||||
`lastVersionId` пропускаются: без манифеста не узнать, во что они разворачивались;
|
||||
2. установленные версии по убыванию времени правки `<id>/<id>.json`.
|
||||
|
||||
Версия с нечитаемым описанием пропускается. Если в `mods/` есть хотя бы один `.jar`, сначала
|
||||
ищется профиль с `inheritsFrom` (сперва в первом списке, потом во втором), и только потом берётся
|
||||
что есть. Не нашлось ничего — `source` равен `content`, поля версии пустые.
|
||||
|
||||
У профиля с `inheritsFrom` версия игры — это `inheritsFrom`, а `resolvedVersionId` — его `id`,
|
||||
поэтому запустится ровно найденный профиль, даже если модлоадер не опознан (OptiFine, LabyMod).
|
||||
У профиля без `inheritsFrom` версия — сам `id`.
|
||||
|
||||
## loaderOf(versionJson)
|
||||
|
||||
Модлоадер по `libraries[].name` описания профиля:
|
||||
|
||||
| Библиотека | `key` | `version` |
|
||||
|------------|-------|-----------|
|
||||
| `net.fabricmc:fabric-loader:<v>` | `fabric` | `<v>` |
|
||||
| `org.quiltmc:quilt-loader:<v>` | `quilt` | `<v>` |
|
||||
| `net.neoforged:neoforge:<v>` | `neoforge` | `<v>` |
|
||||
| `net.neoforged:forge:<mc>-<v>` | `neoforge` | `<v>` (NeoForge для 1.20.1) |
|
||||
| `net.minecraftforge:forge:<mc>-<v>` | `forge` | `<v>` |
|
||||
|
||||
Префикс `<mc>-` срезается, хвост `-1.7.10` у старых Forge остаётся: в каталоге
|
||||
[ModLoaderVersionService](ModLoaderVersionService.md) версии записаны так же, и карточка сборки
|
||||
найдёт выбранную строку.
|
||||
|
||||
Если таких библиотек нет, смотрит на `id`, который дают установщики: `fabric-loader-<v>-<mc>`,
|
||||
`quilt-loader-<v>-<mc>`, `neoforge-<v>`, `<mc>-forge-<v>`. Не опознано — пустой `key`.
|
||||
|
||||
---
|
||||
|
||||
При создании этого документа использовался ИИ.
|
||||
+2
-1
@@ -10,7 +10,8 @@
|
||||
приложения общий контекст OpenGL уже не выставить.
|
||||
2. **`QGuiApplication`**, а не `QApplication`: виджетов в проекте нет.
|
||||
3. **Имя и версия.** `applicationName` = `BiLauncher`, `applicationVersion` = `LAUNCHER_VERSION`
|
||||
(берётся из `project(... VERSION)` в CMake), организация `GaleonDev`, домен `galeonworx.com`. На
|
||||
(в CMake это `PROJECT_VERSION` плюс `LAUNCHER_VERSION_SUFFIX`, например `1.0.1-dev`; QML читает её
|
||||
через `Qt.application.version`), организация `GaleonDev`, домен `galeonworx.com`. На
|
||||
пути к данным лаунчера это не влияет, см. [launcherpaths.h](launcherpaths.md).
|
||||
4. **Иконка окна.** На Windows и Linux в `QIcon` складываются все PNG из ресурса `:/icons/`
|
||||
(16–512 и `@2x`). На macOS этот шаг пропущен: там иконку берут из `icon.icns` внутри бандла.
|
||||
|
||||
Reference in new issue
Block a user