summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--py_modules/lsfg_vk/dll_detection.py120
1 files changed, 119 insertions, 1 deletions
diff --git a/py_modules/lsfg_vk/dll_detection.py b/py_modules/lsfg_vk/dll_detection.py
index f1dace9..e547405 100644
--- a/py_modules/lsfg_vk/dll_detection.py
+++ b/py_modules/lsfg_vk/dll_detection.py
@@ -3,8 +3,9 @@ DLL detection service for Lossless Scaling.
"""
import os
+import re
from pathlib import Path
-from typing import Dict, Any
+from typing import Dict, Any, List
from .base_service import BaseService
from .constants import (
@@ -20,6 +21,12 @@ class DllDetectionService(BaseService):
def check_lossless_scaling_dll(self) -> DllDetectionResponse:
"""Check if Lossless Scaling DLL is available at the expected paths
+ Search order:
+ 1. LSFG_DLL_PATH environment variable
+ 2. XDG_DATA_HOME Steam directory
+ 3. HOME/.local/share Steam directory
+ 4. All Steam library folders (including SD cards)
+
Returns:
DllDetectionResponse with detection status and path information
"""
@@ -39,6 +46,11 @@ class DllDetectionService(BaseService):
if home_path:
return home_path
+ # Check all Steam library folders (including SD cards)
+ steam_libraries_path = self._check_steam_library_folders()
+ if steam_libraries_path:
+ return steam_libraries_path
+
# DLL not found in any expected location
return {
"detected": False,
@@ -118,3 +130,109 @@ class DllDetectionService(BaseService):
"error": None
}
return None
+
+ def _check_steam_library_folders(self) -> DllDetectionResponse | None:
+ """Check all Steam library folders for Lossless Scaling DLL
+
+ This method parses Steam's libraryfolders.vdf file to find all
+ Steam library locations and checks each one for the DLL.
+
+ Returns:
+ DllDetectionResponse if found, None otherwise
+ """
+ steam_libraries = self._get_steam_library_paths()
+
+ for library_path in steam_libraries:
+ dll_path = Path(library_path) / STEAM_COMMON_PATH / LOSSLESS_DLL_NAME
+ if dll_path.exists():
+ self.log.info(f"Found DLL in Steam library: {dll_path}")
+ return {
+ "detected": True,
+ "path": str(dll_path),
+ "source": f"Steam library folder: {library_path}",
+ "message": None,
+ "error": None
+ }
+
+ return None
+
+ def _get_steam_library_paths(self) -> List[str]:
+ """Get all Steam library folder paths from libraryfolders.vdf
+
+ Returns:
+ List of Steam library folder paths
+ """
+ library_paths = []
+
+ # Try different possible Steam installation locations
+ steam_paths = []
+
+ # XDG_DATA_HOME path
+ data_dir = os.getenv(ENV_XDG_DATA_HOME)
+ if data_dir and data_dir.strip():
+ steam_paths.append(Path(data_dir.strip()) / "Steam")
+
+ # HOME/.local/share path (most common on Steam Deck)
+ home_dir = os.getenv(ENV_HOME)
+ if home_dir and home_dir.strip():
+ steam_paths.append(Path(home_dir.strip()) / ".local" / "share" / "Steam")
+
+ for steam_path in steam_paths:
+ if steam_path.exists():
+ # Add the main Steam directory as a library
+ library_paths.append(str(steam_path))
+
+ # Parse libraryfolders.vdf for additional libraries
+ vdf_path = steam_path / "steamapps" / "libraryfolders.vdf"
+ if vdf_path.exists():
+ try:
+ additional_paths = self._parse_library_folders_vdf(vdf_path)
+ library_paths.extend(additional_paths)
+ except Exception as e:
+ self.log.warning(f"Failed to parse {vdf_path}: {str(e)}")
+
+ # Remove duplicates while preserving order
+ seen = set()
+ unique_paths = []
+ for path in library_paths:
+ if path not in seen:
+ seen.add(path)
+ unique_paths.append(path)
+
+ self.log.info(f"Found {len(unique_paths)} Steam library paths: {unique_paths}")
+ return unique_paths
+
+ def _parse_library_folders_vdf(self, vdf_path: Path) -> List[str]:
+ """Parse Steam's libraryfolders.vdf file to extract library paths
+
+ Args:
+ vdf_path: Path to the libraryfolders.vdf file
+
+ Returns:
+ List of additional Steam library folder paths
+ """
+ library_paths = []
+
+ try:
+ with open(vdf_path, 'r', encoding='utf-8', errors='ignore') as f:
+ content = f.read()
+
+ # Look for "path" entries in the VDF file
+ # The format is typically: "path" "/path/to/library"
+ path_pattern = r'"path"\s*"([^"]+)"'
+ matches = re.findall(path_pattern, content, re.IGNORECASE)
+
+ for path_match in matches:
+ # Convert Windows paths to Unix paths if needed
+ path = path_match.replace('\\\\', '/').replace('\\', '/')
+ library_path = Path(path)
+
+ # Verify the library folder exists and has a steamapps directory
+ if library_path.exists() and (library_path / "steamapps").exists():
+ library_paths.append(str(library_path))
+ self.log.info(f"Found additional Steam library: {library_path}")
+
+ except Exception as e:
+ self.log.error(f"Error parsing libraryfolders.vdf: {str(e)}")
+
+ return library_paths