Mord3rca/gamma-launcher

usvfs-workaround: fix paths

Closed this issue · 9 comments

030623-1685791869_scrot

Due to the very nature of *nix being case-sensitive the resulting gamedata folder contains non-merged folders with different capitalization. The picture demonstrates this very well. This happens throughout the gamedata-folder, resulting in in-game glitches and bugs (Noticeably the sound -> TOZ-34 for example).

Wine, as of now, does not seem to handle this:
https://wiki.winehq.org/Case_Insensitive_Filenames

Possible solution

Rewrite paths to be lowercase before copying.
For this another library must be used or a function needs to be written from scratch

Alternatively the function distutils.dir_util.copy_tree(..) can be replaced with a modified version via monkey patching.
I don't know though where to find said function's source code. There is also a probability that it was written in C.

Another way is to write a function that will be executed on the target mod directory after copy_tree which renames the folders to their lowercase counterpart.

It's not possible with folder filtering

I was planning on lowering everything just before but ... It's not a solution since some installation directives contain capital letters.
Still looking for a smart idea to do that. Actually, the only mod with capital letters is: 122- Zone Tales in Loading Screens - Oni, so issue is really minor.

I may need to search for gamedata dirs in decompressed archive and force them to lowercase.

It's not possible with folder filtering

I was planning on lowering everything just before but ... It's not a solution since some installation directives contain capital letters. Still looking for a smart idea to do that. Actually, the only mod with capital letters is: 122- Zone Tales in Loading Screens - Oni, so issue is really minor.

I may need to search for gamedata dirs in decompressed archive and force them to lowercase.

I got a little bit acquainted with python and wrote a recursive function that does what we need. The initial folder will not be renamed (The mod folder).

import os.path
import shutil

# renames all tree subdirectories to lowercase
def tree_lower_subdirectories(directory, modify_root = False):
    if not os.path.lexists(directory): return False

    if modify_root and any(map(str.isupper, os.path.basename(directory))):
        ps = os.path.split(directory)
        directory_lower=os.path.join(ps[0], ps[1].lower())
        if os.path.isdir(directory_lower): # already exists
            shutil.copytree(directory, directory_lower, dirs_exist_ok=True)
            shutil.rmtree(directory)
        else:
            os.rename(directory, directory_lower)
        directory = directory_lower

    for dir_ in os.listdir(directory):
        if os.path.isdir(os.path.join(directory, dir_)):
            tree_lower_subdirectories(
                os.path.join(directory, dir_),
                not modify_root and not modify_root or modify_root
            )

I used it separately in the mods folder. Works as intended :)
The game glitches I observed are solved

PR should fix the issue, you can check that by verifying the content of mod 122
And content installation folder if you use usvfs-workaround

PR should fix the issue, you can check that by verifying the content of mod 122

Great you made that. Why do you not use or at least adapt my code, though? Not that I mind, but I'd like to know.
It has less dependencies, as you are already using shutil.

I prefer to avoid recursive function and using pathlib instead of os since it is used everywhere in this code

Okay, fair enough.