merge: preserve ShaCraft 0.1.1 account and Windows features in modular launcher
This commit is contained in:
+18
-10
@@ -33,10 +33,14 @@ real main class is `net.minecraftforge.installer.SimpleInstaller`, which
|
||||
supports this flag. **Empirically verified (2026-09-06)**: it refuses to
|
||||
target a directory unless a `launcher_profiles.json` stub already exists
|
||||
there ("you need to run the launcher first!") — `ensure_launcher_profiles_stub`
|
||||
writes a minimal one. It then fetches and patches vanilla itself; no
|
||||
pre-seeding needed. Its own downloads go straight to `maven.neoforged.net`/
|
||||
Mojang, outside our control — an accepted trust delegation to NeoForge's
|
||||
official tooling once the installer binary itself is verified.
|
||||
writes a minimal one. It fetches the inputs needed to patch vanilla, but does
|
||||
not guarantee that the complete vanilla runtime library set is present.
|
||||
After installation, `mojang::ensure_client_jar` and `ensure_libraries` always
|
||||
verify and download the complete merged launch set, including LWJGL and its
|
||||
platform natives. The installer's own downloads go straight to
|
||||
`maven.neoforged.net`/Mojang, outside our control — an accepted trust
|
||||
delegation to NeoForge's official tooling once the installer binary itself is
|
||||
verified.
|
||||
|
||||
Also verified: the resulting
|
||||
`libraries/net/neoforged/neoforge/<ver>/neoforge-<ver>-client.jar` (the
|
||||
@@ -53,10 +57,13 @@ own on disk, confirmed).
|
||||
Hosts: `login.microsoftonline.com`, `user.auth.xboxlive.com`,
|
||||
`xsts.auth.xboxlive.com`, `api.minecraftservices.com`.
|
||||
|
||||
Real device-code OAuth login -> Xbox Live user token -> XSTS token ->
|
||||
Minecraft Services login -> `GET /minecraft/profile` ownership check (404 =
|
||||
doesn't own the game = nothing installs or launches). This is the actual
|
||||
ownership gate; it is not optional and there is no fallback identity. See
|
||||
This module is retained for a future Microsoft mode; the current launcher
|
||||
uses authenticated ShaCraft account links and deterministic offline identity.
|
||||
Do not treat this unused module as the active launch gate.
|
||||
|
||||
In a Microsoft flow: device-code OAuth -> Xbox Live user token -> XSTS token ->
|
||||
Minecraft Services login -> `GET /minecraft/profile` ownership check. An
|
||||
authentication/ownership failure must never fall back to another identity. See
|
||||
`MSA_CLIENT_ID`'s doc comment in `msa.rs`: unlike the other three domains,
|
||||
this one needs a deployment-specific value — ShaCraft's own Azure AD app
|
||||
registration, approved for Minecraft API access via
|
||||
@@ -66,13 +73,14 @@ refuse to run while it's still the placeholder.
|
||||
## 4. Eclipse Adoptium (`runtime.rs`)
|
||||
|
||||
Host: `api.adoptium.net` (redirects to `github.com`/
|
||||
`objects.githubusercontent.com` for the actual download — expected, still
|
||||
`objects.githubusercontent.com`/`release-assets.githubusercontent.com` for the download — expected, still
|
||||
verified).
|
||||
|
||||
Java 21 JRE, GPLv2+CE. The API returns the release's SHA-256 inline, verified
|
||||
before extraction. Never touches a Java installation the user already has —
|
||||
`java::ensure_java` only provisions here when `java::detect()` finds nothing
|
||||
with at least the manifest's `javaMajor`.
|
||||
with exactly the manifest's `javaMajor`; a newer major is not assumed
|
||||
compatible with the Minecraft/NeoForge version.
|
||||
|
||||
## Why this separation matters
|
||||
|
||||
|
||||
@@ -4,10 +4,14 @@
|
||||
|
||||
The launcher persists local settings, synchronises Aeronautics mod/config
|
||||
files from the signed ShaCraft v2 manifest, installs the exact Minecraft +
|
||||
NeoForge version the manifest specifies, and launches the game. Players can
|
||||
launch either with a real Microsoft account or with a local offline profile
|
||||
(nickname + deterministic offline UUID) — see `docs/game-trust-boundary.md`
|
||||
and `AGENTS.md`'s trust model section.
|
||||
NeoForge version the manifest specifies, and launches the game. A player
|
||||
signs in with the same local ShaCraft account used on the website. The game
|
||||
identity is derived only from that account's verified Aeronautics nickname;
|
||||
the legacy editable nickname setting is not trusted at launch.
|
||||
|
||||
The interface also shows a live Aeronautics player count from the fixed,
|
||||
read-only `https://shacraft.ru/api/online/aoc` endpoint. It is display-only:
|
||||
the result never controls files, versions, URLs, or the launch command.
|
||||
|
||||
Not yet implemented: a user-selectable profile directory, a "reset managed
|
||||
files only" recovery action, and signed cross-platform release builds of the
|
||||
@@ -28,7 +32,9 @@ Game itself (never controlled by the manifest above)
|
||||
-> Java 21 via Adoptium if none installed (runtime.rs)
|
||||
-> NeoForge's own installer, run headlessly (neoforge.rs)
|
||||
-> generic inheritsFrom merge of the two version JSONs (mojang.rs)
|
||||
-> explicit Microsoft session (msa.rs) OR offline identity (session.rs)
|
||||
-> SHA-1-verified merged libraries + platform natives (mojang.rs)
|
||||
-> verified ShaCraft account link (shacraft_account.rs)
|
||||
-> deterministic offline UUID for the linked nickname (session.rs)
|
||||
-> java process spawned with the merged classpath/args (launch.rs)
|
||||
```
|
||||
|
||||
@@ -37,8 +43,9 @@ screenshots/resourcepacks) live below Tauri's `app_data_dir()/profiles/
|
||||
<profile-id>` — this becomes `--gameDir`. The shared vanilla+NeoForge
|
||||
install (versions/libraries/assets/runtime, reused across profiles that
|
||||
target the same Minecraft version) lives at `app_data_dir()/game`. Settings
|
||||
live at `app_data_dir()/settings.json`, the Microsoft refresh token at
|
||||
`app_data_dir()/account.json` (mode 600). None of these should be assumed to
|
||||
live at `app_data_dir()/settings.json`, and the revocable ShaCraft session at
|
||||
`app_data_dir()/shacraft-session` (mode 600 on Unix). Passwords are never
|
||||
written to disk. None of these should be assumed to
|
||||
be the system `.minecraft` directory.
|
||||
|
||||
## Aeronautics contract
|
||||
@@ -52,6 +59,22 @@ be the system `.minecraft` directory.
|
||||
no launcher release.
|
||||
- ShaCraft download files: HTTPS only, exact hosts `shacraft.ru` and
|
||||
`cdn.shacraft.ru`.
|
||||
- Account API origin: fixed `https://shacraft.ru`; redirects are rejected.
|
||||
- Launch identity: the most recently verified `aoc` nickname returned by the
|
||||
authenticated account API. Local nickname edits cannot select an identity.
|
||||
|
||||
## Planned but not implemented
|
||||
|
||||
1. User-selectable profile directory and structured launcher logs.
|
||||
2. "Reset managed files only" recovery action that doesn't touch player
|
||||
worlds/screenshots/resourcepacks.
|
||||
3. Signed, cross-platform release builds of the launcher itself.
|
||||
4. Cancellation, structured logs and a full cold-install/recovery beta on
|
||||
every target OS. Install progress reports bytes or installer work counts
|
||||
depending on the stage; these units are not interchangeable.
|
||||
|
||||
Do not represent these as completed features in UI or release notes.
|
||||
|
||||
|
||||
## Module boundaries (2026-09-09)
|
||||
|
||||
@@ -62,32 +85,23 @@ even under React StrictMode. A failed repair invalidates profile readiness.
|
||||
Game exit may arrive before launch acknowledgement; the reducer handles both.
|
||||
Browser preview cannot install/launch and does not simulate download progress.
|
||||
|
||||
Rust `lib.rs` registers commands from `commands/`. Install/account permits in
|
||||
`operations.rs` stay owned by blocking workers until completion. These are
|
||||
process-local guards, not cross-process locks or cancellation support.
|
||||
Rust `lib.rs` registers commands from `commands/`. Installation and account
|
||||
permits in `operations.rs` stay owned by blocking workers until completion.
|
||||
ShaCraft sessions have a separate gate from the retained Microsoft module.
|
||||
These are process-local guards, not cross-process locks or cancellation.
|
||||
`storage.rs` provides unique temporary files and atomic replacement; Unix
|
||||
account files are created owner-only rather than chmodded after writing.
|
||||
`trusted_http.rs` constrains initial provider URLs and every redirect.
|
||||
Manifest profile identity, size, signature, portable paths and existing
|
||||
symlinks are checked before managed file writes. Local same-user TOCTOU is
|
||||
outside this protection; do not describe it as an OS sandbox.
|
||||
session files are created owner-only. Windows keeps a recoverable replacement
|
||||
fallback if the OS refuses direct replacement. `trusted_http.rs` constrains provider
|
||||
URLs and redirects. Manifest profile identity, size, signature, portable
|
||||
paths and existing symlinks are checked before managed file writes.
|
||||
Hostile same-user TOCTOU is outside this protection; it is not an OS sandbox.
|
||||
|
||||
## Verification and distribution
|
||||
|
||||
`npm test` covers asynchronous helpers and state transitions;
|
||||
`npm run build` runs strict TypeScript before Vite. `cargo test --locked`
|
||||
covers native policy and storage. Push/PR CI repeats these checks on Linux.
|
||||
Manual `build.yml` builds Windows x64, Linux x64 and both macOS architectures
|
||||
and uploads bundles. Packages are not yet signed release artifacts.
|
||||
|
||||
## Planned but not implemented
|
||||
|
||||
1. User-selectable profile directory and structured launcher logs.
|
||||
2. "Reset managed files only" recovery action that doesn't touch player
|
||||
worlds/screenshots/resourcepacks.
|
||||
3. Signed, cross-platform release builds of the launcher itself.
|
||||
4. Cancellation, structured logs and full cold-install/recovery beta on
|
||||
every target OS. Current install progress reports actual stage work;
|
||||
bytes and installer completion counts are not interchangeable units.
|
||||
|
||||
Do not represent these as completed features in UI or release notes.
|
||||
covers native policy and storage. Push/PR CI repeats checks on Linux.
|
||||
The package workflow runs on main pushes or manually and builds Windows
|
||||
x64, Linux x64 and both macOS architectures with named artifacts.
|
||||
Packages are not yet signed release artifacts. Native cold-install and
|
||||
launch tests are required before calling a platform release-ready.
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
# Глобальный рефакторинг — 2026-09-09
|
||||
|
||||
## Границы работы
|
||||
|
||||
Переработаны backend/шаблоны сайта и React/Rust-слои нового лаунчера.
|
||||
Не менялись миры, модпак, порты, compose-топология, цены или режимы аккаунтов.
|
||||
Не переносились production-БД, секреты и приватный ключ подписи.
|
||||
|
||||
## Backend
|
||||
|
||||
- Монолит main.py разделён на HTTP routers, services, schemas, middleware
|
||||
и единый резолвер ресурсов. Entrypoint app.main:app сохранён.
|
||||
- Cookie/bearer вход используют одну реализацию аккаунтов, паролей и сессий.
|
||||
- Ограничитель попыток входа защищён от гонок и бесконечного роста памяти.
|
||||
Он process-local; multi-worker развертывание требует общего хранилища.
|
||||
- Оплата и подписка фиксируются одной SQLite-транзакцией. Claim/reject,
|
||||
продление, recovery и привязки сериализуют конфликтующие операции.
|
||||
- JSON metadata проверяются централизованно: неверный UTF-8, не-object JSON
|
||||
и небезопасные идентификаторы не приводят к непредусмотренному чтению пути.
|
||||
- Jinja наследование убирает копии фона/шапки/навигации. Размер фона 72×83
|
||||
задаётся единожды. HTML-формы, скрипты и визуальная структура сохранены.
|
||||
- Python зависимости зафиксированы на версиях действовавшего runtime.
|
||||
Добавлены pytest, Ruff, CI и изолированный test-stage Docker.
|
||||
|
||||
## Лаунчер
|
||||
|
||||
- React разделён на компоненты, hooks, типизированный IPC и reducers.
|
||||
TypeScript проверяется сборкой; ошибки IPC не теряются.
|
||||
- Сохранены новые изменения GitHub 0.1.1: обязательный ShaCraft-аккаунт,
|
||||
verified aoc nickname, реальный онлайн, управление окном и Windows-фиксы
|
||||
установки/полных библиотек/точной Java major/длинной JVM-команды.
|
||||
- Сохранения настроек упорядочены; lifecycle install/launch/exit явный;
|
||||
демонстрационные значения прогресса не выдаются за реальную установку.
|
||||
- Rust commands выделены по ответственности. Неиспользуемые команды
|
||||
unsigned sync/inspect удалены; запись профиля требует verified manifest.
|
||||
- Общие атомарные записи и process-local permits защищают файлы от
|
||||
конфликтующих операций. Проверяются переносимые пути, symlink и подпись.
|
||||
- HTTPS exact-host policy распространяется и на redirects отдельных
|
||||
игровых провайдеров. Метаданные архивов Adoptium проверяются до загрузки.
|
||||
- GitHub: тесты/сборка на push/PR; ручная матрица пакетов Linux/Windows/macOS
|
||||
Intel/ARM с сохранением артефактов. Это не подпись релизов и не автообновление.
|
||||
|
||||
## Проверки
|
||||
|
||||
Фактический итог: 88 backend-тестов + 23 subtests (локально и в изолированном
|
||||
Docker), 22 UI-теста, 59 Rust unit tests и отдельная живая read-only проверка
|
||||
production signed-manifest — успешно. npm ci/audit: 0 известных уязвимостей
|
||||
на момент прогона; строгий TypeScript/Vite и Ruff проходят. Это итог после
|
||||
объединения со всеми изменениями GitHub 0.1.1; прежние upstream Rust-тесты
|
||||
сохранены. Browser smoke: вход/регистрация ShaCraft, preview-gating,
|
||||
настройки, закрытие Escape и восстановление фокуса проверены без отправки
|
||||
учётных данных. Четыре тяжёлых/live игровых сценария не запускались.
|
||||
|
||||
Backend выложен, image ID контейнера совпадает с собранным образом;
|
||||
главная/Help/Моды/кабинет/healthz/catalog/signed-manifest отвечают 200,
|
||||
публичная админка по-прежнему закрыта Caddy (403). Внешний вид проверен
|
||||
в браузере. Время запуска mc-aoc не изменилось. Резервный образ сохранён
|
||||
как `shacraft-backend:before-refactor-20260909`, исходники —
|
||||
`/root/shacraft-rollback-NWKzLR`. Схема БД не менялась.
|
||||
|
||||
Backend: неизменность полного OpenAPI-снимка, публичные шаблоны, аккаунты,
|
||||
пароли/recovery, rate limit, LoginSystem gating, admin auth, платежи,
|
||||
rollback/параллельные операции, каталоги/manifest/config, startup/shutdown.
|
||||
Внешние эффекты замещены заглушками, БД только временная.
|
||||
|
||||
Launcher: строгий TypeScript + Vite, тесты UI state/settings/listeners,
|
||||
Rust unit tests по подписи/путям/хранилищу/IPC guards/trusted hosts.
|
||||
Полная холодная установка игры, OAuth и запуск на Windows/macOS требуют
|
||||
отдельного ручного beta-прогона; не выдавать локальные проверки за такой тест.
|
||||
|
||||
## Не замаскированные рефактором ограничения
|
||||
|
||||
1. Привязка ника: NoGravity подтверждает авторизацию игрока на сервере,
|
||||
но не связь с конкретным веб-запросом. Нужен одноразовый challenge в игре.
|
||||
2. Реферальная акция: enforcement REFERRAL_ENABLED и новизны самого
|
||||
плательщика не соответствует всей публичной формулировке. Требуется
|
||||
отдельное согласованное изменение бизнес-правил и регрессионные тесты.
|
||||
3. RCON/уведомления после commit не имеют outbox/retry. Сбой может потребовать
|
||||
ручной выдачи, а не повторного начисления подписки.
|
||||
4. Microsoft OAuth не является текущим способом входа: используется
|
||||
ShaCraft account + verified nickname. Неактивный OAuth-модуль требует
|
||||
собственного client ID и API approval при отдельной будущей активации.
|
||||
5. Нужны подписанные installer/update-релизы, native beta на всех ОС,
|
||||
полноценная отмена загрузок и recovery пользовательских данных.
|
||||
6. Блокировки лаунчера process-local; symlink-проверки не защищают от
|
||||
злонамеренного same-user TOCTOU. Keychain хранения refresh token пока нет.
|
||||
Reference in New Issue
Block a user