Launcher: panel accounts via authlib-injector, skin & cape editor

Microsoft sign-in is gone. Server accounts now receive Yggdrasil tokens
from the panel and launch with authlib-injector pointed at the panel's
auth server, so online-mode servers verify players against it.

- Download authlib-injector from the panel mirror (fallback: official),
  SHA-256 verified and cached, with prefetched metadata
- New Skin & cape settings tab: upload, arm style, reset, cape picker
  with front/back previews
- Avatars render from the panel's head endpoint

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011ARcGWxLx21FwXJ3yfGriS
This commit is contained in:
Claude committed 2026-09-28 08:58:27 +00:00
1 parent 99b45141fc
commit 77a15cab8b
18 files changed
+454 -208

No files matched your search

+15 -1
View File
@@ -131,7 +131,20 @@ pub async fn run(app: AppHandle, instance_id: String, start: bool, deep: bool) -
emit_state(&app, &instance_id, "idle", Some("Instance is up to date".into()));
return Ok(());
}
let auth = auth.unwrap();
let (auth, auth_server) = auth.unwrap();
// Panel accounts authenticate through the panel's Yggdrasil server via
// authlib-injector; offline accounts launch without it.
let agent_args = match &auth_server {
Some(api) => {
report(Event::Stage { stage: Stage::Launching, label: "Preparing sign-in".into() });
let jar =
scopenet_core::authlib::ensure(&state.http, &state.layout, Some(&panel)).await.context("setting up authlib-injector")?;
let prefetched = scopenet_core::authlib::prefetch_metadata(&state.http, api).await.ok();
scopenet_core::authlib::jvm_args(&jar, api, prefetched.as_deref())
}
None => vec![],
};
report(Event::Stage { stage: Stage::Launching, label: "Starting Minecraft".into() });
let pick = |a: u32, b: u32, c: u32| {
@@ -153,6 +166,7 @@ pub async fn run(app: AppHandle, instance_id: String, start: bool, deep: bool) -
let branding = state.manifest.read().unwrap().as_ref().map(|m| m.branding.clone()).unwrap_or_default();
let opts = LaunchOptions {
auth: auth.clone(),
agent_args,
game_dir: game_dir.clone(),
memory_min_mb: min,
memory_max_mb: max,