# Эфир

Настольный лаунчер Minecraft Java для Linux. Тематика: скалк, души и Сифт. Собственная пиксельная графика рисуется средствами Qt; визуальная структура вдохновлена Millida, XMCL и Modrinth.

## Запуск

В меню приложений найдите **Эфир**. Из терминала:

```bash
~/.local/bin/ether-launcher
```

Прямой запуск:

```bash
bash /mnt/windows/ether-launcher/run.sh
```

Проект, виртуальное окружение и игровые данные перенесены на `/mnt/windows/ether-launcher/`. Это подключённый раздел с наибольшим доступным свободным местом на момент переноса: 59,8 млрд байт до копирования, против 58,3 млрд на внешнем SSD и 18,7 млрд в домашней папке. Большой раздел `/dev/nvme1n1p3` не подключён; система не разрешила монтирование, поэтому сравнить его свободное место не удалось.

Диск должен быть подключён в `/mnt/windows`. Ярлык сообщает об отсутствии диска, вместо создания нового хранилища в домашней папке. Старые пути `~/Проекты/moss-launcher` и `~/.local/share/moss-launcher` теперь являются ссылками на новый проект и данные. Новый короткий путь к проекту: `~/Проекты/ether-launcher`.

## Сборки

Нажмите «Создать сборку», укажите название, точную версию Minecraft и загрузчик. Версию можно вписать вручную: варианты в списке служат примерами.

Библиотека показывает карточки сборок и поддерживает поиск по названию, версии и загрузчику. Карточка открывает обзор сборки. На отдельных вкладках находятся моды, параметры памяти/Java и журнал. Экран «Хранилище» показывает путь к данным и свободное место.

Для первой установки нажмите «Установить игру и загрузчик». Добавьте совместимые JAR-моды во вкладке «Моды», затем нажмите «Играть». Fabric API и другие зависимости добавляются как обычные JAR. Раздел «Каталог» позволяет искать и устанавливать моды, сборки, ресурспаки и шейдеры из Modrinth и CurseForge. Контент открывается внутри конкретной сборки: иконка, название, версия, загрузчик, описание, переключатель, информация и удаление. Есть вкладки модов, ресурспаков, дата-паков и шейдеров, перетаскивание файлов и групповое переключение. Обязательные зависимости модов загружаются автоматически; их версия Minecraft и загрузчик проверяются. Обновление всех установленных модов одной кнопкой пока отсутствует.

Загрузчики: Fabric, Forge, NeoForge, Quilt, а также vanilla через minecraft-launcher-lib. Поддержка выбранной пары версии и загрузчика проверяется при установке. При повторной установке библиотека проверяет файлы игры; это не проверка совместимости модов.

Общие файлы Minecraft и Java расположены в `data/runtime/`, отдельные сборки — в `data/instances/`. Для другого места данных можно задать `ETHER_DATA_DIR`. Прежняя переменная `MOSS_DATA_DIR` поддерживается для совместимости. Интерпретатор Python виртуального окружения использует общую установку Python от uv в домашней папке; пакеты самого лаунчера находятся на новом диске.

ZIP содержит `ether-pack.json`, mods, config, resourcepacks, shaderpacks, kubejs и defaultconfigs. Миры, runtime, журналы и учётные данные не включаются. Это собственный формат Эфира, не `.mrpack`; импорт ZIP пока отсутствует. Журнал игры: `ether-launch.log` в папке сборки.

## Аккаунт Эфира (версия 0.5.1)

Нажмите **Аккаунт Эфира** в боковой панели: вход откроется сразу в браузере Linux по умолчанию через `xdg-open`. Выберите Discord или Telegram на сайте. В системном браузере откроется [ether.btvo.ru/account](https://ether.btvo.ru/account). Первый вход создаёт профиль; повторный возвращает к нему. Для входа в лаунчер отдельно подтвердите свой запрос на сайте. Одноразовый запрос действует 5 минут и отменяется вместе с операцией в лаунчере.

**Подключить Microsoft** в аккаунте Эфира открывает сайт в браузере Linux по умолчанию. На сайте нажмите **Подключить Microsoft**: официальный OAuth Microsoft вернёт вас в профиль Эфира. Пользователь не вводит Client ID или секреты. Сайт сохраняет только подтверждённый идентификатор и имя Microsoft, не хранит access/refresh tokens. Для привязки не требуется лицензия Minecraft.

OAuth-приложение один раз настраивает владелец сайта; пока оно не зарегистрировано, сайт показывает, что подключение Microsoft ещё не включено. Вход в Minecraft Java для запуска игры остаётся отдельной функцией лаунчера и требует доступа к Minecraft API. Связанный аккаунт Microsoft сам по себе не выдаёт игровую лицензию или токен запуска.

Discord/Telegram можно подключить или отключить на сайте. Последний способ входа отключить нельзя. Идентификатор одного сервиса нельзя связать с двумя профилями Эфира; профили не объединяются по имени. **Выйти из Эфира** отзывает текущую сессию лаунчера; сессия сайта независима. Секрет сессии хранится через Secret Service/KWallet, а при его недоступности — только в памяти. Токены ботов и Discord Client Secret отсутствуют в лаунчере и скачиваемом архиве.

Интерфейс: **Мои сборки → карточка → Моды и ресурсы → Добавить из каталога**. Главная кнопка сначала устанавливает Minecraft, после установки запускает игру. **Скачать готовую сборку** открывает каталог модпаков. **Как пользоваться** объясняет основные шаги; технические параметры находятся в **Подключениях**.

## Microsoft и сервисы

Если аккаунта ещё нет, откройте **Аккаунт Minecraft → Создать аккаунт Microsoft**: официальный сайт [регистрации Microsoft](https://signup.live.com/) откроется в системном браузере. После регистрации вернитесь в Эфир и нажмите **Войти в Microsoft** для входа через OAuth. Создание аккаунта на сайте не требует Client ID; для OAuth-входа настройте приложение, как описано ниже.

Откройте **Подключения** в боковой панели. Modrinth работает без ключа. Для CurseForge введите выданный вам API-ключ; для Microsoft — Client ID зарегистрированного приложения с разрешением на Minecraft API. Готовых ключей сторонних лаунчеров в проекте нет.

Настройка Microsoft:

1. Зарегистрируйте своё приложение в Microsoft Entra/Azure с поддержкой личных Microsoft-аккаунтов.
2. Добавьте платформу публичного мобильного/настольного приложения и redirect URI `http://localhost`. Client Secret не нужен: лаунчер использует официальную библиотеку MSAL и OAuth 2.0 с PKCE. Для входа по коду устройства разрешите public client flows.
3. Получите разрешение на доступ к Minecraft API через процедуру Microsoft/Minecraft, описанную в [документации minecraft-launcher-lib](https://minecraft-launcher-lib.readthedocs.io/en/latest/tutorial/microsoft_login.html).
4. Введите Client ID в **Подключения**, сохраните и нажмите **Войти в Microsoft**.

Как в [реализации XMCL](https://github.com/Voxelum/x-minecraft-launcher/blob/master/xmcl-runtime/user/accountSystems/MicrosoftOAuthClient.ts), используется MSAL PublicClientApplication с authority `https://login.microsoftonline.com/consumers` и XboxLive scopes. Собственный Client ID требуется и для браузерного OAuth, и для Device Code; Client ID XMCL не подставляется в Эфир.

Обычный вход открывает системный браузер. Лаунчер принимает возврат через локальный HTTP-сервер с временным портом и проверяет `state`. MSAL генерирует PKCE, проверяет OAuth-ответ и получает токен. Возврат использует `form_post`, чтобы код авторизации не попадал в URL. Копировать адрес из браузера не нужно. Кнопка **Войти по коду** открывает Device Code OAuth: код виден в диалоге Эфира, а учётные данные вводятся только на сайте Microsoft. Ожидание можно отменить; оно автоматически заканчивается через 3 минуты для браузерного входа и через 5 минут для кода устройства. Затем проверяются Xbox Live и профиль Minecraft Java. Перед запуском игры MSAL получает Microsoft-токен из кеша и при необходимости обновляет его, затем Эфир получает токен Minecraft. Старые сессии версии 0.3 нужно авторизовать повторно. Кнопка **Выйти из аккаунта** удаляет кеш OAuth и локальный сохранённый вход; аккаунт Microsoft в браузере остаётся доступен.

Полный сериализованный кеш MSAL (включая refresh tokens) и API-ключ CurseForge хранятся через системный Secret Service/KWallet. В JSON сохраняются только Client ID, имя/UUID профиля и идентификатор Microsoft-аккаунта для выбора записи в OAuth-кеше. Если хранилище секретов недоступно или закрыто, секреты остаются только в памяти до завершения приложения. Непроверенные файловые/текстовые keyring-backend не используются. При следующем запуске с сохранённым аккаунтом вход восстанавливается при запуске Minecraft; без доступа к хранилищу потребуется войти повторно.

Для интеграции CurseForge нужен ключ именно для стороннего сервиса/лаунчера: [инструкция API](https://docs.curseforge.com/rest-api/). Он передаётся в заголовке `x-api-key` API и официальному CDN CurseForge; чужим хостам при перенаправлении ключ не отправляется. Когда автор запретил загрузку через API, лаунчер объясняет ограничение: откройте страницу проекта, скачайте файл самостоятельно и добавьте/импортируйте через системный диалог.

Можно также задать переменные `ETHER_MICROSOFT_CLIENT_ID` и `ETHER_CURSEFORGE_API_KEY`; они имеют приоритет над сохранёнными настройками. Секретный ключ не нужно отправлять в чат.

Microsoft-вход и реальные скачивания CurseForge пока не проверены с настоящими регистрационными данными. Протокол возврата OAuth form_post/PKCE, Device Code, восстановление MSAL-кеша, выход и контракты CurseForge проверены автоматическими тестами с подставными ответами сервисов.

## Каталог и импорт сборок

1. Выберите источник и тип контента в **Каталог**.
2. Для модов, ресурспаков и шейдеров укажите целевую сборку. Для модов её версия Minecraft и загрузчик задают совместимость установки.
3. Найдите проект и нажмите **Выбрать версию и установить**. Страница проекта также открывается в системном браузере.
4. Модпак создаёт новую сборку; после импорта нажмите **Установить Minecraft** в её обзоре.

Есть поиск с пагинацией и фильтрами. Modrinth и CurseForge предоставляют версии для выбранного проекта; для CurseForge показывается до 50 файлов, возвращённых API по фильтру. Мод и его обязательные зависимости устанавливаются вместе после проверки загрузок. Другая установленная версия или конфликтующий JAR-мод не перезаписываются: лаунчер просит сначала удалить старый файл. Отключённая обязательная зависимость требует включения.

Кнопка **Импорт .mrpack / CurseForge ZIP** импортирует локальный архив через системный выбор файлов. Поддерживаются `modrinth.index.json`, `manifest.json`, настройки из overrides и client-overrides. Server-overrides и необязательные/серверные файлы пропускаются. CurseForge ZIP с файлами, указанными в манифесте, требует API-ключ для их скачивания. Формат собственного экспорта `ether-pack.json` пока не импортируется этой кнопкой.

Файлы скачиваются во временную папку на диске Эфира. Для API-файлов проверяются размеры и доступные SHA512/SHA1/MD5; файлы с неверными хешами не устанавливаются. Архивы проверяются на выход за пределы папки, NTFS-пути и символические ссылки. Если импорт прерван, незавершённая сборка не появляется в библиотеке. Скачивание и импорт можно отменить; активный сетевой запрос завершится по своему таймауту.

Шейдеры размещаются в `shaderpacks`, ресурспаки — в `resourcepacks`; включить их нужно в игре. Обязательные зависимости, указанные автором в API, устанавливаются автоматически, но неуказанные требования (например, Iris/OptiFine для шейдеров) нужно добавить отдельно. Загружаемые URL поддерживают CDN Modrinth/CurseForge и GitHub/GitLab; неизвестный хост требует ручной загрузки со страницы автора.

## Контент выбранной сборки

Раздел **Контент** находится в странице сборки. JAR-файлы читаются как архивы: имя, версия, описание, загрузчик и иконка берутся из `fabric.mod.json`, `quilt.mod.json`, Forge/NeoForge TOML или `mcmod.info`. Никакой код мода при этом не запускается. У ZIP-пакетов читаются `pack.mcmeta` и `pack.png`.

Сканирование вычисляет SHA1 локальных файлов и сопоставляет их с Modrinth через `version_files`; найденные версии получают описание и ссылку проекта. Изменения метаданных сохраняются только в выбранной сборке. Файлы, не найденные на Modrinth, сохраняют локальные метаданные.

Переключатель включает/отключает конкретный файл переименованием в `.disabled`. Чекбоксы позволяют выбрать несколько файлов для группового переключения. Удаление переносит файл в `.trash` внутри этой сборки; кнопка **Корзина** открывает эту папку системным проводником, откуда файл можно перенести обратно. Миры и другие сборки не затрагиваются.

Кнопка **Добавить из каталога** сразу выбирает текущую сборку и тип контента; после установки открывает её раздел контента. Дата-паки помещаются в `saves/<выбранный мир>/datapacks`. Для них сначала выберите существующий мир; прямой онлайн-каталог дата-паков пока не подключён. Поддержаны локальные `.jar` для модов и `.zip` для пакетов; LiteLoader/.litemod не поддерживается.

## Системный проводник и выбор файлов

На этом компьютере папки по умолчанию ассоциированы с Kitty, поэтому лаунчер вызывает установленный **Dolphin** напрямую. На другом компьютере выбирается доступный графический проводник, затем `xdg-open`. Глобальные системные ассоциации не меняются.

Выбор JAR-файлов, импорт архивов и экспорт ZIP используют внешние системные диалоги Zenity/KDialog. Встроенный файловый диалог Qt полностью удалён. Для выбора файлов нужен установленный `zenity` или `kdialog`; на текущей системе есть Zenity.

Minecraft использует скачанный Java runtime, если он предусмотрен метаданными версии. Для некоторых установщиков загрузчиков нужна системная Java. При несовместимой Java задайте полный путь к нужному исполняемому файлу во вкладке **Настройки**.

## Проверки

```bash
cd /mnt/windows/ether-launcher
.venv/bin/python -m unittest -v
```

Тесты проверяют сохранение и изоляцию сборок, переключение модов, экспорт, навигацию, поиск, настройки, фоновые задачи, возврат OAuth/PKCE, обновление токена, системные диалоги, зависимости, форматы модпаков и проверку скачиваний. Все тестовые сборки создаются во временных папках. Изображения `preview*.png` показывают интерфейс с временными демонстрационными сборками, не добавленными в пользовательское хранилище.

Проверены реальные поиск/выбор версии/скачивание Sodium и импорт Fabulously Optimized 6.5.0 для Minecraft 1.21.1 из Modrinth (48 модов) во временных папках. Полный запуск Minecraft с Microsoft-аккаунтом ещё не проверен.

Референсы: [Millida](https://millida.net/launcher), [XMCL](https://www.xmcl.app/en/), [Modrinth](https://modrinth.com/app).

Документация движка: [minecraft-launcher-lib](https://minecraft-launcher-lib.readthedocs.io/en/latest/tutorial/install_mod_loader.html).
