proton: Move session globals into Session class

This commit is contained in:
Andrew Eikum 2019-07-29 13:06:51 -05:00
parent 975875265c
commit adcdea1315

219
proton
View file

@ -45,7 +45,7 @@ def file_is_wine_fake_dll(path):
return False return False
def run_wine(args): def run_wine(args):
subprocess.call(args, env=env, stderr=lfile, stdout=lfile) subprocess.call(args, env=g_session.env, stderr=g_session.log_file, stdout=g_session.log_file)
def makedirs(path): def makedirs(path):
try: try:
@ -261,7 +261,7 @@ class CompatData:
else: else:
os.symlink(fname, lname) os.symlink(fname, lname)
def setup_prefix(self, config_opts): def setup_prefix(self):
with self.prefix_lock: with self.prefix_lock:
if os.path.exists(self.version_file): if os.path.exists(self.version_file):
with open(self.version_file, "r") as f: with open(self.version_file, "r") as f:
@ -315,19 +315,19 @@ class CompatData:
#check environment for overrides #check environment for overrides
vr_runtime = None vr_runtime = None
if "VR_OVERRIDE" in env: if "VR_OVERRIDE" in g_session.env:
vr_runtime = env["VR_OVERRIDE"] vr_runtime = g_session.env["VR_OVERRIDE"]
env.pop("VR_OVERRIDE") g_session.env.pop("VR_OVERRIDE")
vr_config = None vr_config = None
if "VR_CONFIG_PATH" in env: if "VR_CONFIG_PATH" in g_session.env:
vr_config = env["VR_CONFIG_PATH"] vr_config = g_session.env["VR_CONFIG_PATH"]
env.pop("VR_CONFIG_PATH") g_session.env.pop("VR_CONFIG_PATH")
vr_log = None vr_log = None
if "VR_LOG_PATH" in env: if "VR_LOG_PATH" in g_session.env:
vr_log = env["VR_LOG_PATH"] vr_log = g_session.env["VR_LOG_PATH"]
env.pop("VR_LOG_PATH") g_session.env.pop("VR_LOG_PATH")
#load from json if needed #load from json if needed
if vr_runtime is None or \ if vr_runtime is None or \
@ -361,16 +361,16 @@ class CompatData:
#dump new file #dump new file
if not vr_runtime is None: if not vr_runtime is None:
try: try:
env["PROTON_VR_RUNTIME"] = vr_runtime g_session.env["PROTON_VR_RUNTIME"] = vr_runtime
j = { "runtime": [ "C:\\vrclient\\", "C:\\vrclient" ] } j = { "runtime": [ "C:\\vrclient\\", "C:\\vrclient" ] }
if not vr_config is None: if not vr_config is None:
win_vr_config = subprocess.check_output([g_proton.wine_bin, "winepath", "-w", vr_config], env=env, stderr=lfile).decode("utf-8") win_vr_config = subprocess.check_output([g_proton.wine_bin, "winepath", "-w", vr_config], env=g_session.env, stderr=g_session.log_file).decode("utf-8")
j["config"] = [ win_vr_config.strip() ] j["config"] = [ win_vr_config.strip() ]
if not vr_log is None: if not vr_log is None:
win_vr_log = subprocess.check_output([g_proton.wine_bin, "winepath", "-w", vr_log], env=env, stderr=lfile).decode("utf-8") win_vr_log = subprocess.check_output([g_proton.wine_bin, "winepath", "-w", vr_log], env=g_session.env, stderr=g_session.log_file).decode("utf-8")
j["log"] = [ win_vr_log.strip() ] j["log"] = [ win_vr_log.strip() ]
j["version"] = 1 j["version"] = 1
@ -381,13 +381,13 @@ class CompatData:
except (ValueError, OSError): except (ValueError, OSError):
log("Unable to write VR config! " + str(sys.exc_info()[1])) log("Unable to write VR config! " + str(sys.exc_info()[1]))
if "wined3d" in config_opts: if "wined3d" in g_session.compat_config:
dxvkfiles = [] dxvkfiles = []
wined3dfiles = ["d3d11", "d3d10", "d3d10core", "d3d10_1", "dxgi", "d3d9"] wined3dfiles = ["d3d11", "d3d10", "d3d10core", "d3d10_1", "dxgi", "d3d9"]
else: else:
dxvkfiles = ["d3d11", "d3d10", "d3d10core", "d3d10_1", "dxgi"] dxvkfiles = ["d3d11", "d3d10", "d3d10core", "d3d10_1", "dxgi"]
wined3dfiles = [] wined3dfiles = []
if "d9vk" in config_opts: if "d9vk" in g_session.compat_config:
dxvkfiles.append("d3d9") dxvkfiles.append("d3d9")
else: else:
wined3dfiles.append("d3d9") wined3dfiles.append("d3d9")
@ -403,7 +403,20 @@ class CompatData:
self.prefix_dir + "drive_c/windows/system32/" + f + ".dll") self.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",
self.prefix_dir + "drive_c/windows/syswow64/" + f + ".dll") self.prefix_dir + "drive_c/windows/syswow64/" + f + ".dll")
dlloverrides[f] = "n" g_session.dlloverrides[f] = "n"
class Session:
def __init__(self):
self.log_file = None
self.env = dict(os.environ)
self.dlloverrides = {
"steam.exe": "b", #always use our special built-in steam.exe
"mfplay": "n" #disable built-in mfplay
}
if "STEAM_COMPAT_CONFIG" in os.environ:
self.compat_config = set(os.environ["STEAM_COMPAT_CONFIG"].split(","))
else:
self.compat_config = set()
if not "STEAM_COMPAT_DATA_PATH" in os.environ: if not "STEAM_COMPAT_DATA_PATH" in os.environ:
@ -416,54 +429,50 @@ g_proton.extract_tarball()
g_compatdata = CompatData(os.environ["STEAM_COMPAT_DATA_PATH"]) g_compatdata = CompatData(os.environ["STEAM_COMPAT_DATA_PATH"])
env = dict(os.environ) g_session = Session()
dlloverrides = {
"steam.exe": "b", #always use our special built-in steam.exe
"mfplay": "n" #disable built-in mfplay
}
if "HOST_LC_ALL" in env and len(env["HOST_LC_ALL"]) > 0: if "HOST_LC_ALL" in g_session.env and len(g_session.env["HOST_LC_ALL"]) > 0:
#steam sets LC_ALL=C to help some games, but Wine requires the real value #steam sets LC_ALL=C to help some games, but Wine requires the real value
#in order to do path conversion between win32 and host. steam sets #in order to do path conversion between win32 and host. steam sets
#HOST_LC_ALL to allow us to use the real value. #HOST_LC_ALL to allow us to use the real value.
env["LC_ALL"] = env["HOST_LC_ALL"] g_session.env["LC_ALL"] = g_session.env["HOST_LC_ALL"]
else: else:
env.pop("LC_ALL", "") g_session.env.pop("LC_ALL", "")
#for performance, logging is disabled by default; override with user_settings.py #for performance, logging is disabled by default; override with user_settings.py
env["DXVK_LOG_LEVEL"] = "none" g_session.env["DXVK_LOG_LEVEL"] = "none"
env["WINEDEBUG"] = "-all" g_session.env["WINEDEBUG"] = "-all"
env.pop("WINEARCH", "") g_session.env.pop("WINEARCH", "")
if ld_path_var in os.environ: if ld_path_var in os.environ:
env[ld_path_var] = g_proton.lib64_dir + ":" + g_proton.lib_dir + ":" + os.environ[ld_path_var] g_session.env[ld_path_var] = g_proton.lib64_dir + ":" + g_proton.lib_dir + ":" + os.environ[ld_path_var]
else: else:
env[ld_path_var] = g_proton.lib64_dir + ":" + g_proton.lib_dir g_session.env[ld_path_var] = g_proton.lib64_dir + ":" + g_proton.lib_dir
env["WINEDLLPATH"] = g_proton.lib64_dir + "/wine:" + g_proton.lib_dir + "/wine" g_session.env["WINEDLLPATH"] = g_proton.lib64_dir + "/wine:" + g_proton.lib_dir + "/wine"
if "PATH" in os.environ: if "PATH" in os.environ:
env["PATH"] = g_proton.bin_dir + ":" + os.environ["PATH"] g_session.env["PATH"] = g_proton.bin_dir + ":" + os.environ["PATH"]
else: else:
env["PATH"] = g_proton.bin_dir g_session.env["PATH"] = g_proton.bin_dir
g_proton.make_default_prefix(env) g_proton.make_default_prefix(g_session.env)
env["WINEPREFIX"] = g_compatdata.prefix_dir g_session.env["WINEPREFIX"] = g_compatdata.prefix_dir
if "PROTON_LOG" in env and nonzero(env["PROTON_LOG"]): if "PROTON_LOG" in g_session.env and nonzero(g_session.env["PROTON_LOG"]):
env["WINEDEBUG"] = "+timestamp,+pid,+tid,+seh,+debugstr,+loaddll,+mscoree" g_session.env["WINEDEBUG"] = "+timestamp,+pid,+tid,+seh,+debugstr,+loaddll,+mscoree"
env["DXVK_LOG_LEVEL"] = "info" g_session.env["DXVK_LOG_LEVEL"] = "info"
env["WINE_MONO_TRACE"] = "E:System.NotImplementedException" g_session.env["WINE_MONO_TRACE"] = "E:System.NotImplementedException"
#default wine-mono override for FNA games #default wine-mono override for FNA games
env["WINE_MONO_OVERRIDES"] = "Microsoft.Xna.Framework.*,Gac=n" g_session.env["WINE_MONO_OVERRIDES"] = "Microsoft.Xna.Framework.*,Gac=n"
#load environment overrides #load environment overrides
if os.path.exists(g_proton.user_settings_file): if os.path.exists(g_proton.user_settings_file):
try: try:
import user_settings import user_settings
env.update(user_settings.user_settings) g_session.env.update(user_settings.user_settings)
except: except:
log("************************************************") log("************************************************")
log("THERE IS AN ERROR IN YOUR user_settings.py FILE:") log("THERE IS AN ERROR IN YOUR user_settings.py FILE:")
@ -471,21 +480,16 @@ if os.path.exists(g_proton.user_settings_file):
log("************************************************") log("************************************************")
def check_environment(env_name, config_name): def check_environment(env_name, config_name):
if not env_name in env: if not env_name in g_session.env:
return False return False
if nonzero(env[env_name]): if nonzero(g_session.env[env_name]):
config_opts.add(config_name) g_session.compat_config.add(config_name)
else: else:
config_opts.discard(config_name) g_session.compat_config.discard(config_name)
return True return True
if "STEAM_COMPAT_CONFIG" in os.environ: if "wined3d11" in g_session.compat_config:
config_opts = set(os.environ["STEAM_COMPAT_CONFIG"].split(",")) g_session.compat_config.add("wined3d")
else:
config_opts = set()
if "wined3d11" in config_opts:
config_opts.add("wined3d")
if not check_environment("PROTON_USE_WINED3D", "wined3d"): if not check_environment("PROTON_USE_WINED3D", "wined3d"):
check_environment("PROTON_USE_WINED3D11", "wined3d") check_environment("PROTON_USE_WINED3D11", "wined3d")
@ -497,92 +501,91 @@ check_environment("PROTON_NO_FSYNC", "nofsync")
check_environment("PROTON_FORCE_LARGE_ADDRESS_AWARE", "forcelgadd") check_environment("PROTON_FORCE_LARGE_ADDRESS_AWARE", "forcelgadd")
check_environment("PROTON_OLD_GL_STRING", "oldglstr") check_environment("PROTON_OLD_GL_STRING", "oldglstr")
if not "noesync" in config_opts: if not "noesync" in g_session.compat_config:
env["WINEESYNC"] = "1" g_session.env["WINEESYNC"] = "1"
if not "nofsync" in config_opts: if not "nofsync" in g_session.compat_config:
env["WINEFSYNC"] = "1" g_session.env["WINEFSYNC"] = "1"
if "oldglstr" in config_opts: if "oldglstr" in g_session.compat_config:
#mesa override #mesa override
env["MESA_EXTENSION_MAX_YEAR"] = "2003" g_session.env["MESA_EXTENSION_MAX_YEAR"] = "2003"
#nvidia override #nvidia override
env["__GL_ExtensionStringVersion"] = "17700" g_session.env["__GL_ExtensionStringVersion"] = "17700"
if "forcelgadd" in config_opts: if "forcelgadd" in g_session.compat_config:
#forcelgadd should be used just for testing whether a game is helped by #forcelgadd should be used just for testing whether a game is helped by
#setting LARGE_ADDRESS_AWARE. If it does, then add an AppDefault in the #setting LARGE_ADDRESS_AWARE. If it does, then add an AppDefault in the
#registry, so that it doesn't impact every executable in the prefix. #registry, so that it doesn't impact every executable in the prefix.
env["WINE_LARGE_ADDRESS_AWARE"] = "1" g_session.env["WINE_LARGE_ADDRESS_AWARE"] = "1"
lfile = None if "SteamGameId" in g_session.env:
if "SteamGameId" in env: if g_session.env["WINEDEBUG"] != "-all":
if env["WINEDEBUG"] != "-all":
lfile_path = os.environ["HOME"] + "/steam-" + os.environ["SteamGameId"] + ".log" lfile_path = os.environ["HOME"] + "/steam-" + os.environ["SteamGameId"] + ".log"
if os.path.exists(lfile_path): if os.path.exists(lfile_path):
os.remove(lfile_path) os.remove(lfile_path)
lfile = open(lfile_path, "w+") g_session.log_file = open(lfile_path, "w+")
lfile.write("======================\n") g_session.log_file.write("======================\n")
with open(g_proton.version_file, "r") as f: with open(g_proton.version_file, "r") as f:
lfile.write("Proton: " + f.readline().strip() + "\n") g_session.log_file.write("Proton: " + f.readline().strip() + "\n")
lfile.write("SteamGameId: " + env["SteamGameId"] + "\n") g_session.log_file.write("SteamGameId: " + g_session.env["SteamGameId"] + "\n")
lfile.write("Command: " + str(sys.argv[2:]) + "\n") g_session.log_file.write("Command: " + str(sys.argv[2:]) + "\n")
lfile.write("Options: " + str(config_opts) + "\n") g_session.log_file.write("Options: " + str(g_session.compat_config) + "\n")
lfile.write("======================\n") g_session.log_file.write("======================\n")
lfile.flush() g_session.log_file.flush()
else: else:
env["WINEDEBUG"] = "-all" g_session.env["WINEDEBUG"] = "-all"
g_compatdata.setup_prefix(config_opts) g_compatdata.setup_prefix()
if "nod3d11" in config_opts: if "nod3d11" in g_session.compat_config:
dlloverrides["d3d11"] = "" g_session.dlloverrides["d3d11"] = ""
if "dxgi" in dlloverrides: if "dxgi" in g_session.dlloverrides:
del dlloverrides["dxgi"] del g_session.dlloverrides["dxgi"]
if "nod3d10" in config_opts: if "nod3d10" in g_session.compat_config:
dlloverrides["d3d10_1"] = "" g_session.dlloverrides["d3d10_1"] = ""
dlloverrides["d3d10"] = "" g_session.dlloverrides["d3d10"] = ""
dlloverrides["dxgi"] = "" g_session.dlloverrides["dxgi"] = ""
s = "" s = ""
for dll in dlloverrides: for dll in g_session.dlloverrides:
setting = dlloverrides[dll] setting = g_session.dlloverrides[dll]
if len(s) > 0: if len(s) > 0:
s = s + ";" + dll + "=" + setting s = s + ";" + dll + "=" + setting
else: else:
s = dll + "=" + setting s = dll + "=" + setting
if "WINEDLLOVERRIDES" in os.environ: if "WINEDLLOVERRIDES" in os.environ:
env["WINEDLLOVERRIDES"] = os.environ["WINEDLLOVERRIDES"] + ";" + s g_session.env["WINEDLLOVERRIDES"] = os.environ["WINEDLLOVERRIDES"] + ";" + s
else: else:
env["WINEDLLOVERRIDES"] = s g_session.env["WINEDLLOVERRIDES"] = s
def dump_dbg_env(f): def dump_dbg_env(f):
f.write("PATH=\"" + env["PATH"] + "\" \\\n") f.write("PATH=\"" + g_session.env["PATH"] + "\" \\\n")
f.write("\tTERM=\"xterm\" \\\n") #XXX f.write("\tTERM=\"xterm\" \\\n") #XXX
f.write("\tWINEDEBUG=\"-all\" \\\n") f.write("\tWINEDEBUG=\"-all\" \\\n")
f.write("\tWINEDLLPATH=\"" + env["WINEDLLPATH"] + "\" \\\n") f.write("\tWINEDLLPATH=\"" + g_session.env["WINEDLLPATH"] + "\" \\\n")
f.write("\t" + ld_path_var + "=\"" + env[ld_path_var] + "\" \\\n") f.write("\t" + ld_path_var + "=\"" + g_session.env[ld_path_var] + "\" \\\n")
f.write("\tWINEPREFIX=\"" + env["WINEPREFIX"] + "\" \\\n") f.write("\tWINEPREFIX=\"" + g_session.env["WINEPREFIX"] + "\" \\\n")
if "WINEESYNC" in env: if "WINEESYNC" in g_session.env:
f.write("\tWINEESYNC=\"" + env["WINEESYNC"] + "\" \\\n") f.write("\tWINEESYNC=\"" + g_session.env["WINEESYNC"] + "\" \\\n")
if "SteamGameId" in env: if "SteamGameId" in g_session.env:
f.write("\tSteamGameId=\"" + env["SteamGameId"] + "\" \\\n") f.write("\tSteamGameId=\"" + g_session.env["SteamGameId"] + "\" \\\n")
if "SteamAppId" in env: if "SteamAppId" in g_session.env:
f.write("\tSteamAppId=\"" + env["SteamAppId"] + "\" \\\n") f.write("\tSteamAppId=\"" + g_session.env["SteamAppId"] + "\" \\\n")
if "PROTON_VR_RUNTIME" in env: if "PROTON_VR_RUNTIME" in g_session.env:
f.write("\tPROTON_VR_RUNTIME=\"" + env["PROTON_VR_RUNTIME"] + "\" \\\n") f.write("\tPROTON_VR_RUNTIME=\"" + g_session.env["PROTON_VR_RUNTIME"] + "\" \\\n")
if "WINEDLLOVERRIDES" in env: if "WINEDLLOVERRIDES" in g_session.env:
f.write("\tWINEDLLOVERRIDES=\"" + env["WINEDLLOVERRIDES"] + "\" \\\n") f.write("\tWINEDLLOVERRIDES=\"" + g_session.env["WINEDLLOVERRIDES"] + "\" \\\n")
if "STEAM_COMPAT_CLIENT_INSTALL_PATH" in env: if "STEAM_COMPAT_CLIENT_INSTALL_PATH" in g_session.env:
f.write("\tSTEAM_COMPAT_CLIENT_INSTALL_PATH=\"" + env["STEAM_COMPAT_CLIENT_INSTALL_PATH"] + "\" \\\n") f.write("\tSTEAM_COMPAT_CLIENT_INSTALL_PATH=\"" + g_session.env["STEAM_COMPAT_CLIENT_INSTALL_PATH"] + "\" \\\n")
if "WINE_LARGE_ADDRESS_AWARE" in env: if "WINE_LARGE_ADDRESS_AWARE" in g_session.env:
f.write("\tWINE_LARGE_ADDRESS_AWARE=\"" + env["WINE_LARGE_ADDRESS_AWARE"] + "\" \\\n") f.write("\tWINE_LARGE_ADDRESS_AWARE=\"" + g_session.env["WINE_LARGE_ADDRESS_AWARE"] + "\" \\\n")
def dump_dbg_scripts(): def dump_dbg_scripts():
exe_name = os.path.basename(sys.argv[2]) exe_name = os.path.basename(sys.argv[2])
tmpdir = env.get("PROTON_DEBUG_DIR", "/tmp") + "/proton_" + os.environ["USER"] + "/" tmpdir = g_session.env.get("PROTON_DEBUG_DIR", "/tmp") + "/proton_" + os.environ["USER"] + "/"
makedirs(tmpdir) makedirs(tmpdir)
with open(tmpdir + "winedbg", "w") as f: with open(tmpdir + "winedbg", "w") as f:
@ -660,7 +663,7 @@ def dump_dbg_scripts():
os.chmod(tmpdir + "run", 0o755) os.chmod(tmpdir + "run", 0o755)
def run(): def run():
if "PROTON_DUMP_DEBUG_COMMANDS" in env and nonzero(env["PROTON_DUMP_DEBUG_COMMANDS"]): if "PROTON_DUMP_DEBUG_COMMANDS" in g_session.env and nonzero(g_session.env["PROTON_DUMP_DEBUG_COMMANDS"]):
try: try:
dump_dbg_scripts() dump_dbg_scripts()
except OSError: except OSError:
@ -685,11 +688,11 @@ elif sys.argv[1] == "waitforexitandrun":
run() run()
elif sys.argv[1] == "getcompatpath": elif sys.argv[1] == "getcompatpath":
#linux -> windows path #linux -> windows path
path = subprocess.check_output([g_proton.wine_bin, "winepath", "-w", sys.argv[2]], env=env, stderr=lfile) path = subprocess.check_output([g_proton.wine_bin, "winepath", "-w", sys.argv[2]], env=g_session.env, stderr=g_session.log_file)
binary_stdout.write(path) binary_stdout.write(path)
elif sys.argv[1] == "getnativepath": elif sys.argv[1] == "getnativepath":
#windows -> linux path #windows -> linux path
path = subprocess.check_output([g_proton.wine_bin, "winepath", sys.argv[2]], env=env, stderr=lfile) path = subprocess.check_output([g_proton.wine_bin, "winepath", sys.argv[2]], env=g_session.env, stderr=g_session.log_file)
binary_stdout.write(path) binary_stdout.write(path)
else: else:
log("Need a verb.") log("Need a verb.")