From 4e1f76a713c857014f3b5c07f34f57d30f46a3ec Mon Sep 17 00:00:00 2001 From: HorizonCode Date: Tue, 15 Jul 2025 19:38:00 +0200 Subject: [PATCH] feat: add .net 8 detection for experimental patcher stream --- src-tauri/src/commands.rs | 15 +++++++++------ src-tauri/src/lib.rs | 6 ++++-- src-tauri/src/utils.rs | 29 ++++++++++++++++++++++++++--- src-tauri/tauri.conf.json | 2 +- src/lib/osuUtil.ts | 4 +++- src/pages/Launch.svelte | 38 +++++++++++++++++++++++++++++--------- 6 files changed, 72 insertions(+), 22 deletions(-) diff --git a/src-tauri/src/commands.rs b/src-tauri/src/commands.rs index 8acf687..b5213d9 100644 --- a/src-tauri/src/commands.rs +++ b/src-tauri/src/commands.rs @@ -14,7 +14,8 @@ use tokio::time::{Duration, sleep}; use crate::presence; use crate::utils::{ check_folder_completeness, get_osu_config, get_osu_user_config, get_window_title_by_pid, - set_osu_config_vals, set_osu_user_config_vals, is_wmctrl_available, is_osuwinello_available + is_net8_installed, is_osuwinello_available, is_wmctrl_available, set_osu_config_vals, + set_osu_user_config_vals, }; #[tauri::command] @@ -336,10 +337,8 @@ pub async fn run_osu_updater(folder: String) -> Result<(), String> { sleep(Duration::from_millis(500)).await; } - // Wait for updater process to fully exit let _ = updater_process.wait().await; - // Clean up update-related files let force_update_files = [".require_update", "help.txt", "_pending"]; for update_file_name in &force_update_files { let path = PathBuf::from(&folder).join(update_file_name); @@ -435,7 +434,7 @@ pub struct UpdateFile { pub async fn get_ezpp_launcher_update_files( folder: String, update_url: String, - update_stream: String + update_stream: String, ) -> Result<(Vec, Vec), String> { let osu_path = PathBuf::from(folder); let client = Client::new(); @@ -536,7 +535,6 @@ pub async fn download_ezpp_launcher_update_files( .await .map_err(|e| e.to_string())?; - // Emit progress to frontend app.emit( "download-progress", UpdateStatus { @@ -715,4 +713,9 @@ pub fn has_wmctrl() -> bool { #[tauri::command] pub fn has_osuwinello() -> bool { is_osuwinello_available() -} \ No newline at end of file +} + +#[tauri::command] +pub async fn has_net8() -> bool { + is_net8_installed().await +} diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index 28a733a..bdf183e 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -10,7 +10,8 @@ use crate::commands::{ get_osu_release_stream, get_osu_skin, get_osu_version, get_platform, get_skins_count, 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, has_osuwinello, has_wmctrl + run_osu_updater, set_osu_config_values, set_osu_user_config_values, valid_osu_folder, has_osuwinello, has_wmctrl, + has_net8 }; #[cfg_attr(mobile, tauri::mobile_entry_point)] @@ -62,7 +63,8 @@ pub fn run() { presence_update_user, presence_is_connected, has_osuwinello, - has_wmctrl + has_wmctrl, + has_net8 ]) .plugin(tauri_plugin_fs::init()) .plugin(tauri_plugin_dialog::init()) diff --git a/src-tauri/src/utils.rs b/src-tauri/src/utils.rs index 9f8fe77..0d879d0 100644 --- a/src-tauri/src/utils.rs +++ b/src-tauri/src/utils.rs @@ -239,13 +239,13 @@ pub fn get_window_title_by_pid(target_pid: Pid) -> String { #[cfg(windows)] pub fn get_window_title_by_pid(pid: Pid) -> String { + use std::ffi::OsString; + use std::os::windows::ffi::OsStringExt; use std::sync::{Arc, Mutex}; use winapi::shared::windef::HWND; use winapi::um::winuser::{ EnumWindows, GetWindowTextW, GetWindowThreadProcessId, IsWindowVisible, }; - use std::ffi::OsString; - use std::os::windows::ffi::OsStringExt; extern "system" fn enum_windows_proc( hwnd: HWND, @@ -266,7 +266,7 @@ pub fn get_window_title_by_pid(pid: Pid) -> String { let title_str = title.to_string_lossy().into_owned(); if !title_str.is_empty() { *result.lock().unwrap() = Some(title_str); - return 0 + return 0; } } } @@ -284,3 +284,26 @@ pub fn get_window_title_by_pid(pid: Pid) -> String { } result.lock().unwrap().clone().unwrap_or_default() } + +pub async fn is_net8_installed() -> bool { + use std::process::Command; + let output_result = Command::new("dotnet").arg("--list-runtimes").output(); + match output_result { + Ok(output) => { + if !output.status.success() { + eprintln!( + "Error: `dotnet --list-runtimes` failed with status: {}", + output.status + ); + eprintln!("stderr: {}", String::from_utf8_lossy(&output.stderr)); + return false; + } + + let stdout_str = String::from_utf8_lossy(&output.stdout); + stdout_str + .lines() + .any(|line| line.starts_with("Microsoft.WindowsDesktop.App 8.")) + } + Err(_) => false, + } +} diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index 2bb338d..e9a22b9 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -1,7 +1,7 @@ { "$schema": "https://schema.tauri.app/config/2", "productName": "ezpplauncher", - "version": "3.0.0-beta.2", + "version": "3.0.0-beta.5", "identifier": "farm.ezpp.launcher", "build": { "beforeDevCommand": "bun run vite:dev", diff --git a/src/lib/osuUtil.ts b/src/lib/osuUtil.ts index a139199..a998896 100644 --- a/src/lib/osuUtil.ts +++ b/src/lib/osuUtil.ts @@ -136,4 +136,6 @@ export const isOsuCorrupted = async (folder: string) => export const hasWMCTRL = async () => await invoke('has_wmctrl'); export const hasOsuWinello = async () => - await invoke('has_osuwinello'); \ No newline at end of file + await invoke('has_osuwinello'); +export const hasNet8 = async () => + await invoke('has_net8'); \ No newline at end of file diff --git a/src/pages/Launch.svelte b/src/pages/Launch.svelte index 14141ab..321c3c5 100644 --- a/src/pages/Launch.svelte +++ b/src/pages/Launch.svelte @@ -90,6 +90,7 @@ getSkin, getSkinsCount, getVersion, + hasNet8, hasOsuWinello, hasWMCTRL, isOsuCorrupted, @@ -189,20 +190,20 @@ return; } - if($platform === "linux"){ - if(!(await hasWMCTRL())){ + if ($platform === 'linux') { + if (!(await hasWMCTRL())) { toast.error('Hmmm...', { description: 'wmctrl seems to be missing, please install via AUR.', }); launching.set(false); - return; + return; } - if(!(await hasOsuWinello())){ + if (!(await hasOsuWinello())) { toast.error('Hmmm...', { description: 'osu-winello seems to be missing, please install it.', }); launching.set(false); - return; + return; } } @@ -1050,12 +1051,18 @@ >
-
Shows misses in Relax and Autopilot {#if $platform !== "windows"}currently only on windows! {/if}
+
+ Shows misses in Relax and Autopilot {#if $platform !== 'windows'}currently only on windows! + {/if} +
{ patch.set(e); $userSettings.save(); @@ -1168,8 +1175,21 @@
{ + if (newStream === 'experimental' && (await hasNet8())) { + launcherStream.set('stable'); + toast.error('.NET 8.0 Desktop Runtime not found!', { + action: { + label: 'Download .NET 8.0', + onClick: async () => + await openURL( + 'https://dotnet.microsoft.com/en-us/download/dotnet/thank-you/runtime-desktop-8.0.18-windows-x64-installer' + ), + }, + }); + return; + } $userSettings.value('patcherStream').set(newStream); launcherStream.set(newStream); await $userSettings.save();