diff --git a/desktop/.gitmodules b/desktop/.gitmodules index 8468694d..f47083b2 100644 --- a/desktop/.gitmodules +++ b/desktop/.gitmodules @@ -4,3 +4,6 @@ [submodule "src-tauri/tailscale/libtailscale"] path = src-tauri/tailscale/libtailscale url = https://github.com/tailscale/libtailscale.git +[submodule "src-tauri/umu/umu-launcher"] + path = src-tauri/umu/umu-launcher + url = https://github.com/Open-Wine-Components/umu-launcher.git diff --git a/desktop/src-tauri/Cargo.lock b/desktop/src-tauri/Cargo.lock index 74139dbd..549056bf 100644 --- a/desktop/src-tauri/Cargo.lock +++ b/desktop/src-tauri/Cargo.lock @@ -1332,6 +1332,7 @@ dependencies = [ "log", "log4rs", "md5", + "memfd-exec", "native_model", "parking_lot 0.12.3", "rayon", @@ -1571,7 +1572,7 @@ version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "38e2275cc4e4fc009b0669731a1e5ab7ebf11f469eaede2bab9309a5b4d6057f" dependencies = [ - "memoffset", + "memoffset 0.9.1", "rustc_version", ] @@ -2948,6 +2949,16 @@ version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" +[[package]] +name = "memfd-exec" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e627eb44f3789e87dccac3f4c7279a608cbf14ff71f2c54f122f44a07e2ca338" +dependencies = [ + "libc", + "nix 0.26.4", +] + [[package]] name = "memmap" version = "0.7.0" @@ -2967,6 +2978,15 @@ dependencies = [ "libc", ] +[[package]] +name = "memoffset" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4" +dependencies = [ + "autocfg", +] + [[package]] name = "memoffset" version = "0.9.1" @@ -3126,6 +3146,19 @@ version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" +[[package]] +name = "nix" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "598beaf3cc6fdd9a5dfb1630c2800c7acd31df7aaf0f565796fba2b53ca1af1b" +dependencies = [ + "bitflags 1.3.2", + "cfg-if", + "libc", + "memoffset 0.7.1", + "pin-utils", +] + [[package]] name = "nix" version = "0.30.1" @@ -3136,7 +3169,7 @@ dependencies = [ "cfg-if", "cfg_aliases", "libc", - "memoffset", + "memoffset 0.9.1", ] [[package]] @@ -4032,7 +4065,7 @@ dependencies = [ "once_cell", "socket2", "tracing", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -6152,7 +6185,7 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "89daebc3e6fd160ac4aa9fc8b3bf71e1f74fbf92367ae71fb83a037e8bf164b9" dependencies = [ - "memoffset", + "memoffset 0.9.1", "tempfile", "winapi", ] @@ -7314,7 +7347,7 @@ dependencies = [ "futures-core", "futures-lite", "hex 0.4.3", - "nix", + "nix 0.30.1", "ordered-stream", "serde", "serde_repr", diff --git a/desktop/src-tauri/Cargo.toml b/desktop/src-tauri/Cargo.toml index bf29c156..384ee59b 100644 --- a/desktop/src-tauri/Cargo.toml +++ b/desktop/src-tauri/Cargo.toml @@ -57,6 +57,7 @@ droplet-rs = "0.7.3" gethostname = "1.0.1" native_model = { version = "0.6.1", features = ["rmp_serde_1_3"] } tailscale = { path = "./tailscale" } +memfd-exec = "0.2.1" [dependencies.dynfmt] version = "0.1.5" diff --git a/desktop/src-tauri/src/database/db.rs b/desktop/src-tauri/src/database/db.rs index 2a340878..7566519c 100644 --- a/desktop/src-tauri/src/database/db.rs +++ b/desktop/src-tauri/src/database/db.rs @@ -58,12 +58,14 @@ impl DatabaseImpls for DatabaseInterface { let games_base_dir = data_root_dir.join("games"); let logs_root_dir = data_root_dir.join("logs"); let cache_dir = data_root_dir.join("cache"); + let pfx_dir = data_root_dir.join("pfx"); debug!("creating data directory at {:?}", data_root_dir); create_dir_all(data_root_dir.clone()).unwrap(); create_dir_all(&games_base_dir).unwrap(); create_dir_all(&logs_root_dir).unwrap(); create_dir_all(&cache_dir).unwrap(); + create_dir_all(&pfx_dir).unwrap(); let exists = fs::exists(db_path.clone()).unwrap(); diff --git a/desktop/src-tauri/src/database/models.rs b/desktop/src-tauri/src/database/models.rs index 9a25facd..48f79b30 100644 --- a/desktop/src-tauri/src/database/models.rs +++ b/desktop/src-tauri/src/database/models.rs @@ -3,7 +3,7 @@ pub mod data { use serde::{Deserialize, Serialize}; pub type GameVersion = v1::GameVersion; - pub type Database = v1::Database; + pub type Database = v2::Database; pub type Settings = v1::Settings; pub type DatabaseAuth = v1::DatabaseAuth; @@ -11,6 +11,8 @@ pub mod data { pub type ApplicationTransientStatus = v1::ApplicationTransientStatus; pub type DownloadableMetadata = v1::DownloadableMetadata; pub type DownloadType = v1::DownloadType; + pub type DatabaseApplications = v1::DatabaseApplications; + pub type DatabaseCompatInfo = v2::DatabaseCompatInfo; pub mod v1 { use crate::process::process_manager::Platform; @@ -157,8 +159,46 @@ pub mod data { pub prev_database: Option, pub cache_dir: PathBuf, } + } + + pub mod v2 { + use std::{collections::HashMap, io::ErrorKind, path::PathBuf, process::Command}; + + use crate::process::process_manager::UMU_LAUNCHER_EXECUTABLE; + + use super::*; + + #[native_model(id = 1, version = 2)] + #[derive(Serialize, Deserialize, Clone, Default)] + pub struct Database { + #[serde(default)] + pub settings: Settings, + pub auth: Option, + pub base_url: String, + pub applications: DatabaseApplications, + pub prev_database: Option, + pub cache_dir: PathBuf, + pub compat_info: Option, + } + + #[native_model(id = 8, version = 2)] + #[derive(Serialize, Deserialize, Clone, Default)] + + pub struct DatabaseCompatInfo { + umu_installed: bool, + } impl Database { + fn create_new_compat_info() -> Option { + #[cfg(target_os = "windows")] + return None; + + let has_umu_installed = Command::new(UMU_LAUNCHER_EXECUTABLE).spawn().is_ok(); + Some(DatabaseCompatInfo { + umu_installed: has_umu_installed, + }) + } + pub fn new>( games_base_dir: T, prev_database: Option, @@ -177,6 +217,21 @@ pub mod data { auth: None, settings: Settings::default(), cache_dir, + compat_info: Database::create_new_compat_info(), + } + } + } + + impl From for Database { + fn from(value: v1::Database) -> Self { + Self { + settings: value.settings, + auth: value.auth, + base_url: value.base_url, + applications: value.applications, + prev_database: value.prev_database, + cache_dir: value.cache_dir, + compat_info: Database::create_new_compat_info(), } } } diff --git a/desktop/src-tauri/src/lib.rs b/desktop/src-tauri/src/lib.rs index c726cc97..67d25821 100644 --- a/desktop/src-tauri/src/lib.rs +++ b/desktop/src-tauri/src/lib.rs @@ -330,7 +330,7 @@ pub fn run() { ], )?; - TrayIconBuilder::new() + let trayicon_result = TrayIconBuilder::new() .icon(app.default_window_icon().unwrap().clone()) .menu(&menu) .on_menu_event(|app, event| match event.id.as_ref() { @@ -345,8 +345,11 @@ pub fn run() { warn!("menu event not handled: {:?}", event.id); } }) - .build(app) - .expect("error while setting up tray menu"); + .build(app); + + if let Err(trayicon_error) = trayicon_result { + warn!("failed to set up tray icon: {}", trayicon_error.to_string()) + } { let mut db_handle = borrow_db_mut_checked(); diff --git a/desktop/src-tauri/src/process/compat.rs b/desktop/src-tauri/src/process/compat.rs index 2b4f3076..e69de29b 100644 --- a/desktop/src-tauri/src/process/compat.rs +++ b/desktop/src-tauri/src/process/compat.rs @@ -1,13 +0,0 @@ -// Since this code isn't being used, we can either: -// 1. Delete the entire file if compatibility features are not planned -// 2. Or add a TODO comment if planning to implement later - -// Option 1: Delete the file -// Delete src-tauri/src/process/compat.rs - -// Option 2: Add TODO comment -/* -TODO: Compatibility layer for running Windows games on Linux -This module is currently unused but reserved for future implementation -of Windows game compatibility features on Linux. -*/ diff --git a/desktop/src-tauri/src/process/mod.rs b/desktop/src-tauri/src/process/mod.rs index 6a1aed5d..2fc8dfd9 100644 --- a/desktop/src-tauri/src/process/mod.rs +++ b/desktop/src-tauri/src/process/mod.rs @@ -1,3 +1,4 @@ pub mod commands; +#[cfg(target_os = "linux")] pub mod compat; pub mod process_manager; diff --git a/desktop/src-tauri/src/process/process_manager.rs b/desktop/src-tauri/src/process/process_manager.rs index 818aaa08..de98ee66 100644 --- a/desktop/src-tauri/src/process/process_manager.rs +++ b/desktop/src-tauri/src/process/process_manager.rs @@ -358,7 +358,7 @@ impl ProcessHandler for NativeGameLauncher { } } -const UMU_LAUNCHER_EXECUTABLE: &str = "umu-run"; +pub const UMU_LAUNCHER_EXECUTABLE: &str = "umu-run"; struct UMULauncher; impl ProcessHandler for UMULauncher { fn create_launch_process(