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

Proton initialized title files not found when casing does not match. #55

Closed
wtjones opened this issue Oct 19, 2020 · 4 comments
Closed
Labels
bug Something isn't working
Milestone

Comments

@wtjones
Copy link
Contributor

wtjones commented Oct 19, 2020

I had to modify the manifest make this entry pull in. The reason for the lower cases is due to the fact that the wine prefix was created on install, and the game's installer must have defaulted to create my games/company of heroes 2 with that casing for no apparent reason.

The PCGamingWiki could be updated, but would still be broken for users that already had a My Games folder for example.

before:

<winDocuments>/My Games/Company of Heroes 2/Savegames:
      tags:
        - save
      when:
        - os: windows

after:

<winDocuments>/my games/company of heroes 2/Savegames:
      tags:
        - save
      when:
        - os: windows

image

@wtjones wtjones changed the title Proton initialized title files not found when case does not match. Proton initialized title files not found when casing does not match. Oct 19, 2020
@mtkennerly mtkennerly added the bug Something isn't working label Oct 19, 2020
@mtkennerly
Copy link
Owner

Ah, yeah, since Windows doesn't actually enforce the capitalization, it doesn't make sense to enforce it when checking a Windows entry on Linux. I'll see if I can make it case-insensitive here.

In the meantime, don't forget that manual edits to the manifest will be reset when it downloads a new copy, so you may want to make a custom game entry instead until this is fixed (if it has the same name, it'll override the manifest's entry for that game).

@mtkennerly
Copy link
Owner

It turns out that the case sensitivity option in the glob crate is ignored outright (rust-lang/glob#61), so I would need to use a different crate to fix this. I tried globwalk, but it seems to have some other issues/differences that would prevent me from switching, and I'm not sure there are any other viable options right now. I'm afraid this may have to wait :/

@mtkennerly mtkennerly added the blocked Waiting on a dependency label Nov 1, 2020
@mtkennerly
Copy link
Owner

mtkennerly commented Oct 3, 2022

Took another look at this. Here's what I found so far:

Glob v0.3.0

I double checked the behavior of the case sensitivity option, and it seems like it works in some cases, but not all.

Example on Windows (setting: case-sensitive):

  • Existing file: C:/Program Files (x86)/Steam/steamapps/common/1000 Amps/save1
  • Does not find anything (correct): C:/Program Files (x86)/Steam/steamapps/common/1000 Amps/saVe*
  • Still finds something (incorrect): C:/Program files (x86)/Steam/steamapps/common/1000 Amps/save*

Similar behavior on Linux (setting: case-insensitive):

checking: "/home/vagrant/a-custom-game/*.txt"
found:    "/home/vagrant/a-custom-game/file1.txt"
found:    "/home/vagrant/a-custom-game/file2.txt"

checking: "/home/vagrant/a-custom-game/*.Txt"
found:    "/home/vagrant/a-custom-game/file1.txt"
found:    "/home/vagrant/a-custom-game/file2.txt"

checking: "/home/vagrant/a-custom-Game/*.txt"
[no results]

checking: "/home/vagrant/a-custom-g*me/*.txt"
found:    "/home/vagrant/a-custom-game/file1.txt"
found:    "/home/vagrant/a-custom-game/file2.txt"

It seems like the case insensitivity option only affects text that's adjacent to a wildcard.

GlobWalk v0.8.1

Doesn't seem to support absolute paths in globs. Even if you provide an absolute path, I think it tries to find the path relative to the current folder. You can pass in a different base folder, but it doesn't seem to work correctly when the base is just C:, so you'd have to split something like C:/foo/bar/*.txt into two parts: C:/foo and bar/*.txt. I don't think it can find files like C:/*.txt unless the current directory is already C:.

With the below code, it took 28 seconds to scan a single game, and it encountered a large number of "permission denied" errors. Maybe related to Gilnaa/globwalk#29.

diff --git a/src/path.rs b/src/path.rs
index 0cddfac..d0b7825 100644
--- a/src/path.rs
+++ b/src/path.rs
@@ -370,13 +370,15 @@ impl StrictPath {
     }

     pub fn glob(&self) -> Vec<StrictPath> {
-        let options = glob::MatchOptions {
-            case_sensitive: crate::prelude::CASE_INSENSITIVE_OS,
-            require_literal_separator: true,
-            require_literal_leading_dot: false,
-        };
-        match glob::glob_with(&self.render(), options) {
-            Ok(xs) => xs.filter_map(|r| r.ok()).map(StrictPath::from).collect(),
+        let rendered = self.render();
+        let parts: Vec<_> = rendered.split('/').collect();
+        if parts.len() < 3 {
+            return vec![];
+        }
+        let base = format!("{}/{}", parts[0], parts[1]);
+        let path = parts[2..].join("/");
+        match globwalk::GlobWalkerBuilder::new(base, path).case_insensitive(crate::prelude::CASE_INSENSITIVE_OS).follow_links(true).build() {
+            Ok(xs) => xs.filter_map(|r| r.ok()).map(|x| StrictPath::from(x.path())).collect(),
             Err(_) => vec![],
         }
     }

Wax v0.5.0

Significantly slower than the current implementation. Timing for a full backup preview:

  • Before: 10 seconds
  • After: 1 minute 25 seconds

It also doesn't natively support globs that begin with a Windows drive letter, which means every path has to be split in a way that it understands.

diff --git a/src/path.rs b/src/path.rs
index 0cddfac..8254569 100644
--- a/src/path.rs
+++ b/src/path.rs
@@ -370,17 +370,16 @@ impl StrictPath {
     }

     pub fn glob(&self) -> Vec<StrictPath> {
-        let options = glob::MatchOptions {
-            case_sensitive: crate::prelude::CASE_INSENSITIVE_OS,
-            require_literal_separator: true,
-            require_literal_leading_dot: false,
+        let (drive, plain) = self.split_drive();
+        let plain = plain.replace('(', "\\(").replace(')', "\\)");
+        let glob = match wax::Glob::new(&plain) {
+            Ok(x) => x,
+            Err(_) => return vec![self.clone()],
         };
-        match glob::glob_with(&self.render(), options) {
-            Ok(xs) => xs.filter_map(|r| r.ok()).map(StrictPath::from).collect(),
-            Err(_) => vec![],
-        }
+        glob.walk(drive + "/").filter_map(|r| r.ok()).map(|x| StrictPath::from(x.path())).collect()
     }

+
     pub fn same_content(&self, other: &StrictPath) -> bool {
         self.try_same_content(other).unwrap_or(false)
     }

@mtkennerly
Copy link
Owner

I've forked the Glob crate and just published Globetter, which fixes the case sensitivity option. I'm planning to incorporate this into Ludusavi.

@mtkennerly mtkennerly added this to the v0.14.0 milestone Oct 4, 2022
@mtkennerly mtkennerly removed the blocked Waiting on a dependency label Oct 5, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants