From 8e00526d2769684c7cdc2bbab00355a2e9017269 Mon Sep 17 00:00:00 2001 From: Matt Date: Sat, 23 May 2026 16:31:17 +0000 Subject: [PATCH] launcher: refresh Microsoft session right before launch Microsoft access tokens have a ~1 hour TTL. The launcher cached the MSession once at sign-in and re-used it on every Play click, so leaving the launcher open for >1 hour and then hitting Play sent stale credentials to MC -- Mojang's session check on the server then rejected the join with "Invalid session". Fix: in DoLaunchAsync, before assembling the MC launch command, call _auth.TryAuthenticateSilentlyAsync(). XboxAuthNet's silent flow uses the cached refresh token (~14 day TTL) to mint a fresh access token transparently. On success ApplySession swaps in the new MSession and we launch with valid credentials. On failure (refresh token also stale) the launcher prompts the player to sign in again -- they keep the launcher open, hit Sign In, no MC restart needed. No new dependencies, no UI change beyond the brief "Refreshing session..." status line, no perf cost beyond the ~500ms HTTP roundtrip to Microsoft each launch. Bump the launcher version in launcher/ModpackLauncher.csproj before publishing so old launcher installs see the upgrade banner. --- launcher/MainWindow.axaml.cs | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/launcher/MainWindow.axaml.cs b/launcher/MainWindow.axaml.cs index 40aba38..d801c11 100644 --- a/launcher/MainWindow.axaml.cs +++ b/launcher/MainWindow.axaml.cs @@ -797,6 +797,32 @@ public partial class MainWindow : Window try { SetBusy(true); + + // ─── Refresh the Microsoft session before launch. ───────────────── + // _session was set at sign-in; the access token inside is short-lived + // (~1 hour). If the launcher's been open longer than that, MC will + // send stale credentials to the server and Mojang's session check + // rejects the join ("Invalid session"). XboxAuthNet's silent flow + // uses the cached refresh token (~14 day TTL) to mint a fresh + // access token transparently. + UpdateStatus("Refreshing session...", ""); + var freshSession = await _auth.TryAuthenticateSilentlyAsync(); + if (freshSession != null) + { + ApplySession(freshSession); + AppendLog("[auth] Session refreshed before launch."); + } + else + { + // Refresh token also stale -- need full interactive re-login. + // Don't try inline (player would lose context); prompt them to + // hit Sign In again. + AppendLog("[auth] Silent refresh returned no session; sign-in required."); + UpdateStatus("Session expired", "Please sign in again to continue."); + ClearSession(); + return; + } + var progress = new Progress(OnProgress); var installDir = GetInstallDir(); _launch ??= new LaunchService(installDir); -- 2.52.0