Skip to content

Commit

Permalink
Support new library folder config format
Browse files Browse the repository at this point in the history
The new Steam beta stores additional data for each library folder
instead of just storing the library path as the field value.

Fixes #105
  • Loading branch information
Matoking committed Jun 6, 2021
1 parent f56447e commit 9272751
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 7 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
### Fixed
- Custom Proton installations now use Steam Runtime installations when applicable
- Fix crash caused by older Steam app installations using a different app manifest structure
- Fix crash caused by the change to lowercase field names in multiple VDF files
- Fix crash caused by change to lowercase field names in multiple VDF files
- Fix crash caused by change in the Steam library folder configuration file

## [1.5.1] - 2021-05-10
### Fixed
Expand Down
14 changes: 12 additions & 2 deletions src/protontricks/steam.py
Original file line number Diff line number Diff line change
Expand Up @@ -612,10 +612,20 @@ def parse_library_folders(data):
"""
vdf_data = lower_dict(vdf.loads(data))
# Library folders have integer field names in ascending order
library_folders = [
Path(value) for key, value in vdf_data["libraryfolders"].items()
library_entries = [
value for key, value in vdf_data["libraryfolders"].items()
if key.isdigit()
]
library_folders = []

for value in library_entries:
if isinstance(value, dict):
# Library data is stored in a dict in newer Steam releases
library_folders.append(Path(value["path"]))
else:
# Older releases just store the library path as a string
# and nothing else
library_folders.append(Path(value))

logger.info(
"Found %d Steam library folders", len(library_folders)
Expand Down
15 changes: 12 additions & 3 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -533,7 +533,7 @@ def steam_library_factory(steam_dir, steam_libraryfolders_path, tmp_path):
"""
Factory function to add fake Steam library folders
"""
def func(name):
def func(name, new_struct=False):
library_dir = Path(str(tmp_path)) / "mnt" / name
library_dir.mkdir(parents=True)

Expand All @@ -545,9 +545,18 @@ def func(name):
# Each new library adds a new entry into the config file with the
# field name that starts from 1 and increases with each new library
# folder.
# Newer Steam releases stores the library entry in a dict, while
# older releases just store the full path as the field value
library_id = len(libraryfolders_config["LibraryFolders"].keys()) - 1
libraryfolders_config["LibraryFolders"][str(library_id)] = \
str(library_dir)
if new_struct:
libraryfolders_config["LibraryFolders"][str(library_id)] = {
"path": str(library_dir),
"label": "",
"mounted": "1"
}
else:
libraryfolders_config["LibraryFolders"][str(library_id)] = \
str(library_dir)

steam_libraryfolders_path.write_text(vdf.dumps(libraryfolders_config))

Expand Down
33 changes: 32 additions & 1 deletion tests/test_steam.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
from protontricks.steam import (SteamApp, find_appid_proton_prefix,
find_steam_path, find_steam_proton_app,
get_custom_proton_installations,
get_custom_windows_shortcuts, get_steam_apps)
get_custom_windows_shortcuts, get_steam_apps,
get_steam_lib_paths)


class TestSteamApp:
Expand Down Expand Up @@ -158,6 +159,36 @@ def test_find_steam_specific_app_proton(
assert proton_app.name == "Proton 6.66"


class TestFindLibraryPaths:
@pytest.mark.parametrize(
"new_struct", [False, True], ids=["old struct", "new struct"]
)
def test_get_steam_lib_paths(
self, steam_dir, steam_library_factory, new_struct):
"""
Find the Steam library folders generated with either the old or new
structure.
Older Steam releases only use a field value containing the path
to the library, while newer releases store a dict with additional
information besides the library path.
"""
library_a = steam_library_factory(
"TestLibrary_A", new_struct=new_struct
)
library_b = steam_library_factory(
"TestLibrary_B", new_struct=new_struct
)

lib_paths = get_steam_lib_paths(steam_dir)

assert len(lib_paths) == 3
assert str(lib_paths[0]) == str(steam_dir)
assert str(lib_paths[1]) == str(library_a)
assert str(lib_paths[2]) == str(library_b)




class TestFindAppidProtonPrefix:
def test_find_appid_proton_prefix_steamapps_case(
self, steam_app_factory, steam_dir, default_proton,
Expand Down

0 comments on commit 9272751

Please sign in to comment.