diff options
Diffstat (limited to 'py_modules/lsfg_vk/dll_detection.py')
| -rw-r--r-- | py_modules/lsfg_vk/dll_detection.py | 120 |
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 |
