#!/usr/bin/env python2 #script to launch Wine with the correct environment import filecmp import json import os import shutil import subprocess import sys import tarfile PFX="Proton: " def log(msg): sys.stdout.write(PFX + msg + os.linesep) def run_wine(args): if lfile == None: subprocess.call(args, env=env) else: subprocess.call(args, env=env, stdout=lfile, stderr=subprocess.STDOUT) def makedirs(path): try: os.makedirs(path) except: #already exists pass if not ("STEAM_COMPAT_DATA_PATH" in os.environ): log("No compat data path?") sys.exit(1) if "STEAM_COMPAT_CONFIG" in os.environ: config = os.environ["STEAM_COMPAT_CONFIG"] basedir = os.path.dirname(sys.argv[0]) bindir = basedir + "/dist/bin/" libdir = basedir + "/dist/lib64:" + basedir + "/dist/lib" wine_path = bindir + "/wine64" #extract if needed if not os.path.exists(basedir + "/dist") or \ not os.path.exists(basedir + "/dist/version") or \ not filecmp.cmp(basedir + "/version", basedir + "/dist/version"): if os.path.exists(basedir + "/dist"): shutil.rmtree(basedir + "/dist") tar = tarfile.open(basedir + "/proton_dist.tar.gz", mode="r:gz") tar.extractall(path=basedir + "/dist") tar.close() shutil.copy(basedir + "/version", basedir + "/dist/") env = dict(os.environ) env["WINEDEBUG"] = "-all" lfile_path = None #env["WINEDEBUG"] = "+tid,+seh,+steamclient" #lfile_path = env["HOME"] + "/steam-" + env["SteamGameId"] + ".log" if not lfile_path is None: if os.path.exists(lfile_path): os.remove(lfile_path) lfile = open(lfile_path, "w") else: lfile = None if "LD_LIBRARY_PATH" in os.environ: env["LD_LIBRARY_PATH"] = libdir + ":" + env["LD_LIBRARY_PATH"] else: env["LD_LIBRARY_PATH"] = libdir if not os.path.isdir(basedir + "/dist/share/default_pfx"): #make default prefix env["WINEPREFIX"] = basedir + "/dist/share/default_pfx" run_wine([wine_path, "wineboot"]) run_wine([bindir + "/wineserver", "-w"]) prefix = os.environ["STEAM_COMPAT_DATA_PATH"] + "/pfx/" env["WINEPREFIX"] = prefix if not os.path.isdir(prefix): #copy default prefix into place shutil.copytree(basedir + "/dist/share/default_pfx", prefix, symlinks=True) #copy steam files into place steamdir = env["HOME"] + "/.steam/steam/legacycompat/" dst = prefix + "/drive_c/Program Files (x86)/" makedirs(dst + "Steam") filestocopy = ["steamclient.dll", "steamclient64.dll", "Steam.dll"] for f in filestocopy: if os.path.isfile(steamdir + f): shutil.copy(steamdir + f, dst + "Steam/" + f) #copy openvr files into place dst = prefix + "/drive_c/vrclient/bin/" makedirs(dst) shutil.copy(basedir + "/dist/lib/wine/fakedlls/vrclient.dll", dst) shutil.copy(basedir + "/dist/lib64/wine/fakedlls/vrclient_x64.dll", dst) #parse linux openvr config and present it in win32 format to the app. #logic from openvr's CVRPathRegistry_Public::GetPaths #check environment for overrides vr_runtime = None if "VR_OVERRIDE" in env: vr_runtime = env["VR_OVERRIDE"] env.pop("VR_OVERRIDE") vr_config = None if "VR_CONFIG_PATH" in env: vr_config = env["VR_CONFIG_PATH"] env.pop("VR_CONFIG_PATH") vr_log = None if "VR_LOG_PATH" in env: vr_log = env["VR_LOG_PATH"] env.pop("VR_LOG_PATH") #load from json if needed if vr_runtime is None or \ vr_config is None or \ vr_log is None: try: if "XDG_CONFIG_HOME" in env: path = env["XDG_CONFIG_HOME"] else: path = env["HOME"] + "/.config" path = path + "/openvr/openvrpaths.vrpath" j = json.load(open(path, "r")) if vr_runtime is None: vr_runtime = j["runtime"][0] if vr_config is None: vr_config = j["config"][0] if vr_log is None: vr_log = j["log"][0] except: pass makedirs(prefix + "/drive_c/users/steamuser/Local Settings/Application Data/openvr") #remove existing file vrpaths_name = prefix + "/drive_c/users/steamuser/Local Settings/Application Data/openvr/openvrpaths.vrpath" if os.path.exists(vrpaths_name): os.remove(vrpaths_name) #dump new file if not vr_runtime is None: try: env["PROTON_VR_RUNTIME"] = vr_runtime j = { "runtime": [ "C:\\vrclient\\", "C:\\vrclient" ] } if not vr_config is None: win_vr_config = subprocess.check_output([wine_path, "winepath", "-w", vr_config], env=env, stderr=open("/dev/null", "w")) j["config"] = [ win_vr_config.strip() ] if not vr_log is None: win_vr_log = subprocess.check_output([wine_path, "winepath", "-w", vr_log], env=env, stderr=open("/dev/null", "w")) j["log"] = [ win_vr_log.strip() ] j["version"] = 1 j["jsonid"] = "vrpathreg" json.dump(j, open(vrpaths_name, "w"), indent=2) except: pass #start target app run_wine([wine_path] + sys.argv[1:]) sys.exit(0)