Add Tauri launcher with Svelte UI

- Accounts: panel login/sign-up, Microsoft device-code sign-in, offline
  play; tokens encrypted with a key kept in the OS credential store
- Home: instance rail, live server status, news feed, social links,
  Play button with download progress, speed and ETA
- Full settings: accounts, memory/resolution/after-launch behaviour,
  Java and GC presets, Minecraft keybind editor applied to options.txt,
  theme overrides, storage manager, self-update via GitHub releases
- Game console, crash dialog with hints, per-instance overrides
- Live admin branding (colours, fonts, backgrounds, custom CSS)
- Online install tests for vanilla/Fabric/Quilt/Forge/NeoForge (CI)

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 05:00:30 +00:00
1 parent af9147ec75
commit 50eb1a0cac
60 files changed
+9424 -47

No files matched your search

+78
View File
@@ -0,0 +1,78 @@
//! ScopeNet launcher (Tauri shell). The heavy lifting lives in
//! `scopenet-core`; this crate wires it to the UI.
mod accounts;
mod commands;
mod game;
mod secrets;
mod settings;
mod state;
mod updater;
use tauri::Manager;
pub fn run() {
tracing_subscriber::fmt()
.with_env_filter(tracing_subscriber::EnvFilter::try_from_default_env().unwrap_or_else(|_| "info".into()))
.init();
tauri::Builder::default()
// A second launch just focuses the existing window.
.plugin(tauri_plugin_single_instance::init(|app, _args, _cwd| {
if let Some(w) = app.get_webview_window("main") {
w.show().ok();
w.unminimize().ok();
w.set_focus().ok();
}
}))
.plugin(tauri_plugin_dialog::init())
.plugin(tauri_plugin_opener::init())
.setup(|app| {
let data_dir = app.path().app_data_dir()?;
app.manage(state::AppState::new(data_dir));
// The window starts hidden and the UI reveals it once painted (no
// white flash). If the UI never does, show it anyway.
let handle = app.handle().clone();
std::thread::spawn(move || {
std::thread::sleep(std::time::Duration::from_secs(4));
if let Some(w) = handle.get_webview_window("main") {
if !w.is_visible().unwrap_or(true) {
tracing::warn!("UI didn't signal ready; showing window");
w.show().ok();
}
}
});
Ok(())
})
.invoke_handler(tauri::generate_handler![
commands::bootstrap,
commands::refresh_manifest,
commands::set_panel_url,
commands::save_settings,
commands::login_panel,
commands::register_panel,
commands::add_offline,
commands::ms_start,
commands::ms_finish,
commands::ms_cancel,
commands::select_account,
commands::remove_account,
commands::launch,
commands::repair_instance,
commands::cancel_launch,
commands::kill_game,
commands::instance_local,
commands::ping_server,
commands::open_folder,
commands::open_file,
commands::storage_info,
commands::delete_instance_data,
commands::clear_cache,
commands::detect_java,
commands::check_update,
commands::install_update,
commands::show_window,
])
.run(tauri::generate_context!())
.expect("error while running the launcher");
}