Lutris: Allow checking data directory for game configs #497
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Fixes #495.
Overview
This PR addresses two issues with how we currently fetch game config files for Lutris, which is used to display the CtInfo dialog and Games List dialog.
I tested this change on my laptop (uses the newer
~/.local/share/lutris/games
path), and this PR fixes the crash in #495 and finds the game config for the one game I have installed (GE-Proton9-25 for Battlenet displays properly in the Games List and CtInfo dialog). I have also tested this setup on my Desktop PC (uses the older~/.config/lutris/games
path), which works correctly and displays the same games with and without this change.Problem
Currently, we check for games in the
~/.config/lutris/games
folder and that folder only. However, we assume that if we get a Lutris config folder back at all fromself.install_loc.get('config_dir')
, then we will have a~/.config/lutris/games
. However this is not the case. So if~/.config/lutris/games
does not exist, there will be a crash when attempting to callos.listdir
on that folder. This crash was the reason for opening #495.However this was a symptom of another problem: Lutris no longer uses
~/.config/lutris/games
by default and instead will use~/.local/share/lutris
for new installations. This is why I was experiencing the crash described, because my Lutris game config folder was at~/.local/share/lutris
on my laptop but at~/.config/lutris
on my Desktop PC.The Lutris codebase has a comment noting that
~/.config/lutris
is deprecated: https://github.com/lutris/lutris/blob/6b968e858955c0638bf93b3a72fec5ae650f0932/lutris/settings.py#L20-L25So the overall problem was that:
~/.config/lutris/games
would always exist, which is not the case.~/.local/share/lutris/games
which is the newer folder. However if~/.config/lutris/games
exists, we should prefer that, and Lutris cannot use both~/.config/lutris/games
and~/.local/share/lutris/games
at the same time.Solution
We now search
~/.local/share/lutris/games
to find game configuration files (and Flatpak equivalent), if~/.config/lutris/games
does not exist (and Flatpak equivalent). Lutris will prefer~/.config/lutris/games
if it exists, but this path is deprecated and Lutris will default to using~/.local/share/lutris/games
(XDG Data Directory) if the Config directory does not exist.As a result of this, we also fix the crash which was a symptom of this problem and the catalyst for opening #495. The crash comes from
os.listdir
when searching for our game config file, if~/.config/lutris
exists but not~/.config/lutris/games
, caused by the assumption that the games folder will exist in the config folder if the config folder exists. We no longer get as far asos.listdir
unless we find a valid Lutris game config folder, either in the Config Directory or Data directory.The overall implementation here will "fall up" to
~/.local/share/lutris/games
if~/.config/lutris/games
is not found, different to before where we assumed thegames
folder existed if we got any truthy value back frominstall_loc.get('config_dir')
.Implementation
Most of the implementation is fairly straightforward "if no Lutris games folder in config dir, check the data dir for the games folder, and if neither exist then return an empty dict". One detail worth calling out though is how we get the data directory. We do this by going two directories up from the
install_loc.get('install_dir')
, which in the case of Lutris will be something like~/.local/share/lutris/runners/wine/../..games/
. We get theabspath
andexpanduser
of this so we end up with a clean path, like/home/gaben/.local/share/lutris/games
.This works, and should be safe to do, and we do similar logic in Ctmods to get the install folder we want to use (such as the vkd3d-proton Ctmod). So there is precedent for doing this in the codebase, and it should be safe to do for Flatpak paths as well, since
install_dir
for Lutris should always belutris/runners/wine
. Two directories up should always give us the Lutris root install. It is worth noting that we make similar assumptions about theinstall_dir
path and directory structure around that for Heroic inheroicutil
. But let me know if there are any concerns with this kind of approach!For consistency, the whole
LutrisGame#get_game_config
method now works with/path/to/lutris/games
instead of just getting the Lutris config folder andos.path.join
ing on thegames
folder. This means the method a bit easier to read as well imo, since we only build the path to the game in one place.Let me know if I missed anything or if there are any concerns/edge cases I did not consider. All feedback is welcome.
Thanks! :-)