Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: allow returning multiple directories #64

Open
wants to merge 10 commits into
base: master
Choose a base branch
from

Conversation

LuisMayo
Copy link

This PR adds the ability for the library to locate many valid installations, which may be useful, specially on Linux installations. As discussed here: #17 (comment)

I'm really a newbie when it comes to Rust so I'd be happy to fix any problems you may encounter and thanks for your work!

@amtep
Copy link

amtep commented Apr 13, 2024

Just wanted to let you know that I'm also waiting for this feature :)

My use case is that I want to find a particular game, regardless of in which installation it's installed.
So I'll loop over the steamdirs until the find_app resolves.

I looked at the code and wondered, is it really an error if no installations are found? I figure it could just return an empty Vec in that case.

@LuisMayo
Copy link
Author

Just wanted to let you know that I'm also waiting for this feature :)

My use case is that I want to find a particular game, regardless of in which installation it's installed. So I'll loop over the steamdirs until the find_app resolves.

I looked at the code and wondered, is it really an error if no installations are found? I figure it could just return an empty Vec in that case.

That's actually the very same reason I want it. My app patches a Videogame (VHS) and I want to locate it to patch the exe, no matter the install dir

About returning on Error I just made it to be consistent with the locate function, but it's true that it may not make that much sense, so I could change it to return an empty array, I don't have strong feelings towards any of the options.

mainrs added a commit to gemu-age-launcher/steamlocate-rs that referenced this pull request Jan 21, 2025
The implementation is based on WilliamVenner#64,
with some code changes around Vec and Iterator handling.
@dotaxis
Copy link

dotaxis commented Feb 10, 2025

I would love to have this merged. I'm building a project and would like to account for edge cases where people may have both Flatpak and Native Steam installed and I want to let them pick which installation to work with.

I will just use your fork for now. Thank you!

@LuisMayo
Copy link
Author

I see the branch is now conflicting with main. If I get any signal this is wanted I will rebase!

And you can use the fork of course. I've been doing that and it works for me

@dotaxis
Copy link

dotaxis commented Feb 10, 2025

Unfortunately I wasn't able to use it in my case because it returned multiple entries for each installation, as per these lines:

// Flatpak steam install directories
home_dir.join(".var/app/com.valvesoftware.Steam/.local/share/Steam"),
home_dir.join(".var/app/com.valvesoftware.Steam/.steam/steam"),
home_dir.join(".var/app/com.valvesoftware.Steam/.steam/root"),
// Standard install directories
home_dir.join(".local/share/Steam"),
home_dir.join(".steam/steam"),
home_dir.join(".steam/root"),
home_dir.join(".steam"),
// Snap steam install directories
snap_dir.join("steam/common/.local/share/Steam"),
snap_dir.join("steam/common/.steam/steam"),
snap_dir.join("steam/common/.steam/root"),

In my experience the .steam/root symlink always exists, but I don't have a huge variety of environments to be sure of that. It would be great to have some logic which makes locate_multiple only return one entry per native/flatpak/snap installation, but since I'm not currently looking to support snaps in my project, I just wrote out a function to test for the .steam/root locations and use from_dir() to convert them to SteamDir.

IMO, only a crazy person would have multiple installations of Steam on the same machine, but I can't count on other people to not be crazy, so I'm still very interested in this PR.

This crate has been an absolute lifesaver and other than this very minor limitation, it's perfect.

@CosmicHorrorDev
Copy link
Collaborator

Sorry for the (very long) delay. I'm finally getting around to taking a look at this and in general I like the idea of providing an API for locating all steam installations. One caveat though; I would also really like to be able to detect when a steam installation is still actually valid (ref #17). Most of the time it seems like people have multiple installations from installing and uninstalling in different ways that leave lingering files that we pick up as a steam installation. I'd prefer if we could filter out no-longer-valid installations in some way

Re @amtep

I looked at the code and wondered, is it really an error if no installations are found? I figure it could just return an empty Vec in that case.

