mirror of
https://github.com/lutris/lutris
synced 2024-09-15 22:09:55 +00:00
Use libraryfolders.vdf to find addtl steam games
* Add `read_library_folders` method to read and parse the `libraryfolders.vdf` file for additional Steam game libraries * Add `get_library_config` method to the steam runner file to execute the `read_library_folders()` method from the steam config file. * After parsing the `config.vdf` file for any `BaseInstallFolder_X` keys, it will now also look for any `path` keys in the parsed `libraryfolders.vdf` dictionary. This happens before the code cleans up duplicate entries in the `dirs` array.
This commit is contained in:
parent
2b7ef5dc01
commit
6a61aa570f
|
@ -10,7 +10,7 @@ from lutris.runners.runner import Runner
|
|||
from lutris.util import linux, system
|
||||
from lutris.util.log import logger
|
||||
from lutris.util.steam.appmanifest import get_appmanifest_from_appid, get_path_from_appmanifest
|
||||
from lutris.util.steam.config import STEAM_DATA_DIRS, get_default_acf, get_steam_dir, read_config
|
||||
from lutris.util.steam.config import STEAM_DATA_DIRS, get_default_acf, get_steam_dir, read_config, read_library_folders
|
||||
from lutris.util.steam.vdf import to_vdf
|
||||
from lutris.util.strings import split_arguments
|
||||
|
||||
|
@ -144,6 +144,10 @@ class steam(Runner):
|
|||
"""Return the "Steam" part of Steam's config.vdf as a dict."""
|
||||
return read_config(self.steam_data_dir)
|
||||
|
||||
def get_library_config(self):
|
||||
"""Return the "libraryfolders" part of Steam's libraryfolders.vdf as a dict """
|
||||
return read_library_folders(self.steam_data_dir)
|
||||
|
||||
@property
|
||||
def game_path(self):
|
||||
if not self.appid:
|
||||
|
@ -235,6 +239,21 @@ class steam(Runner):
|
|||
dirs.append(path)
|
||||
i += 1
|
||||
|
||||
# New Custom dirs
|
||||
if library_config := self.get_library_config():
|
||||
paths = []
|
||||
for entry in library_config.values():
|
||||
if "mounted" in entry:
|
||||
if entry.get("path") and entry.get("mounted") == "1":
|
||||
path = system.fix_path_case(entry.get("path") + "/steamapps")
|
||||
paths.append(path)
|
||||
else:
|
||||
path = system.fix_path_case(entry.get("path") + "/steamapps")
|
||||
paths.append(path)
|
||||
for path in paths:
|
||||
if path and os.path.isdir(path):
|
||||
dirs.append(path)
|
||||
|
||||
# Deduplicate directories with the same Device.Inode
|
||||
unique_dirs = {}
|
||||
for _dir in dirs:
|
||||
|
|
|
@ -141,6 +141,30 @@ def read_config(steam_data_dir):
|
|||
logger.error("Steam config %s is empty: %s", config_filename, ex)
|
||||
|
||||
|
||||
def read_library_folders(steam_data_dir):
|
||||
"""Read the Steam Library Folders config and return it as an object"""
|
||||
def get_entry_case_insensitive(library_dict, path):
|
||||
for key, value in library_dict.items():
|
||||
if key.lower() == path[0].lower():
|
||||
if len(path) <= 1:
|
||||
return value
|
||||
return get_entry_case_insensitive(library_dict[key], path[1:])
|
||||
raise KeyError(path[0])
|
||||
if not steam_data_dir:
|
||||
return None
|
||||
library_filename = os.path.join(steam_data_dir, "config/libraryfolders.vdf")
|
||||
if not system.path_exists(library_filename):
|
||||
return None
|
||||
with open(library_filename, "r") as steam_library_file:
|
||||
library = vdf_parse(steam_library_file, {})
|
||||
# The contentstatsid key is unused and causes problems when looking for library paths.
|
||||
library["libraryfolders"].pop("contentstatsid")
|
||||
try:
|
||||
return get_entry_case_insensitive(library, ["libraryfolders"])
|
||||
except KeyError as ex:
|
||||
logger.error("Steam libraryfolders %s is empty: %s", library_filename, ex)
|
||||
|
||||
|
||||
def get_steamapps_paths():
|
||||
from lutris.runners import steam # pylint: disable=import-outside-toplevel
|
||||
return steam.steam().get_steamapps_dirs()
|
||||
|
|
Loading…
Reference in a new issue