proton: Don't hard-code compatdata paths

This commit is contained in:
Andrew Eikum 2019-07-29 11:09:18 -05:00
parent 6d6e86df99
commit 5c9dd25e81

77
proton
View file

@ -72,7 +72,7 @@ def upgrade_pfx(old_ver):
if old_ver == CURRENT_PREFIX_VERSION: if old_ver == CURRENT_PREFIX_VERSION:
return return
log("Upgrading prefix from " + str(old_ver) + " to " + CURRENT_PREFIX_VERSION + " (" + os.environ["STEAM_COMPAT_DATA_PATH"] + ")") log("Upgrading prefix from " + str(old_ver) + " to " + CURRENT_PREFIX_VERSION + " (" + g_compatdata.base_dir + ")")
if old_ver is None: if old_ver is None:
return return
@ -93,25 +93,25 @@ def upgrade_pfx(old_ver):
(int(new_proton_maj) == int(old_proton_maj) and \ (int(new_proton_maj) == int(old_proton_maj) and \
int(new_proton_min) < int(old_proton_min)): int(new_proton_min) < int(old_proton_min)):
log("Removing newer prefix") log("Removing newer prefix")
if old_proton_ver == "3.7" and not os.path.exists(os.environ["STEAM_COMPAT_DATA_PATH"] + "/tracked_files"): if old_proton_ver == "3.7" and not os.path.exists(g_compatdata.tracked_files_file):
#proton 3.7 did not generate tracked_files, so copy it into place first #proton 3.7 did not generate tracked_files, so copy it into place first
try_copy(g_proton.path("proton_3.7_tracked_files"), os.environ["STEAM_COMPAT_DATA_PATH"] + "/tracked_files") try_copy(g_proton.path("proton_3.7_tracked_files"), g_compatdata.tracked_files_file)
remove_tracked_files(os.environ["STEAM_COMPAT_DATA_PATH"]) remove_tracked_files(g_compatdata.base_dir)
return return
if old_proton_ver == "3.7" and old_prefix_ver == "1": if old_proton_ver == "3.7" and old_prefix_ver == "1":
if not os.path.exists(prefix + "/drive_c/windows/syswow64/kernel32.dll"): if not os.path.exists(g_compatdata.prefix_dir + "/drive_c/windows/syswow64/kernel32.dll"):
#shipped a busted 64-bit-only installation on 20180822. detect and wipe clean #shipped a busted 64-bit-only installation on 20180822. detect and wipe clean
log("Detected broken 64-bit-only installation, re-creating prefix.") log("Detected broken 64-bit-only installation, re-creating prefix.")
shutil.rmtree(prefix) shutil.rmtree(g_compatdata.prefix_dir)
return return
#replace broken .NET installations with wine-mono support #replace broken .NET installations with wine-mono support
if os.path.exists(prefix + "/drive_c/windows/Microsoft.NET/NETFXRepair.exe") and \ if os.path.exists(g_compatdata.prefix_dir + "/drive_c/windows/Microsoft.NET/NETFXRepair.exe") and \
file_is_wine_fake_dll(prefix + "/drive_c/windows/system32/mscoree.dll"): file_is_wine_fake_dll(g_compatdata.prefix_dir + "/drive_c/windows/system32/mscoree.dll"):
log("Broken .NET installation detected, switching to wine-mono.") log("Broken .NET installation detected, switching to wine-mono.")
#deleting this directory allows wine-mono to work #deleting this directory allows wine-mono to work
shutil.rmtree(prefix + "/drive_c/windows/Microsoft.NET") shutil.rmtree(g_compatdata.prefix_dir + "/drive_c/windows/Microsoft.NET")
except ValueError: except ValueError:
log("Prefix has an invalid version?! You may want to back up user files and delete this prefix.") log("Prefix has an invalid version?! You may want to back up user files and delete this prefix.")
@ -189,11 +189,23 @@ class Proton:
def path(self, d): def path(self, d):
return self.base_dir + d return self.base_dir + d
class CompatData:
def __init__(self, compatdata):
self.base_dir = compatdata + "/"
self.prefix_dir = self.path("pfx/")
self.version_file = self.path("version")
self.tracked_files_file = self.path("tracked_files")
self.prefix_lock = FileLock(self.path("pfx.lock"), timeout=-1)
def path(self, d):
return self.base_dir + d
if not "STEAM_COMPAT_DATA_PATH" in os.environ: if not "STEAM_COMPAT_DATA_PATH" in os.environ:
log("No compat data path?") log("No compat data path?")
sys.exit(1) sys.exit(1)
g_proton = Proton(os.path.dirname(sys.argv[0])) g_proton = Proton(os.path.dirname(sys.argv[0]))
g_compatdata = CompatData(os.environ["STEAM_COMPAT_DATA_PATH"])
#extract if needed #extract if needed
with g_proton.dist_lock: with g_proton.dist_lock:
@ -245,8 +257,7 @@ with g_proton.dist_lock:
run_wine([g_proton.wine_bin, "wineboot"]) run_wine([g_proton.wine_bin, "wineboot"])
run_wine([g_proton.wineserver_bin, "-w"]) run_wine([g_proton.wineserver_bin, "-w"])
prefix = os.environ["STEAM_COMPAT_DATA_PATH"] + "/pfx/" env["WINEPREFIX"] = g_compatdata.prefix_dir
env["WINEPREFIX"] = prefix
if "PROTON_LOG" in env and nonzero(env["PROTON_LOG"]): if "PROTON_LOG" in env and nonzero(env["PROTON_LOG"]):
env["WINEDEBUG"] = "+timestamp,+pid,+tid,+seh,+debugstr,+loaddll,+mscoree" env["WINEDEBUG"] = "+timestamp,+pid,+tid,+seh,+debugstr,+loaddll,+mscoree"
@ -369,29 +380,27 @@ def set_dir_casefold_bit(dir_path):
pass pass
os.close(dr) os.close(dr)
prefix_lock = FileLock(os.environ["STEAM_COMPAT_DATA_PATH"] + "/pfx.lock", timeout=-1) with g_compatdata.prefix_lock:
with prefix_lock: if os.path.exists(g_compatdata.version_file):
version_file = os.environ["STEAM_COMPAT_DATA_PATH"] + "/version" with open(g_compatdata.version_file, "r") as f:
if os.path.exists(version_file):
with open(version_file, "r") as f:
upgrade_pfx(f.readline().strip()) upgrade_pfx(f.readline().strip())
else: else:
upgrade_pfx(None) upgrade_pfx(None)
if not os.path.exists(prefix): if not os.path.exists(g_compatdata.prefix_dir):
makedirs(prefix + "/drive_c") makedirs(g_compatdata.prefix_dir + "/drive_c")
set_dir_casefold_bit(prefix + "/drive_c") set_dir_casefold_bit(g_compatdata.prefix_dir + "/drive_c")
if not os.path.exists(prefix + "/user.reg"): if not os.path.exists(g_compatdata.prefix_dir + "/user.reg"):
#copy default prefix into place #copy default prefix into place
with open(os.environ["STEAM_COMPAT_DATA_PATH"] + "/tracked_files", "w") as tfiles: with open(g_compatdata.tracked_files_file, "w") as tfiles:
mergedirs(g_proton.default_pfx_dir, prefix, tfiles) mergedirs(g_proton.default_pfx_dir, g_compatdata.prefix_dir, tfiles)
with open(version_file, "w") as f: with open(g_compatdata.version_file, "w") as f:
f.write(CURRENT_PREFIX_VERSION + "\n") f.write(CURRENT_PREFIX_VERSION + "\n")
#create font files symlinks #create font files symlinks
create_fonts_symlinks(prefix) create_fonts_symlinks(g_compatdata.prefix_dir)
#copy steam files into place #copy steam files into place
if "STEAM_COMPAT_CLIENT_INSTALL_PATH" in os.environ: if "STEAM_COMPAT_CLIENT_INSTALL_PATH" in os.environ:
@ -400,7 +409,7 @@ with prefix_lock:
else: else:
#linux-only fallback, really shouldn't get here #linux-only fallback, really shouldn't get here
steamdir = os.environ["HOME"] + ".steam/root/" steamdir = os.environ["HOME"] + ".steam/root/"
dst = prefix + "/drive_c/Program Files (x86)/" dst = g_compatdata.prefix_dir + "/drive_c/Program Files (x86)/"
makedirs(dst + "Steam") makedirs(dst + "Steam")
filestocopy = ["steamclient.dll", filestocopy = ["steamclient.dll",
"steamclient64.dll", "steamclient64.dll",
@ -413,13 +422,13 @@ with prefix_lock:
try_copy(steamdir + "/legacycompat/" + f, dstfile) try_copy(steamdir + "/legacycompat/" + f, dstfile)
#copy openvr files into place #copy openvr files into place
dst = prefix + "/drive_c/vrclient/bin/" dst = g_compatdata.prefix_dir + "/drive_c/vrclient/bin/"
makedirs(dst) makedirs(dst)
try_copy(g_proton.lib_dir + "wine/fakedlls/vrclient.dll", dst) try_copy(g_proton.lib_dir + "wine/fakedlls/vrclient.dll", dst)
try_copy(g_proton.lib64_dir + "wine/fakedlls/vrclient_x64.dll", dst) try_copy(g_proton.lib64_dir + "wine/fakedlls/vrclient_x64.dll", dst)
try_copy(g_proton.lib_dir + "wine/dxvk/openvr_api_dxvk.dll", prefix + "/drive_c/windows/syswow64/") try_copy(g_proton.lib_dir + "wine/dxvk/openvr_api_dxvk.dll", g_compatdata.prefix_dir + "/drive_c/windows/syswow64/")
try_copy(g_proton.lib64_dir + "wine/dxvk/openvr_api_dxvk.dll", prefix + "/drive_c/windows/system32/") try_copy(g_proton.lib64_dir + "wine/dxvk/openvr_api_dxvk.dll", g_compatdata.prefix_dir + "/drive_c/windows/system32/")
#parse linux openvr config and present it in win32 format to the app. #parse linux openvr config and present it in win32 format to the app.
#logic from openvr's CVRPathRegistry_Public::GetPaths #logic from openvr's CVRPathRegistry_Public::GetPaths
@ -462,10 +471,10 @@ with prefix_lock:
except (TypeError, ValueError, OSError): except (TypeError, ValueError, OSError):
log("Missing or invalid openvrpaths.vrpath file! " + str(sys.exc_info()[1])) log("Missing or invalid openvrpaths.vrpath file! " + str(sys.exc_info()[1]))
makedirs(prefix + "/drive_c/users/steamuser/Local Settings/Application Data/openvr") makedirs(g_compatdata.prefix_dir + "/drive_c/users/steamuser/Local Settings/Application Data/openvr")
#remove existing file #remove existing file
vrpaths_name = prefix + "/drive_c/users/steamuser/Local Settings/Application Data/openvr/openvrpaths.vrpath" vrpaths_name = g_compatdata.prefix_dir + "/drive_c/users/steamuser/Local Settings/Application Data/openvr/openvrpaths.vrpath"
if os.path.exists(vrpaths_name): if os.path.exists(vrpaths_name):
os.remove(vrpaths_name) os.remove(vrpaths_name)
@ -505,15 +514,15 @@ with prefix_lock:
for f in wined3dfiles: for f in wined3dfiles:
try_copy(g_proton.default_pfx_dir + "drive_c/windows/system32/" + f + ".dll", try_copy(g_proton.default_pfx_dir + "drive_c/windows/system32/" + f + ".dll",
prefix + "drive_c/windows/system32/" + f + ".dll") g_compatdata.prefix_dir + "drive_c/windows/system32/" + f + ".dll")
try_copy(g_proton.default_pfx_dir + "drive_c/windows/syswow64/" + f + ".dll", try_copy(g_proton.default_pfx_dir + "drive_c/windows/syswow64/" + f + ".dll",
prefix + "drive_c/windows/syswow64/" + f + ".dll") g_compatdata.prefix_dir + "drive_c/windows/syswow64/" + f + ".dll")
for f in dxvkfiles: for f in dxvkfiles:
try_copy(g_proton.lib64_dir + "wine/dxvk/" + f + ".dll", try_copy(g_proton.lib64_dir + "wine/dxvk/" + f + ".dll",
prefix + "drive_c/windows/system32/" + f + ".dll") g_compatdata.prefix_dir + "drive_c/windows/system32/" + f + ".dll")
try_copy(g_proton.lib_dir + "wine/dxvk/" + f + ".dll", try_copy(g_proton.lib_dir + "wine/dxvk/" + f + ".dll",
prefix + "drive_c/windows/syswow64/" + f + ".dll") g_compatdata.prefix_dir + "drive_c/windows/syswow64/" + f + ".dll")
dlloverrides[f] = "n" dlloverrides[f] = "n"
if "nod3d11" in config_opts: if "nod3d11" in config_opts: