Chimera Launcher
Посмотреть и раскритиковать
Я писал этот лаунчер для себя: хотел запускать Windows-игры на Linux и не держать в голове, чем Lutris отличается от Heroic и какой префикс к чему относится. Получилось приложение на Rust и GTK4, которым я пользуюсь каждый день.
Буду рад замечаниям. Особенно тем, что начинаются со слов «так делать нельзя, потому что».
Что посмотреть за пять минут
- Главная — что умеет, со снимками экрана.
-
Исходники — всё дерево
прямо в браузере. Или
git clone https://project-chimera.ru/launcher/git/chimera-launcher.git - Журнал разработки — что ломалось и чем чинилось. Там же видно, как я принимаю решения.
- Что уходит в сеть — таблица по каждому случаю.
Решения, о которых хочется поспорить
Каждое выбрано осознанно, но ни одно не бесспорно.
Настройки в четыре слоя
Значение настройки берётся из четырёх мест по порядку: умолчание, профиль сообщества, общие настройки, настройка этой игры. Выбор человека сильнее всех остальных слоёв.
Команда chl settings <игра> печатает итоговое значение и
слой, из которого оно пришло. Без этого вопрос «почему игра запускается
вот так» остаётся без ответа.
Спорно: четыре слоя сложнее двух. Я выбрал их, потому что советы сообщества нельзя класть в тот же файл, что и выбор человека — иначе чужой совет однажды перепишет ваш.
Один префикс на все игры
Wine-префикс — это «диск C:» для игры. Обычно на каждую игру заводят свой. Здесь он общий.
Спорно: общий префикс ломается сразу для всех игр. Взамен он не съедает по 3–6 ГБ на игру, а перед каждым изменением лаунчер снимает копию и умеет откатиться.
Настройки доходят до игр Steam без перезапуска Steam
Steam не перечитывает параметры запуска, пока его не перезапустишь
(баг
steam-for-linux#6443). Поэтому лаунчер ставит себя в
compatibilitytools.d отдельным слоем совместимости: Steam
запускает наш скрипт, он выставляет окружение и передаёт управление
Proton.
Спорно: лезть в каталог чужой программы. Взамен настройки применяются на следующем запуске игры, а не после перезапуска Steam.
Витрина Epic: мы врали о себе, и защита ловила именно это
Перед сайтом Epic стоит Cloudflare, и встроенный браузер сутки упирался в «подтвердите, что вы человек». Я перебрал пять версий и все пять оказались мимо: защита от межсайтового отслеживания, нестабильный внешний адрес из-за туннеля, подмена внутренних признаков страницы, строка родного лаунчера Epic, разные строки для разных хостов. Каждая что-то чинила и ломала соседнее.
Причина была проще всех догадок. WebKitGTK называется Safari-подобной
строкой, и это правда: у него нет ни
navigator.userAgentData, ни остального, что есть у
настоящего Chrome. Назвавшись Chrome, движок начинает противоречить сам
себе — а Cloudflare ровно это и сверяет: заявленное против
наблюдаемого. Увидев расхождение, он поднимает проверку до галочки,
которую WebKitGTK уже не проходит.
Подмена строки убрана вовсе. Сайт видит Safari, каким браузер и является, и пропускает без единой проверки. Вход в витрину при этом берётся из токена лаунчера: пароль не вводится, галочка не появляется.
Тот же урок читается в исходниках Heroic: его preload
подменяет navigator.platform и
navigator.userAgentData — но только когда строка говорит
«Windows». То есть он не выдаёт себя за чужой браузер, а следит, чтобы
заявленное сходилось с наблюдаемым. Обработки Cloudflare у него нет
вовсе.
Спорно: полтора десятка правок, каждая из которых лечила симптом очередной лжи о себе, — это полтора десятка мест, где я не проверил основание. Записано в журнал разработки как есть, вместе с ошибочными выводами по дороге.
Видеокарту выбирает человек, а не лаунчер
На машине с двумя видеокартами Vulkan отдаёт их списком, и нулевым устройством идёт встроенная в процессор. Нулевое берут все — и DXVK, и VKD3D, и всё, что переводит DirectX в Vulkan. То есть игры по умолчанию шли на встроенной, а дискретная простаивала, и внешне это неотличимо от «игра тяжёлая».
Настройка «Видеокарта» показывает найденные карты списком, с пометкой
«дискретная» или «встроенная», и выбор уходит в слой Mesa
device_select.
Спорно: очевидное умолчание — подставлять дискретную самим. Не делаю,
потому что список стоит запуска vulkaninfo, а это двести
миллисекунд на каждый запуск игры ради выбора, который человек делает
один раз.
Сессия Steam берётся у клиента Steam
Витрина Steam внутри лаунчера открывается под аккаунтом. Лаунчер в Steam не входит и пароля не знает: он читает локальный файл cookies клиента Steam и берёт оттуда пять записей для двух доменов магазина.
Спорно сильнее всего. Читать чужие cookies — приём из арсенала другого жанра. Поэтому настройка выключается, а на странице «Приватность» написано, что именно читается и куда попадает.
Что я и сам считаю слабым
- У записи игры нет поля «магазин». Epic и GOG пишутся одинаково, поэтому установленная игра из магазина попадает на обе вкладки библиотеки.
- Число запусков у игр Steam своё, неполное. Наигранное время лаунчер берёт у самого Steam, а вот запусков Steam не считает вовсе — их видно только те, что сделаны отсюда. Поэтому средняя длина сессии считается лишь по своим запускам.
- Нет оверлея поверх игры. Окно поверх игры не решает задачу: нужен слой Vulkan и перехват ввода.
- Записи экрана нет. Хоткей зарезервирован, реализации нет.
- Зеркало репозитория только на чтение. Прислать изменения пока некуда.
- Тесты интерфейса проверяют сборку, а не поведение. Логика вынесена в чистые функции и покрыта, но щелчки по кнопкам никто не проверяет.
Куда писать
Про код и решения
Скажите мне напрямую. Зеркало пока только на чтение, так что обсуждение идёт словами, а не пул-реквестами.
Про баг в работе
Из лаунчера: «Диагностика» → «Отправить отчёт». Он соберёт нужное под симптом и покажет целиком до отправки.
Про игру, которая не идёт
Карточка игры → «Префикс» → «Поделиться своим опытом». Так наполняется база запусков.