I would agree. Returning an empty vec when trying to locate all installations seems reasonable to me

Re @dotaxis

In my experience the .steam/root symlink always exists

I can confirm the same on my installation. Both ~/.steam/steam and ~/.steam/root are both symlinks to the same installation. I'm also equally unsure if this is always the case or if we should be preferring one or the other. It's possible that we could just remove one and leave the other 🤔


Also thanks for all the kind words! It's been a lot of effort trying to juggle all of the projects I try to maintain, but knowing that other people get use out of them makes all the work worth it :)

@dotaxis
Copy link

dotaxis commented Feb 11, 2025

I can confirm the same on my installation. Both ~/.steam/steam and ~/.steam/root are both symlinks to the same installation. I'm also equally unsure if this is always the case or if we should be preferring one or the other. It's possible that we could just remove one and leave the other 🤔

I can't find any documentation on what the different symlinks are meant to point to but I think it is safe to remove .local/share/Steam

But perhaps a better approach would be to actually follow the symlinks and then form a vector of install directories based on where they point to. That would avoid duplicates without just guessing at which symlinks are important.

@CosmicHorrorDev
Copy link
Collaborator

But perhaps a better approach would be to actually follow the symlinks and then form a vector of install directories based on where they point to. That would avoid duplicates without just guessing at which symlinks are important.

That seems like it might be the most robust approach. It should just involve a little std::fs::read_link logic

@dotaxis
Copy link

dotaxis commented Feb 15, 2025

@LuisMayo do you have any interest in implementing this using read_link to avoid dupes?

@LuisMayo
Copy link
Author

I will implement Link following as well as other of the suggestions here (like empty Vec)

I'm gonna have a really busy week so it may take a while even those two little changes

@CosmicHorrorDev
Copy link
Collaborator

Just ping me whenever your changes are ready. Now that v2 is released I'm much more available for review :)

@LuisMayo
Copy link
Author

Hi

Changes pushed @CosmicHorrorDev

Please someone check if Windows side of things is working fine since I haven't had the time to do it

Thanks!

@CosmicHorrorDev
Copy link
Collaborator

Clippy will probably be angry, but that's what CI is for after all 😸

@LuisMayo
Copy link
Author

I think clippy should be happy now

@CosmicHorrorDev
Copy link
Collaborator

CosmicHorrorDev commented Feb 16, 2025

cargo clippy --fix may make things a bit easier btw. I'm not sure if it handles cfgs outside of what you're using locally, but it's a bit easier than manually fixing everything

@LuisMayo
Copy link
Author

Ok more changes now. Let's see if it works

@CosmicHorrorDev
Copy link
Collaborator

Also another quick tip: I think you can enable action runs on your fork to get a bit of a faster feedback loop

@CosmicHorrorDev CosmicHorrorDev self-requested a review February 16, 2025 18:01
@LuisMayo
Copy link
Author

Finally. Sorry for the trouble

Copy link
Collaborator

@CosmicHorrorDev CosmicHorrorDev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a few nits, but overall the implementation is looking pretty good now 🚀

@CosmicHorrorDev
Copy link
Collaborator

Finally. Sorry for the trouble

No worries at all! I'm just happy to have help :D

@LuisMayo
Copy link
Author

Hi @CosmicHorrorDev

Suggestions applied!

Thanks a lot

Copy link
Collaborator

@CosmicHorrorDev CosmicHorrorDev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I went ahead and pushed a commit that switches things back to maintaining the original order that dirs get returned in while deduping with a BTreeSet instead of sorting and deduping, so that way we keep the same order that things are returned in as main (aka makes me comfortable releasing this without having to consider it a breaking change)

@CosmicHorrorDev
Copy link
Collaborator

@LuisMayo It looks like there are some merge conflicts. I can handle them if you don't want to deal with them, but I can also leave it to you of course

@LuisMayo
Copy link
Author

LuisMayo commented Feb 23, 2025 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants