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.
This commit is contained in:
commit
a1f19e86c6
74 files changed
+2108
-95
No files matched your search
@@ -7,7 +7,7 @@ use scopenet_core::install::{self, InstallSpec};
|
||||
use scopenet_core::launch::{self, LaunchOptions};
|
||||
use scopenet_core::progress::{Event, Reporter, Stage};
|
||||
use scopenet_core::{options, servers_dat, sync};
|
||||
use scopenet_shared::{InstanceManifest, LaunchEvent};
|
||||
use scopenet_shared::InstanceManifest;
|
||||
use serde::Serialize;
|
||||
use std::collections::VecDeque;
|
||||
use std::path::PathBuf;
|
||||
@@ -79,6 +79,10 @@ fn reporter(app: &AppHandle) -> Reporter {
|
||||
pub async fn run(app: AppHandle, instance_id: String, start: bool, deep: bool) -> Result<()> {
|
||||
let state = app.state::<AppState>();
|
||||
let report = reporter(&app);
|
||||
let activity = crate::telemetry::capture(&state);
|
||||
if let Some(recorder) = &activity {
|
||||
recorder.background(if deep { "repair_start" } else { "install_start" }, &instance_id);
|
||||
}
|
||||
emit_state(&app, &instance_id, "preparing", None);
|
||||
|
||||
let account = state.accounts.read().unwrap().active().cloned();
|
||||
@@ -127,6 +131,9 @@ pub async fn run(app: AppHandle, instance_id: String, start: bool, deep: bool) -
|
||||
options::apply_keybinds(&game_dir, &settings.keybinds).ok();
|
||||
}
|
||||
|
||||
if let Some(recorder) = &activity {
|
||||
recorder.background(if deep { "repair_complete" } else { "install_complete" }, &instance_id);
|
||||
}
|
||||
if !start {
|
||||
emit_state(&app, &instance_id, "idle", Some("Instance is up to date".into()));
|
||||
return Ok(());
|
||||
@@ -183,20 +190,11 @@ pub async fn run(app: AppHandle, instance_id: String, start: bool, deep: bool) -
|
||||
tracing::info!("launching: {} {}", cmd.java.display(), launch::redact(&cmd.args, &auth.access_token).join(" "));
|
||||
|
||||
let close_after = settings.after_launch == "close";
|
||||
let mut child = launch::spawn(&cmd, installed.java_major, !close_after).context("couldn't start Java")?;
|
||||
|
||||
if settings.send_stats && !panel.is_empty() {
|
||||
let http = state.http.clone();
|
||||
let token = accounts::panel_token(&state);
|
||||
let ev = LaunchEvent { instance_id: instance_id.clone(), kind: "launch".into(), username: Some(auth.username.clone()) };
|
||||
tokio::spawn(async move {
|
||||
let mut req = http.post(format!("{panel}/api/v1/launcher/events")).json(&ev);
|
||||
if let Some(t) = token {
|
||||
req = req.bearer_auth(t);
|
||||
}
|
||||
req.send().await.ok();
|
||||
});
|
||||
// Register the authenticated launch before Quick Play can reach the server.
|
||||
if let Some(recorder) = &activity {
|
||||
recorder.send("launch", &instance_id).await?;
|
||||
}
|
||||
let mut child = launch::spawn(&cmd, installed.java_major, !close_after).context("couldn't start Java")?;
|
||||
|
||||
if close_after {
|
||||
tokio::time::sleep(Duration::from_millis(1500)).await;
|
||||
@@ -288,6 +286,17 @@ pub async fn run(app: AppHandle, instance_id: String, start: bool, deep: bool) -
|
||||
let crashed = !killed && code.is_some_and(|c| c != 0);
|
||||
let crash_report = if crashed { newest_crash_report(&app2, &id2) } else { None };
|
||||
let st = app2.state::<AppState>();
|
||||
crate::telemetry::background(
|
||||
&st,
|
||||
if killed {
|
||||
"game_killed"
|
||||
} else if crashed {
|
||||
"game_crash"
|
||||
} else {
|
||||
"game_exit"
|
||||
},
|
||||
&id2,
|
||||
);
|
||||
*st.game.lock().unwrap() = None;
|
||||
if let Some(w) = app2.get_webview_window("main") {
|
||||
w.show().ok();
|
||||
|
||||
Reference in new issue
Block a user