1 parent
1943996608
commit
f10b654953
34 files changed
+2099
-4576
No files matched your search
+40
-57
@@ -1,76 +1,59 @@
|
||||
# javalocator.h — JavaLocator
|
||||
# JavaLocator
|
||||
|
||||
## Обзор
|
||||
`javalocator.h`, `javalocator.cpp`
|
||||
|
||||
Для запуска Minecraft нужна Java подходящей версии: старым версиям игры — восьмая, новым —
|
||||
семнадцатая или двадцать первая. Лаунчер умеет скачивать сборки Java сам (см.
|
||||
[JavaInstaller](JavaInstaller.md)), но сначала стоит посмотреть, что уже есть на машине.
|
||||
Поиск java, уже установленной на машине, и выбор подходящей под версию игры. Скачиванием
|
||||
занимается [JavaInstaller](JavaInstaller.md), а здесь только смотрим, что есть.
|
||||
|
||||
`JavaLocator` отвечает за поиск: собирает все доступные java, определяет их версии и выбирает
|
||||
подходящую под требование версии игры. Пространство имён используется при подготовке запуска и при
|
||||
показе списка найденных Java в настройках.
|
||||
Это пространство имён со свободными функциями. Его используют [GameLauncher](GameLauncher.md) при
|
||||
запуске, [LauncherBackend](LauncherBackend.md) для списка в настройках и для шага Java в установке
|
||||
сезонной сборки.
|
||||
|
||||
## Пространства имён
|
||||
## findAll(gameDir)
|
||||
|
||||
`JavaLocator` группирует четыре функции поиска и выбора. Состояния нет, но результат определения
|
||||
версии кэшируется внутри реализации.
|
||||
Список путей к исполняемому `java` (`java.exe` на Windows) без повторов. Порядок такой:
|
||||
|
||||
## Функции
|
||||
1. сборки, скачанные лаунчером в `<root>/java` (через `JavaRuntimeStore::installed()`);
|
||||
2. всё, что найдётся рекурсивно в `<gameDir>/runtime`: туда кладёт Java официальный лаунчер;
|
||||
3. `$JAVA_HOME/bin`;
|
||||
4. `java` из `PATH`;
|
||||
5. стандартные каталоги установки. На Windows это `Program Files`, `Program Files (x86)` и
|
||||
`ProgramW6432` с подпапками `Java`, `Eclipse Adoptium`, `Eclipse Foundation`, `AdoptOpenJDK`,
|
||||
`Amazon Corretto`, `Zulu`, `BellSoft`, `Microsoft`, `Semeru` и JBR из Android Studio. На macOS
|
||||
это `/Library/Java/JavaVirtualMachines` и такая же папка в домашнем каталоге. На Linux —
|
||||
`/usr/lib/jvm`, `/usr/java`, `/opt/java`, `/opt/jdk`.
|
||||
|
||||
#### QStringList findAll(const QString &gameDir)
|
||||
В каждом каталоге установки проверяются `bin`, `Contents/Home/bin` (так устроены JDK на macOS) и
|
||||
`jre/bin`.
|
||||
|
||||
Все java, которые удалось найти, без дублей и в порядке приоритета. Просматриваются четыре
|
||||
источника: рантайм самого Minecraft внутри папки игры, переменная `JAVA_HOME`, переменная `PATH` и
|
||||
стандартные каталоги установки JDK и JRE.
|
||||
## majorVersion(javaPath)
|
||||
|
||||
Параметр `gameDir` — папка игры; из неё берётся первый источник.
|
||||
Запускает `java -version` и достаёт мажорную версию из строки `version "..."`. Старая схема
|
||||
`1.8.0_x` даёт 8. Если процесс не ответил за 5 секунд или вывод не разобрался, возвращается 0.
|
||||
|
||||
Результат показывается в диалоге настроек списком «что нашлось в системе».
|
||||
Результат кэшируется в статической таблице на всё время работы лаунчера. Если java по тому же пути
|
||||
обновить, лаунчер узнает об этом только после перезапуска. Кэш не защищён от гонок, поэтому
|
||||
функцию можно вызывать только из одного потока, и в проекте это GUI-поток.
|
||||
|
||||
#### int majorVersion(const QString &javaPath)
|
||||
## select(gameDir, requiredMajor, preferred, &error)
|
||||
|
||||
Мажорная версия java по её пути: 8, 17, 21 и так далее. Возвращает `0`, если запустить
|
||||
исполняемый файл не удалось — путь неверен, файл не исполняемый или это не java.
|
||||
Выбирает java для запуска.
|
||||
|
||||
Результат кэшируется: определение версии требует запуска процесса, а один и тот же путь
|
||||
проверяется многократно.
|
||||
- Если `preferred` задан, он идёт первым кандидатом. Это может быть путь к файлу или к домашней
|
||||
папке JDK (тогда берётся `bin/java`). Если по этому пути ничего нет, функция сразу возвращает
|
||||
ошибку и других кандидатов не смотрит: пользователь явно указал путь, и молча подменять его
|
||||
было бы неправильно.
|
||||
- Дальше добавляется всё из `findAll()`.
|
||||
- Возвращается первый кандидат с версией не ниже `requiredMajor`. Если таких нет, в `error`
|
||||
пишется, какая самая новая java нашлась и где.
|
||||
|
||||
#### QString windowlessVariant(const QString &javaPath)
|
||||
Функция возвращает первую подходящую, а не самую новую. Поэтому скачанная лаунчером Java 17
|
||||
выиграет у системной Java 21, если игре нужна 17.
|
||||
|
||||
Заменяет `java.exe` на `javaw.exe`, чтобы игра не открывала окно консоли. На Unix возвращает вход
|
||||
без изменений — там разницы нет.
|
||||
## windowlessVariant(javaPath)
|
||||
|
||||
#### QString select(const QString &gameDir, int requiredMajor, const QString &preferred, QString \*error)
|
||||
|
||||
Выбирает java не ниже `requiredMajor`. Если задан `preferred` — путь, указанный пользователем в
|
||||
настройках, — он проверяется первым и, если подходит, побеждает. Иначе перебираются найденные
|
||||
`findAll()` варианты.
|
||||
|
||||
При неудаче возвращает пустую строку и заполняет `error` — текст объясняет, что именно не нашлось:
|
||||
подходящей версии нет вовсе или указанный пользователем путь не подошёл.
|
||||
|
||||
Функция запускает процессы для определения версий, поэтому может занять заметное время; вызывать
|
||||
её в обработчике нажатия не стоит.
|
||||
|
||||
## Зависимости
|
||||
|
||||
Подключает `QString` и `QStringList`. От классов проекта не зависит.
|
||||
|
||||
## Пример использования
|
||||
|
||||
```cpp
|
||||
QString error;
|
||||
const QString java = JavaLocator::select(gameDir,
|
||||
version.javaMajor,
|
||||
settings.javaPath,
|
||||
&error);
|
||||
if (java.isEmpty()) {
|
||||
emit launchError(error);
|
||||
return;
|
||||
}
|
||||
|
||||
process.start(JavaLocator::windowlessVariant(java), arguments);
|
||||
```
|
||||
На Windows заменяет `java.exe` на `javaw.exe` из той же папки, если он там есть. Тогда при запуске
|
||||
игры не появляется консольное окно. На других системах возвращает путь без изменений.
|
||||
|
||||
---
|
||||
|
||||
|
||||
Reference in new issue
Block a user