chore: make updater thread non blocking
This commit is contained in:
parent
67352bfe37
commit
8f7269ba1b
1
src-tauri/Cargo.lock
generated
1
src-tauri/Cargo.lock
generated
@ -1101,6 +1101,7 @@ dependencies = [
|
|||||||
"tauri-plugin-sql",
|
"tauri-plugin-sql",
|
||||||
"tokio",
|
"tokio",
|
||||||
"winapi",
|
"winapi",
|
||||||
|
"windows-sys 0.60.2",
|
||||||
"winreg 0.55.0",
|
"winreg 0.55.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -35,6 +35,7 @@ reqwest = { version = "0.12.22", features = ["json", "stream"] }
|
|||||||
md5 = "0.8.0"
|
md5 = "0.8.0"
|
||||||
tokio = { version = "1.46.0", features = ["full"] }
|
tokio = { version = "1.46.0", features = ["full"] }
|
||||||
open = "5.3.2"
|
open = "5.3.2"
|
||||||
|
windows-sys = "0.60.2"
|
||||||
|
|
||||||
[target.'cfg(not(any(target_os = "android", target_os = "ios")))'.dependencies]
|
[target.'cfg(not(any(target_os = "android", target_os = "ios")))'.dependencies]
|
||||||
tauri-plugin-single-instance = "2.3.0"
|
tauri-plugin-single-instance = "2.3.0"
|
||||||
|
@ -3,14 +3,13 @@ use reqwest::Client;
|
|||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::process::Command;
|
|
||||||
use std::thread;
|
|
||||||
use std::time::Duration;
|
|
||||||
use sysinfo::System;
|
use sysinfo::System;
|
||||||
use tauri::AppHandle;
|
use tauri::AppHandle;
|
||||||
use tauri::Emitter;
|
use tauri::Emitter;
|
||||||
use tokio::fs;
|
use tokio::fs;
|
||||||
use tokio::io::AsyncWriteExt;
|
use tokio::io::AsyncWriteExt;
|
||||||
|
use tokio::process::Command;
|
||||||
|
use tokio::time::{Duration, sleep};
|
||||||
use winreg::RegKey;
|
use winreg::RegKey;
|
||||||
use winreg::enums::*;
|
use winreg::enums::*;
|
||||||
|
|
||||||
@ -18,7 +17,6 @@ use crate::utils::{
|
|||||||
check_folder_completeness, get_osu_config, get_osu_user_config, get_window_title_by_pid,
|
check_folder_completeness, get_osu_config, get_osu_user_config, get_window_title_by_pid,
|
||||||
set_osu_config_vals, set_osu_user_config_vals,
|
set_osu_config_vals, set_osu_user_config_vals,
|
||||||
};
|
};
|
||||||
use std::os::windows::process::CommandExt;
|
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
pub fn get_hwid() -> String {
|
pub fn get_hwid() -> String {
|
||||||
@ -269,110 +267,128 @@ pub fn set_osu_config_values(
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
pub fn run_osu_updater(folder: String) -> Result<(), String> {
|
pub async fn run_osu_updater(folder: String) -> Result<(), String> {
|
||||||
let osu_exe_path = PathBuf::from(folder.clone()).join("osu!.exe");
|
let osu_exe_path = PathBuf::from(&folder).join("osu!.exe");
|
||||||
|
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
const DETACHED_PROCESS: u32 = 0x00000008;
|
const DETACHED_PROCESS: u32 = 0x00000008;
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
const CREATE_NEW_PROCESS_GROUP: u32 = 0x00000200;
|
const CREATE_NEW_PROCESS_GROUP: u32 = 0x00000200;
|
||||||
|
|
||||||
let handle = thread::spawn(move || {
|
let mut updater_process = {
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
let mut updater_process = Command::new(&osu_exe_path)
|
{
|
||||||
|
Command::new(&osu_exe_path)
|
||||||
.arg("-repair")
|
.arg("-repair")
|
||||||
.creation_flags(DETACHED_PROCESS | CREATE_NEW_PROCESS_GROUP)
|
.creation_flags(DETACHED_PROCESS | CREATE_NEW_PROCESS_GROUP)
|
||||||
.spawn()
|
.spawn()
|
||||||
.ok()?; // Ignore error, just exit thread
|
.map_err(|e| format!("Failed to spawn updater: {}", e))?
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(not(windows))]
|
#[cfg(not(windows))]
|
||||||
let mut updater_process = Command::new(&osu_exe_path).arg("-repair").spawn().ok()?; // Ignore error, just exit thread
|
{
|
||||||
|
Command::new(&osu_exe_path)
|
||||||
|
.arg("-repair")
|
||||||
|
.spawn()
|
||||||
|
.map_err(|e| format!("Failed to spawn updater: {}", e))?
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
thread::sleep(Duration::from_millis(500));
|
sleep(Duration::from_millis(500)).await;
|
||||||
|
|
||||||
let mut sys = System::new_all();
|
let mut sys = System::new_all();
|
||||||
|
|
||||||
|
loop {
|
||||||
sys.refresh_processes(sysinfo::ProcessesToUpdate::All, true);
|
sys.refresh_processes(sysinfo::ProcessesToUpdate::All, true);
|
||||||
|
|
||||||
let mut termination_thread_running = true;
|
let mut found = false;
|
||||||
|
|
||||||
while termination_thread_running {
|
for (_pid, process) in sys.processes() {
|
||||||
for (_, process) in sys.processes() {
|
|
||||||
if process.name() == "osu!.exe" {
|
if process.name() == "osu!.exe" {
|
||||||
let process_id = process.pid();
|
let pid = process.pid();
|
||||||
let window_title = get_window_title_by_pid(process_id);
|
let title = get_window_title_by_pid(pid);
|
||||||
|
|
||||||
if !window_title.is_empty() && !window_title.contains("updater") {
|
if !title.is_empty() && !title.contains("updater") {
|
||||||
if let Ok(_) = process.kill_and_wait() {
|
let _ = process.kill_and_wait();
|
||||||
termination_thread_running = false;
|
found = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if !termination_thread_running {
|
if found {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
thread::sleep(Duration::from_millis(500));
|
sleep(Duration::from_millis(500)).await;
|
||||||
sys.refresh_processes(sysinfo::ProcessesToUpdate::All, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let _ = updater_process.wait();
|
// 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"];
|
let force_update_files = [".require_update", "help.txt", "_pending"];
|
||||||
|
|
||||||
for update_file_name in &force_update_files {
|
for update_file_name in &force_update_files {
|
||||||
let update_file = PathBuf::from(&folder).join(update_file_name);
|
let path = PathBuf::from(&folder).join(update_file_name);
|
||||||
if update_file.exists() {
|
if path.exists() {
|
||||||
let metadata = std::fs::symlink_metadata(&update_file);
|
match std::fs::symlink_metadata(&path) {
|
||||||
if let Ok(meta) = metadata {
|
Ok(meta) => {
|
||||||
let result = if meta.is_dir() {
|
let res = if meta.is_dir() {
|
||||||
std::fs::remove_dir_all(&update_file)
|
std::fs::remove_dir_all(&path)
|
||||||
} else {
|
} else {
|
||||||
std::fs::remove_file(&update_file)
|
std::fs::remove_file(&path)
|
||||||
};
|
};
|
||||||
if let Err(e) = result {
|
|
||||||
eprintln!(
|
if let Err(e) = res {
|
||||||
"Failed to remove force update file {:?}: {}",
|
eprintln!("Failed to remove {:?}: {}", path, e);
|
||||||
update_file, e
|
}
|
||||||
);
|
}
|
||||||
|
Err(e) => {
|
||||||
|
eprintln!("Could not stat {:?}: {}", path, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Some(())
|
|
||||||
});
|
|
||||||
|
|
||||||
handle.join().map_err(|_| "Thread panicked".to_string())?;
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
pub fn run_osu(folder: String, patch: bool) -> Result<(), String> {
|
pub async fn run_osu(folder: String, patch: bool) -> Result<(), String> {
|
||||||
|
/* #[cfg(windows)]
|
||||||
|
use std::os::windows::process::CommandExt; */
|
||||||
|
|
||||||
let osu_exe_path = PathBuf::from(&folder).join("osu!.exe");
|
let osu_exe_path = PathBuf::from(&folder).join("osu!.exe");
|
||||||
|
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
const DETACHED_PROCESS: u32 = 0x00000008;
|
const DETACHED_PROCESS: u32 = 0x00000008;
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
const CREATE_NEW_PROCESS_GROUP: u32 = 0x00000200;
|
const CREATE_NEW_PROCESS_GROUP: u32 = 0x00000200;
|
||||||
|
|
||||||
|
let mut game_process = {
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
let mut game_process = Command::new(osu_exe_path)
|
{
|
||||||
.creation_flags(DETACHED_PROCESS | CREATE_NEW_PROCESS_GROUP)
|
Command::new(&osu_exe_path)
|
||||||
.arg("-devserver")
|
.arg("-devserver")
|
||||||
.arg("ez-pp.farm")
|
.arg("ez-pp.farm")
|
||||||
|
.creation_flags(DETACHED_PROCESS | CREATE_NEW_PROCESS_GROUP)
|
||||||
.spawn()
|
.spawn()
|
||||||
.map_err(|e| e.to_string())?;
|
.map_err(|e| format!("Failed to spawn updater: {}", e))?
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(not(windows))]
|
#[cfg(not(windows))]
|
||||||
let mut game_process = Command::new(osu_exe_path)
|
{
|
||||||
|
Command::new(&osu_exe_path)
|
||||||
.arg("-devserver")
|
.arg("-devserver")
|
||||||
.arg("ez-pp.farm")
|
.arg("ez-pp.farm")
|
||||||
.spawn()
|
.spawn()
|
||||||
.map_err(|e| e.to_string())?;
|
.map_err(|e| format!("Failed to spawn updater: {}", e))?
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
if patch {
|
if patch {
|
||||||
thread::sleep(Duration::from_secs(3));
|
sleep(Duration::from_secs(3)).await;
|
||||||
|
|
||||||
let patcher_exe_path = PathBuf::from(&folder)
|
let patcher_exe_path = PathBuf::from(&folder)
|
||||||
.join("EZPPLauncher")
|
.join("EZPPLauncher")
|
||||||
.join("patcher")
|
.join("patcher")
|
||||||
@ -396,8 +412,7 @@ pub fn run_osu(folder: String, patch: bool) -> Result<(), String> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
game_process.wait().map_err(|e| e.to_string())?;
|
game_process.wait().await.map_err(|e| e.to_string())?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user