Все сервисы регистрируются как синглтоны в Bootstrapper.cs и внедряются через конструктор.
- Файл:
Services/Core/IpcService.cs - Назначение: Центральный реестр IPC-каналов — единый источник истины для всего взаимодействия React ↔ .NET
- Ключевой метод:
RegisterAll()— регистрирует все IPC-обработчики - Аннотации: Содержит XML-комментарии
@typeи@ipc, используемые генератором кода - Домены: config, game, news, profile, settings, i18n, window, browser, mods, console
- Таймаут выбора папки: Для
hyprism:file:browseFolderиспользуется увеличенный таймаут (300 сек.), чтобы выбор директории не обрывался на фронтенде. - Резолв целевого экземпляра модов: обработчики mod IPC выбирают путь по метаданным реально установленного экземпляра (включая latest) и не используют неявный fallback в плейсхолдер
branch/latest. - Точное нацеливание модов: mod IPC принимает опциональный
instanceId; если он передан, он имеет приоритет над branch/version и исключает коллизии при нескольких экземплярах с одной версией. - Changelog модов:
hyprism:mods:changelogвозвращает (best-effort) plaintext changelog для конкретного файла модификации CurseForge (modId+fileId). - Нацеливание instance-операций: обработчики удаления инстанса и работы с сейвами принимают
instanceIdи в первую очередь резолвят путь по GUID; branch/version сохранён как fallback для обратной совместимости. - Импорт экземпляров:
hyprism:instance:importподдерживает импорт из ZIP-архивов и PWR-файлов. ZIP-файлы распаковываются напрямую; PWR-файлы применяются через Butler для создания нового экземпляра с автоопределением версии из имени файла. - Обновление иконок инстанса:
hyprism:instance:getIconвозвращает URL файла с cache-busting параметром (?v=<lastWriteTicks>), чтобы новый логотип отображался сразу после перезаписи. - Правило загрузки иконок на фронтенде: в списке инстансов запросы иконок выполняются последовательно (не параллельно), чтобы исключить смешивание ответов в общем IPC reply-канале.
- Файл:
Services/Core/ConfigService.cs - Тип: Singleton
- Назначение: Конфигурация приложения (сохраняется в JSON)
- Пути конфигурации:
- Windows:
%APPDATA%/HyPrism/config.json - Linux:
~/.config/HyPrism/config.json - macOS:
~/Library/Application Support/HyPrism/config.json
- Windows:
- Файл:
Services/Core/Logger.cs - Тип: Статический класс
- Назначение: Структурированное логирование (бэкенд Serilog + цветной вывод в консоль + буфер в памяти)
- Методы:
Info(),Success(),Warning(),Error(),Debug(),Progress() - Файлы логов:
{appDir}/Logs/{timestamp}.log
- Файл:
Services/Core/LocalizationService.cs - Тип: Singleton (паттерн Instance)
- Назначение: Переключение языков в реальном времени с поддержкой вложенных ключей
- Файлы локалей:
Assets/Locales/{code}.json
- Файл:
Services/Core/BrowserService.cs - Назначение: Открытие URL в системном браузере по умолчанию
- Файл:
Services/Core/DiscordService.cs - Назначение: Интеграция с Discord Rich Presence
- Файл:
Services/Core/GitHubService.cs - Назначение: Проверка релизов и функция самообновления
- Назначение: Управление жизненным циклом игры — загрузка, установка, патчинг, запуск
- Состояния: preparing → download → install → patching → launching → running → stopped
- Режим кастомной авторизации: Для неофициальных профилей используется патч клиентского бинарника для кастомных session-доменов. Серверная авторизация использует один из двух режимов, управляемых настройкой
UseDualAuth. - Режимы патчинга сервера:
- Легаси патчинг JAR (по умолчанию):
ClientPatcher.EnsureAllPatched()статически патчит и клиентский бинарник, иServer/HytaleServer.jar, заменяяhytale.comна кастомный auth-домен. Это стабильный, проверенный подход. - DualAuth (экспериментальный): Патчится только клиентский бинарник; серверный JAR остаётся без изменений. Runtime Java Agent (
dualauth-agent.jar) загружается с GitHub и инжектится через переменную окружения-javaagent:для обработки серверной авторизации в рантайме. Может вызывать вылеты и проблемы с подключением.
- Легаси патчинг JAR (по умолчанию):
- Безопасность переключения режимов: Переключение обрабатывается корректно — при смене легаси на DualAuth серверный JAR восстанавливается из бэкапа
.original; при смене DualAuth на легаси JAR перепатчивается. - Домен JWKS для DualAuth: Домен для JWKS discovery вычисляется из sessions-домена заменой префикса
sessions.наauth.(например,sessions.sanasol.ws→auth.sanasol.ws). Обрабатывается методомDeriveAuthDomain()в GameLauncher. - Инвалидация AOT-кэша: Перед запуском
InvalidateAotCacheIfNeeded()обнаруживает изменение JVM-флагов через SHA-256 хеш и удаляет.aotи.jsaкэш-файлы в директории Server, чтобы предотвратить несоответствие UseCompactObjectHeaders. - Восстановление при 403 official CDN: если официальный URL возвращает HTTP 403 (просроченный подписанный
verify-токен), сервис принудительно обновляет кэш версий и один раз повторяет загрузку с official перед fallback на mirror. - Fallback для pre-release mirror: если целевой full-файл зеркала невалиден/отсутствует (например, 0-byte placeholder), сервис пытается установить предыдущую full-сборку и применяет цепочку патчей до целевой версии.
- Синхронизация запуска с выбранным инстансом: при выборе инстанса обновляются и
SelectedInstanceId, и legacy-поля запуска (VersionType/SelectedVersion), а запуск с Dashboard отправляет явныеbranch/version, чтобы исключить старт «старого» инстанса. - Режим установки из меню инстансов: запросы запуска из страницы инстансов могут передавать
launchAfterDownload=false, поэтому загрузка/установка завершается без автозапуска игры. - Приоритет пути запуска: если задан
SelectedInstanceId,GameSessionServiceрезолвит путь установки/запуска сначала по ID инстанса (без fallback на другой установленный инстанс того же branch/version). - Хранение метаданных latest:
latest.jsonхранится в корне ветки (Instances/<branch>/latest.json), а не вInstances/<branch>/latest/latest.json, чтобы не провоцировать случайное создание плейсхолдер-папокlatest. - Linux NVIDIA EGL fix: в режиме dedicated launcher экспортирует
__EGL_VENDOR_LIBRARY_FILENAMESв обнаруженный NVIDIA GLVND vendor JSON (например,/usr/share/glvnd/egl_vendor.d/10_nvidia.json), чтобы исключить fallback вllvmpipeна затронутых системах.
- Файл:
Services/Game/ClientPatcher.cs - КРИТИЧЕСКИЙ: Бинарные манипуляции для целостности игры
- Правило: НИКОГДА не изменяйте без явных инструкций
- Назначение: Управление обнаружением версий игры и разрешением URL загрузки
- Источники: Запрашивает списки версий с официального API Hytale и комьюнити зеркал (определяемых JSON мета-файлами в
Mirrors/) - Единое кэширование: Списки версий (
versions.json) и цепочки патчей (patches.json) кэшируются VersionService из ВСЕХ источников (official + зеркала) в одном координированном запросе. Оба кэша используют одинаковую мультисорсную структуру (official данные + per-mirror данные по source ID). - Санитизация кэша: Списки зеркал в
versions.jsonиpatches.jsonочищаются по текущему набору зарегистрированных mirror source ID (удаляются legacy/устаревшие записи и дубли ID) - Fallback на зеркало: При недоступности official зеркала автоматически тестируются и выбираются во время выполнения, с переключением на другие доступные зеркала при сбоях
- Политика release-загрузок: Для mirror
releaseлаунчер предпочитает полные standalone-сборки; метаданные патчей остаются в кэше для будущих сценариев обновления
- Файл:
Services/Game/Sources/IVersionSource.cs - Диагностический layout: Каждый источник отдает
LayoutInfoс тремя явными полями:- где загружаются полные сборки (
FullBuildLocation) - где загружаются diff-патчи (
PatchLocation) - как работает source-level кэш (
CachePolicy)
- где загружаются полные сборки (
- Цель: Снизить неоднозначность в поведении mirror patch/full и ускорить диагностику ошибочных URL
- Файл:
Services/Game/Sources/JsonMirrorSource.cs - Назначение: Универсальная реализация зеркал на основе JSON мета-дескрипторов (
Mirrors/*.mirror.json) - Типы источников:
pattern(шаблоны URL + обнаружение версий) иjson-index(единый API endpoint) - Цепочка патчей:
GetPatchChainAsyncстроит полную цепочку патчей из известных версий + URL-шаблонов, позволяя VersionService кэшировать патчи зеркал наравне с official - Тест скорости: Поддерживает тестирование скорости зеркала с измерением пинга и скорости загрузки
- Файл:
Services/Game/Sources/HytaleVersionSource.cs - Назначение: Официальный аутентифицированный источник версий (
account-data.hytale.com/patches) - Цепочка патчей:
GetPatchChainAsyncполучает шаги патчей через API-запросfrom_build=1 - Совместимость заголовков: Отправляет launcher-совместимые заголовки (
User-Agent,x-hytale-launcher-version,x-hytale-launcher-branch) и сохраняет retry с обновлением токена при 401/403
- Назначение: Просмотр, поиск и управление модами (интеграция с CurseForge)
- Fallback для URL загрузки: если CurseForge возвращает пустой
downloadUrl, а/download-urlотвечает403или пустым payload, сервис вычисляет детерминированный CDN URL поfileId + fileName. - Совместимость версий: Моды с конкретным
ServerVersionвmanifest.jsonJAR (формат:YYYY.MM.DD-<hash>) автоматически помещаются в карантин, если версия установленного сервера не совпадает. Моды сServerVersion: "*"(wildcard) всегда совместимы.
- Назначение: CRUD-операции с профилями игроков
- Возможности: Несколько профилей, управление аватарами, переключение профилей
- Политика хранения модов: переключение профиля не перенаправляет
UserData/ModsвProfiles/.../Mods; моды остаются в папке выбранного экземпляра. - Формат папок профилей: профили хранятся в
Profiles/{profileId}(GUID). - Миграция legacy-формата: при старте лаунчер пытается мигрировать старые name-based папки в
Profiles/в ID-based формат (best-effort, неразрушающее объединение при наличии обеих папок). - Маршрутизация auth для official-профиля: при переключении на официальный профиль домен аутентификации автоматически устанавливается в
sessions.hytale.com.