diff options
| author | SulfurNitride <SulfurNitride@users.noreply.github.com> | 2026-04-08 03:30:04 -0500 |
|---|---|---|
| committer | SulfurNitride <SulfurNitride@users.noreply.github.com> | 2026-04-08 03:30:04 -0500 |
| commit | 3de4056df4ea5d0afbcea388ad8d681daea1aac3 (patch) | |
| tree | fc5978451f9f51b84268f45bd2fa6f5d4a17baaf /libs/nak/src/steam/proton.rs | |
| parent | 5ba23a6d7a40052d9e1d4bd0cf018cfe7814d03a (diff) | |
Remove NaK/Rust dependency, port remaining functionality to native C++
Replace NaK Rust crate and nak_ffi with native C++ implementations:
- Game detection (Steam, Heroic, Bottles), VDF parser, icon extraction
- Prefix symlinks, SLR manager, Steam path detection
- Known games database
Add FUSE VFS optimizations: zero-copy reads via fuse_reply_data,
default_permissions mount option, FUSE_CAP_ASYNC_DIO, FUSE_CAP_EXPIRE_ONLY,
lookup cache parent index, cached mode bits, increased I/O buffer sizes.
Update build system, prefix setup, and various fixes.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Diffstat (limited to 'libs/nak/src/steam/proton.rs')
| -rw-r--r-- | libs/nak/src/steam/proton.rs | 252 |
1 files changed, 0 insertions, 252 deletions
diff --git a/libs/nak/src/steam/proton.rs b/libs/nak/src/steam/proton.rs deleted file mode 100644 index 4059dc4..0000000 --- a/libs/nak/src/steam/proton.rs +++ /dev/null @@ -1,252 +0,0 @@ -//! Steam Proton detection and management -//! -//! Finds Protons that Steam can see and use for non-Steam games. -//! This includes Steam's built-in Protons and custom Protons in compatibilitytools.d. - -use std::fs; -use std::path::PathBuf; - -use super::find_steam_path; - -/// Information about an installed Proton version -#[derive(Debug, Clone)] -pub struct SteamProton { - /// Display name (e.g., "GE-Proton9-20", "Proton Experimental") - pub name: String, - /// Internal name used in config.vdf (e.g., "proton_experimental", "GE-Proton9-20") - pub config_name: String, - /// Full path to the Proton installation - pub path: PathBuf, - /// Whether this is a Steam-provided Proton (vs custom) - pub is_steam_proton: bool, - /// Whether this is Proton Experimental - pub is_experimental: bool, -} - -impl SteamProton { - /// Get the path to the wine binary. - pub fn wine_binary(&self) -> Option<PathBuf> { - let paths = [ - self.path.join("files/bin/wine"), - self.path.join("dist/bin/wine"), - ]; - paths.into_iter().find(|p| p.exists()) - } - - /// Get the path to the wineserver binary. - pub fn wineserver_binary(&self) -> Option<PathBuf> { - let paths = [ - self.path.join("files/bin/wineserver"), - self.path.join("dist/bin/wineserver"), - ]; - paths.into_iter().find(|p| p.exists()) - } - - /// Get the bin directory containing wine executables. - pub fn bin_dir(&self) -> Option<PathBuf> { - self.wine_binary().and_then(|p| p.parent().map(|p| p.to_path_buf())) - } -} - -/// Find all Protons that Steam can use (Proton 10+ only) -pub fn find_steam_protons() -> Vec<SteamProton> { - let mut protons = Vec::new(); - - let Some(steam_path) = find_steam_path() else { - return protons; - }; - - // 1. Steam's built-in Protons (steamapps/common/Proton*) - protons.extend(find_builtin_protons(&steam_path)); - - // 2. Custom Protons in user's compatibilitytools.d - protons.extend(find_custom_protons(&steam_path)); - - // 3. System-level Protons in /usr/share/steam/compatibilitytools.d/ - // (Arch packages Proton here; Flatpak has --filesystem=/usr/share/steam:ro) - protons.extend(find_system_protons()); - - // Filter to only include Proton 10+ (required for Steam-native integration) - protons.retain(is_proton_10_or_newer); - - // Filter to only include Protons with valid wine binaries - protons.retain(|p| { - let has_wine = p.wine_binary().is_some(); - if !has_wine { - crate::logging::log_warning(&format!( - "Skipping Proton '{}': wine binary not found at expected paths (files/bin/wine or dist/bin/wine)", - p.name - )); - } - has_wine - }); - - // Sort: Experimental first, then by name descending (newest first) - protons.sort_by(|a, b| { - if a.is_experimental != b.is_experimental { - return b.is_experimental.cmp(&a.is_experimental); - } - b.name.cmp(&a.name) - }); - - protons -} - -/// Check if a Proton version is 10 or newer -fn is_proton_10_or_newer(proton: &SteamProton) -> bool { - let name = &proton.name; - - if proton.is_experimental || name.contains("Experimental") { - return true; - } - - if name.contains("CachyOS") { - return true; - } - - if name == "LegacyRuntime" || name.contains("Runtime") { - return false; - } - - if name.starts_with("GE-Proton") { - if let Some(version_part) = name.strip_prefix("GE-Proton") { - let major: Option<u32> = version_part - .split('-') - .next() - .and_then(|s| s.parse().ok()); - return major.map(|v| v >= 10).unwrap_or(false); - } - } - - if name.starts_with("Proton ") { - if let Some(version_part) = name.strip_prefix("Proton ") { - let major: Option<u32> = version_part - .split('.') - .next() - .and_then(|s| s.parse().ok()); - return major.map(|v| v >= 10).unwrap_or(false); - } - } - - if name.starts_with("EM-") { - if let Some(version_part) = name.strip_prefix("EM-") { - let major: Option<u32> = version_part - .split('.') - .next() - .and_then(|s| s.parse().ok()); - return major.map(|v| v >= 10).unwrap_or(false); - } - } - - // Unknown format - allow it - true -} - -/// Find Steam's built-in Proton versions -fn find_builtin_protons(steam_path: &std::path::Path) -> Vec<SteamProton> { - let mut found = Vec::new(); - let common_dir = steam_path.join("steamapps/common"); - - let Ok(entries) = fs::read_dir(&common_dir) else { - return found; - }; - - for entry in entries.flatten() { - let path = entry.path(); - if !path.is_dir() { - continue; - } - - let name = entry.file_name().to_string_lossy().to_string(); - - if name.starts_with("Proton") && path.join("proton").exists() { - let is_experimental = name.contains("Experimental"); - - let config_name = if is_experimental { - "proton_experimental".to_string() - } else { - let version = name.replace("Proton ", ""); - let major = version.split('.').next().unwrap_or(&version); - format!("proton_{}", major) - }; - - found.push(SteamProton { - name: name.clone(), - config_name, - path, - is_steam_proton: true, - is_experimental, - }); - } - } - - found -} - -/// Find custom Protons in compatibilitytools.d -fn find_custom_protons(steam_path: &std::path::Path) -> Vec<SteamProton> { - let mut found = Vec::new(); - let compat_dir = steam_path.join("compatibilitytools.d"); - - let Ok(entries) = fs::read_dir(&compat_dir) else { - return found; - }; - - for entry in entries.flatten() { - let path = entry.path(); - if !path.is_dir() { - continue; - } - - let name = entry.file_name().to_string_lossy().to_string(); - - let has_proton = path.join("proton").exists(); - let has_vdf = path.join("compatibilitytool.vdf").exists(); - - if has_proton || has_vdf { - found.push(SteamProton { - name: name.clone(), - config_name: name.clone(), - path, - is_steam_proton: false, - is_experimental: false, - }); - } - } - - found -} - -/// Find system-level Protons in /usr/share/steam/compatibilitytools.d/ -fn find_system_protons() -> Vec<SteamProton> { - let mut found = Vec::new(); - let system_compat_dir = PathBuf::from("/usr/share/steam/compatibilitytools.d"); - - let Ok(entries) = fs::read_dir(&system_compat_dir) else { - return found; - }; - - for entry in entries.flatten() { - let path = entry.path(); - if !path.is_dir() { - continue; - } - - let name = entry.file_name().to_string_lossy().to_string(); - - let has_proton = path.join("proton").exists(); - let has_vdf = path.join("compatibilitytool.vdf").exists(); - - if has_proton || has_vdf { - found.push(SteamProton { - name: name.clone(), - config_name: name.clone(), - path, - is_steam_proton: false, - is_experimental: false, - }); - } - } - - found -} |
