From 084e006f06a64fbc3ffd18d3efb0ea5a8cc78582 Mon Sep 17 00:00:00 2001 From: HorizonCode Date: Wed, 30 Jul 2025 20:26:05 +0200 Subject: [PATCH] chore: add inline updater --- src-tauri/Cargo.lock | 124 ++++++++++++++++---------------------- src-tauri/Cargo.toml | 2 +- src-tauri/nsis-hooks.nsh | 6 ++ src-tauri/src/commands.rs | 77 +++++++++++++++++++++++ src-tauri/src/lib.rs | 13 ++-- src-tauri/tauri.conf.json | 6 +- src/lib/osuUtil.ts | 14 +++++ src/screens/Launch.svelte | 51 +++++++++++++--- 8 files changed, 206 insertions(+), 87 deletions(-) create mode 100644 src-tauri/nsis-hooks.nsh diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index 98040dd..0c4568c 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -134,7 +134,7 @@ dependencies = [ "futures-lite", "parking", "polling", - "rustix 1.0.8", + "rustix", "slab", "windows-sys 0.60.2", ] @@ -165,7 +165,7 @@ dependencies = [ "cfg-if", "event-listener", "futures-lite", - "rustix 1.0.8", + "rustix", ] [[package]] @@ -191,7 +191,7 @@ dependencies = [ "cfg-if", "futures-core", "futures-io", - "rustix 1.0.8", + "rustix", "signal-hook-registry", "slab", "windows-sys 0.60.2", @@ -438,12 +438,12 @@ dependencies = [ [[package]] name = "cargo_toml" -version = "0.22.1" +version = "0.22.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02260d489095346e5cafd04dea8e8cb54d1d74fcd759022a9b72986ebe9a1257" +checksum = "374b7c592d9c00c1f4972ea58390ac6b18cbb6ab79011f3bdc90a0b82ca06b77" dependencies = [ "serde", - "toml 0.8.23", + "toml 0.9.4", ] [[package]] @@ -901,9 +901,9 @@ checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" [[package]] name = "dyn-clone" -version = "1.0.19" +version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c7a8fb8a9fbf66c1f703fe16184d10ca0ee9d23be5b4436400408ba54a95005" +checksum = "d0881ea181b1df73ff77ffaaf9c7544ecc11e82fba9b5f27b262a3c73a332555" [[package]] name = "embed-resource" @@ -914,7 +914,7 @@ dependencies = [ "cc", "memchr", "rustc_version", - "toml 0.9.2", + "toml 0.9.4", "vswhom", "winreg 0.55.0", ] @@ -1010,7 +1010,7 @@ dependencies = [ [[package]] name = "ezpplauncher" -version = "3.0.3" +version = "3.0.2" dependencies = [ "base64 0.22.1", "discord-rich-presence", @@ -2113,25 +2113,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "07033963ba89ebaf1584d767badaa2e8fcec21aedea6b8c0346d487d49c28667" dependencies = [ "cfg-if", - "windows-targets 0.53.2", + "windows-targets 0.53.3", ] [[package]] name = "libredox" -version = "0.1.6" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4488594b9328dee448adb906d8b126d9b7deb7cf5c22161ee591610bb1be83c0" +checksum = "360e552c93fa0e8152ab463bc4c4837fce76a225df11dfaeea66c313de5e61f7" dependencies = [ "bitflags 2.9.1", "libc", ] -[[package]] -name = "linux-raw-sys" -version = "0.4.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" - [[package]] name = "linux-raw-sys" version = "0.9.4" @@ -2146,9 +2140,9 @@ checksum = "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956" [[package]] name = "litrs" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4ce301924b7887e9d637144fdade93f9dfff9b60981d4ac161db09720d39aa5" +checksum = "f5e54036fe321fd421e10d732f155734c4e4afd610dd556d9a82833ab3ee0bed" [[package]] name = "lock_api" @@ -2259,9 +2253,9 @@ dependencies = [ [[package]] name = "muda" -version = "0.17.0" +version = "0.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58b89bf91c19bf036347f1ab85a81c560f08c0667c8601bece664d860a600988" +checksum = "01c1738382f66ed56b3b9c8119e794a2e23148ac8ea214eda86622d4cb9d415a" dependencies = [ "crossbeam-channel", "dpi", @@ -2275,7 +2269,7 @@ dependencies = [ "png", "serde", "thiserror 2.0.12", - "windows-sys 0.59.0", + "windows-sys 0.60.2", ] [[package]] @@ -2982,7 +2976,7 @@ dependencies = [ "concurrent-queue", "hermit-abi", "pin-project-lite", - "rustix 1.0.8", + "rustix", "windows-sys 0.60.2", ] @@ -3305,9 +3299,9 @@ checksum = "20675572f6f24e9e76ef639bc5552774ed45f1c30e2951e1e99c59888861c539" [[package]] name = "redox_syscall" -version = "0.5.15" +version = "0.5.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e8af0dde094006011e6a740d4879319439489813bd0bcdc7d821beaeeff48ec" +checksum = "5407465600fb0548f1442edf71dd20683c6ed326200ace4b1ef0763521bb3b77" dependencies = [ "bitflags 2.9.1", ] @@ -3462,9 +3456,9 @@ dependencies = [ [[package]] name = "rustc-demangle" -version = "0.1.25" +version = "0.1.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "989e6739f80c4ad5b13e0fd7fe89531180375b18520cc8c82080e4dc4035b84f" +checksum = "56f7d92ca342cea22a06f2121d944b4fd82af56988c270852495420f961d4ace" [[package]] name = "rustc-hash" @@ -3481,19 +3475,6 @@ dependencies = [ "semver", ] -[[package]] -name = "rustix" -version = "0.38.44" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" -dependencies = [ - "bitflags 2.9.1", - "errno", - "libc", - "linux-raw-sys 0.4.15", - "windows-sys 0.59.0", -] - [[package]] name = "rustix" version = "1.0.8" @@ -3503,15 +3484,15 @@ dependencies = [ "bitflags 2.9.1", "errno", "libc", - "linux-raw-sys 0.9.4", + "linux-raw-sys", "windows-sys 0.60.2", ] [[package]] name = "rustls" -version = "0.23.29" +version = "0.23.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2491382039b29b9b11ff08b76ff6c97cf287671dbb74f0be44bda389fffe9bd1" +checksum = "c0ebcbd2f03de0fc1122ad9bb24b127a5a6cd51d72604a3f3c50ac459762b6cc" dependencies = [ "once_cell", "ring", @@ -4356,9 +4337,9 @@ dependencies = [ [[package]] name = "tauri-plugin-dialog" -version = "2.3.1" +version = "2.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05bedd4c3cf6f7aa97918a8814a736bd3695c9ddf3ede2d50eda6069c3290edc" +checksum = "37e5858cc7b455a73ab4ea2ebc08b5be33682c00ff1bf4cad5537d4fb62499d9" dependencies = [ "log", "raw-window-handle", @@ -4537,7 +4518,7 @@ dependencies = [ "fastrand", "getrandom 0.3.3", "once_cell", - "rustix 1.0.8", + "rustix", "windows-sys 0.59.0", ] @@ -4650,9 +4631,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.46.1" +version = "1.47.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0cc3a2344dafbe23a245241fe8b09735b521110d30fcefbbd5feb1797ca35d17" +checksum = "43864ed400b6043a4757a25c7a64a8efde741aed79a056a2fb348a406701bb35" dependencies = [ "backtrace", "bytes", @@ -4663,10 +4644,10 @@ dependencies = [ "pin-project-lite", "signal-hook-registry", "slab", - "socket2 0.5.10", + "socket2 0.6.0", "tokio-macros", "tracing", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -4727,9 +4708,9 @@ dependencies = [ [[package]] name = "toml" -version = "0.9.2" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed0aee96c12fa71097902e0bb061a5e1ebd766a6636bb605ba401c45c1650eac" +checksum = "41ae868b5a0f67631c14589f7e250c1ea2c574ee5ba21c6c8dd4b1485705a5a1" dependencies = [ "indexmap 2.10.0", "serde", @@ -4893,9 +4874,9 @@ dependencies = [ [[package]] name = "tray-icon" -version = "0.21.0" +version = "0.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2da75ec677957aa21f6e0b361df0daab972f13a5bee3606de0638fd4ee1c666a" +checksum = "a0d92153331e7d02ec09137538996a7786fe679c629c279e82a6be762b7e6fe2" dependencies = [ "crossbeam-channel", "dirs", @@ -5222,13 +5203,13 @@ dependencies = [ [[package]] name = "wayland-backend" -version = "0.3.10" +version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe770181423e5fc79d3e2a7f4410b7799d5aab1de4372853de3c6aa13ca24121" +checksum = "673a33c33048a5ade91a6b139580fa174e19fb0d23f396dca9fa15f2e1e49b35" dependencies = [ "cc", "downcast-rs", - "rustix 0.38.44", + "rustix", "scoped-tls", "smallvec", "wayland-sys", @@ -5236,21 +5217,21 @@ dependencies = [ [[package]] name = "wayland-client" -version = "0.31.10" +version = "0.31.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "978fa7c67b0847dbd6a9f350ca2569174974cd4082737054dbb7fbb79d7d9a61" +checksum = "c66a47e840dc20793f2264eb4b3e4ecb4b75d91c0dd4af04b456128e0bdd449d" dependencies = [ "bitflags 2.9.1", - "rustix 0.38.44", + "rustix", "wayland-backend", "wayland-scanner", ] [[package]] name = "wayland-protocols" -version = "0.32.8" +version = "0.32.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "779075454e1e9a521794fed15886323ea0feda3f8b0fc1390f5398141310422a" +checksum = "efa790ed75fbfd71283bd2521a1cfdc022aabcc28bdcff00851f9e4ae88d9901" dependencies = [ "bitflags 2.9.1", "wayland-backend", @@ -5260,9 +5241,9 @@ dependencies = [ [[package]] name = "wayland-scanner" -version = "0.31.6" +version = "0.31.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "896fdafd5d28145fce7958917d69f2fd44469b1d4e861cb5961bcbeebc6d1484" +checksum = "54cb1e9dc49da91950bdfd8b848c49330536d9d1fb03d4bfec8cae50caa50ae3" dependencies = [ "proc-macro2", "quick-xml 0.37.5", @@ -5271,9 +5252,9 @@ dependencies = [ [[package]] name = "wayland-sys" -version = "0.31.6" +version = "0.31.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbcebb399c77d5aa9fa5db874806ee7b4eba4e73650948e8f93963f128896615" +checksum = "34949b42822155826b41db8e5d0c1be3a2bd296c747577a43a3e6daefc296142" dependencies = [ "dlib", "log", @@ -5587,7 +5568,7 @@ version = "0.60.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" dependencies = [ - "windows-targets 0.53.2", + "windows-targets 0.53.3", ] [[package]] @@ -5623,10 +5604,11 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.53.2" +version = "0.53.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c66f69fcc9ce11da9966ddb31a40968cad001c5bedeb5c2b82ede4253ab48aef" +checksum = "d5fe6031c4041849d7c496a8ded650796e7b6ecc19df1a431c1a363342e5dc91" dependencies = [ + "windows-link", "windows_aarch64_gnullvm 0.53.0", "windows_aarch64_msvc 0.53.0", "windows_i686_gnu 0.53.0", diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index 3ad4077..1cca1ee 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ezpplauncher" -version = "3.0.3" +version = "3.0.2" description = "EZPPLauncher redefined." authors = ["HorizonCode"] edition = "2024" diff --git a/src-tauri/nsis-hooks.nsh b/src-tauri/nsis-hooks.nsh new file mode 100644 index 0000000..bd185fb --- /dev/null +++ b/src-tauri/nsis-hooks.nsh @@ -0,0 +1,6 @@ +!macro NSIS_HOOK_POSTINSTALL + ${If} $PassiveMode = 1 + ${OrIf} ${Silent} + Exec '"$INSTDIR\${MAINBINARYNAME}.exe"' + ${EndIf} +!macroend \ No newline at end of file diff --git a/src-tauri/src/commands.rs b/src-tauri/src/commands.rs index f8d9fa0..8f95a22 100644 --- a/src-tauri/src/commands.rs +++ b/src-tauri/src/commands.rs @@ -6,6 +6,7 @@ use std::path::PathBuf; use sysinfo::System; use tauri::AppHandle; use tauri::Emitter; +use tauri::Manager; use tokio::fs; use tokio::io::AsyncWriteExt; use tokio::process::Command; @@ -729,3 +730,79 @@ pub fn encrypt_string(string: String, entropy: String) -> String { Err(_) => string, } } + +#[tauri::command] +pub async fn download_ezpp_launcher_update(app: AppHandle, url: String) -> Result<(), String> { + let client = Client::new(); + + let mut response = client.get(&url).send().await.map_err(|e| e.to_string())?; + + if !response.status().is_success() { + return Err(format!("Failed to download update: {}", response.status())); + } + + let temp_dir = app.path().temp_dir().expect("Failed to get temp directory"); + let file_path = temp_dir.join("ezpplauncher_update.exe"); + + let mut file_out = fs::File::create(&file_path) + .await + .map_err(|e| e.to_string())?; + let mut downloaded = 0u64; + let size = response + .content_length() + .ok_or("Failed to get content length")? as usize; + + while let Some(chunk) = response.chunk().await.map_err(|e| e.to_string())? { + downloaded += chunk.len() as u64; + file_out + .write_all(&chunk) + .await + .map_err(|e| e.to_string())?; + + app.emit( + "download-progress", + UpdateStatus { + file_name: "Update".to_string(), + downloaded, + size: size, + progress: ((downloaded as f64 / size as f64 * 100.0) * 100.0).trunc() / 100.0, + }, + ) + .unwrap_or_default(); + } + + Ok(()) +} + +#[cfg(windows)] +#[tauri::command] +pub async fn install_ezpp_launcher_update(app: AppHandle) -> Result<(), String> { + let temp_dir = app.path().temp_dir().expect("Failed to get temp directory"); + let file_path = temp_dir.join("ezpplauncher_update.exe"); + if !file_path.exists() { + return Err("Update file does not exist".to_string()); + } + + // run this app detached and exit + + const DETACHED_PROCESS: u32 = 0x00000008; + const CREATE_NEW_PROCESS_GROUP: u32 = 0x00000200; + + Command::new(&file_path) + .arg("/QN") + .creation_flags(DETACHED_PROCESS | CREATE_NEW_PROCESS_GROUP) + .spawn() + .map_err(|e| format!("Failed to spawn updater: {}", e))?; + + sleep(Duration::from_millis(250)).await; + + app.exit(0x0100); + + Ok(()) +} + +#[cfg(not(windows))] +#[tauri::command] +pub async fn install_ezpp_launcher_update(_app: AppHandle) -> Result<(), String> { + Ok(()) +} diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index 1b7b39a..3f4d845 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -5,10 +5,11 @@ pub mod commands; pub mod presence; pub mod utils; use crate::commands::{ - check_for_corruption, download_ezpp_launcher_update_files, encrypt_string, exit, - find_osu_installation, get_beatmapsets_count, get_ezpp_launcher_update_files, get_hwid, - get_launcher_version, get_osu_release_stream, get_osu_skin, get_osu_version, get_platform, - get_skins_count, has_net8, has_osuwinello, has_wmctrl, is_osu_running, open_url_in_browser, + check_for_corruption, download_ezpp_launcher_update, download_ezpp_launcher_update_files, + encrypt_string, exit, find_osu_installation, get_beatmapsets_count, + get_ezpp_launcher_update_files, get_hwid, get_launcher_version, get_osu_release_stream, + get_osu_skin, get_osu_version, get_platform, get_skins_count, has_net8, has_osuwinello, + has_wmctrl, install_ezpp_launcher_update, is_osu_running, open_url_in_browser, presence_connect, presence_disconnect, presence_is_connected, presence_update_status, presence_update_user, replace_ui_files, run_osu, run_osu_updater, set_osu_config_values, set_osu_user_config_values, valid_osu_folder, @@ -61,7 +62,9 @@ pub fn run() { has_osuwinello, has_wmctrl, has_net8, - encrypt_string + encrypt_string, + download_ezpp_launcher_update, + install_ezpp_launcher_update ]) .plugin(tauri_plugin_fs::init()) .plugin(tauri_plugin_dialog::init()) diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index e0226a2..b2abe21 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -2,7 +2,8 @@ "$schema": "https://schema.tauri.app/config/2", "productName": "EZPPLauncher", "version": "3.0.3", - "identifier": "farm.ezpp.launcher", + "identifier": "farm.EZPPFarm.Launcher", + "mainBinaryName": "ezpplauncher", "build": { "beforeDevCommand": "bun run vite:dev", "devUrl": "http://localhost:1420", @@ -41,7 +42,8 @@ }, "nsis": { "installMode": "currentUser", - "compression": "lzma" + "compression": "lzma", + "installerHooks": "./nsis-hooks.nsh" } }, "icon": [ diff --git a/src/lib/osuUtil.ts b/src/lib/osuUtil.ts index 043904c..33bf770 100644 --- a/src/lib/osuUtil.ts +++ b/src/lib/osuUtil.ts @@ -138,3 +138,17 @@ export const hasOsuWinello = async () => await invoke('has_osuwinello') export const hasNet8 = async () => await invoke('has_net8'); export const encryptString = async (str: string, entropy: string) => await invoke('encrypt_string', { string: str, entropy }); +export const downloadUpdate = async ( + url: string, + progressCallback: (file: UpdateStatus) => void +) => { + const downloadStatusListen = await listen('download-progress', (event) => + progressCallback(event.payload as UpdateStatus) + ); + try { + await invoke('download_ezpp_launcher_update', { url }); + } finally { + downloadStatusListen(); + } +}; +export const installUpdate = async () => await invoke('install_ezpp_launcher_update'); diff --git a/src/screens/Launch.svelte b/src/screens/Launch.svelte index ccd71f3..d6a0459 100644 --- a/src/screens/Launch.svelte +++ b/src/screens/Launch.svelte @@ -83,6 +83,7 @@ import { osuapi } from '@/api/osuapi'; import { downloadEZPPLauncherUpdateFiles, + downloadUpdate, encryptString, exit, getBeatmapSetsCount, @@ -94,6 +95,7 @@ hasNet8, hasOsuWinello, hasWMCTRL, + installUpdate, isOsuCorrupted, isOsuRunning, isValidOsuFolder, @@ -114,6 +116,8 @@ let launchInfo = $state(''); let launchError = $state(undefined); + let downloadingUpdate = $state(false); + let selectedGamemode = $derived( getGamemodeInt(modeIntToStr($preferredMode), typeIntToStr($preferredType)) ); @@ -577,14 +581,45 @@
- + {#if $platform === 'windows'} + {#if downloadingUpdate} +
+ + {launchInfo} +
+ {:else} + + {/if} + {:else} + + {/if}