Files
SCOPENET-MC/docs/architecture.md
T
SCOPEDD a1f19e86c6 Complete private authentication, server integrations and activity reporting
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.
2026-09-28 13:31:17 -04:00

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/shared defines every JSON type exchanged, so the panel and launcher can't drift apart.
  • crates/core has 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 core for version and loader lookups.

Launch pipeline

  1. Resolve the account and validate its private Yggdrasil session.
  2. Fetch the instance from the panel (cached for offline play).
  3. 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.
  4. 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.
  5. Write servers.dat and keybinds, build the Java command (quick play / --server, memory, GC presets, @argfile for long classpaths), and start the game.
  6. 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 /files are public URLs. Don't put secrets in instance files.