Add Fabric/Forge version builds and Paper integration, preserve permanent player identities across renames, harden session authorization, and surface privacy-conscious launcher/server activity in the panel.
3.7 KiB
3.7 KiB
Architecture
┌──────────────────────────┐ HTTPS (JSON) ┌──────────────────────────┐
│ Launcher (Tauri) │ ─────────────────────────▶ │ Panel (Axum + SQLite) │
│ Svelte UI ⇄ Rust shell │ manifest, instances, │ Svelte admin UI │
│ │ │ auth, stats │ /files, /uploads │
│ scopenet-core engine │ └──────────────────────────┘
│ ├─ Mojang / Java │ ──▶ piston-meta, libraries.minecraft.net, resources
│ ├─ Fabric/Quilt/Forge │ ──▶ meta.fabricmc.net, maven.minecraftforge.net, …
│ └─ modpack files │ ──▶ Modrinth/CurseForge CDNs, panel /files
└──────────────────────────┘
crates/shareddefines every JSON type exchanged, so the panel and launcher can't drift apart.crates/corehas no UI dependencies. It's unit-tested, and CI runs real installs of vanilla, legacy, Fabric, Quilt, Forge and NeoForge against the live servers.- The panel also uses
corefor version and loader lookups.
Launch pipeline
- Resolve the account and validate its private Yggdrasil session.
- Fetch the instance from the panel (cached for offline play).
install: vanilla version JSON → Java runtime (Mojang's own builds) → client jar, libraries, assets → loader profile (Fabric/Quilt), or replay the Forge/NeoForge installer's processors → merge → natives.sync: download the admin's files; remove files the admin removed; never touch the player's own files. With an unchanged revision, only existence is checked.- Write
servers.datand keybinds, build the Java command (quick play /--server, memory, GC presets,@argfilefor long classpaths), and start the game. - Stream logs to the console; on a crash, show the tail of the log with hints.
Disk layout (launcher)
%APPDATA%\net.scopenet.launcher\
settings.json, accounts.json, secrets.bin (encrypted), manifest.json (cache)
minecraft\
versions\ libraries\ assets\ runtimes\ natives\ cache\
instances\<id>\ ← game directory (saves, mods, options.txt, …)
HTTP API
Public (used by launchers). Send Authorization: Bearer <token> to see restricted instances:
| Method | Path | |
|---|---|---|
| GET | /api/v1/launcher/manifest |
Branding, auth options, visible instances |
| GET | /api/v1/launcher/instances/{id} |
Instance + file list |
| POST | /api/v1/launcher/events |
Launch stats |
| POST | /api/v1/auth/login · /register |
Panel accounts |
| GET | /api/v1/auth/me |
Current user |
| GET | /files/{instance}/{path} |
Hosted instance files |
| GET | /healthz |
Health check |
Admin (role = admin): /api/admin/{stats,users,groups,branding,settings,instances,uploads} plus instances/{id}/{import/modrinth,import/curseforge,import/upload,files,reset} and meta/search proxies under /api/admin/{meta,modrinth,curseforge}.
Security notes
- Passwords are hashed with Argon2id; tokens are HS256 JWTs (30 days); disabled accounts are rejected on every request.
- Server-provided paths are sanitised (
safe_join) on both sides — no..or absolute paths. - The panel never returns the CurseForge key; SVG uploads are refused (script risk).
- The launcher's CSP only allows scripts from the app itself; media may load from any HTTPS host (admin-chosen images).
- Hosted
/filesare public URLs. Don't put secrets in instance files.