From c1b855900681840d022e9e750e36658a62a6dd94 Mon Sep 17 00:00:00 2001 From: Rankyn Bass Date: Sat, 31 Aug 2024 16:03:29 -0700 Subject: [PATCH 1/7] Add nvapi handling --- .../Compatibility/CompatibilityTools.cs | 51 ++++++++++++++++++- .../Compatibility/DxvkSettings.cs | 19 ++++++- 2 files changed, 67 insertions(+), 3 deletions(-) diff --git a/src/XIVLauncher.Common.Unix/Compatibility/CompatibilityTools.cs b/src/XIVLauncher.Common.Unix/Compatibility/CompatibilityTools.cs index afe438859..9fbbe7004 100644 --- a/src/XIVLauncher.Common.Unix/Compatibility/CompatibilityTools.cs +++ b/src/XIVLauncher.Common.Unix/Compatibility/CompatibilityTools.cs @@ -71,7 +71,11 @@ public async Task EnsureTool(DirectoryInfo tempPath) EnsurePrefix(); if (DxvkSettings.Enabled) + { await InstallDxvk().ConfigureAwait(false); + if (DxvkSettings.NvapiEnabled) + await InstallNvapi().ConfigureAwait(false); + } IsToolReady = true; } @@ -93,7 +97,50 @@ private async Task InstallDxvk() File.Copy(fileName, Path.Combine(system32, Path.GetFileName(fileName)), true); } - // 32-bit files for Directx9. + // 32-bit files for Directx9. Only needed for external programs. + var dxvkPath32 = Path.Combine(dxvkDirectory.FullName, DxvkSettings.FolderName, "x32"); + var syswow64 = Path.Combine(Settings.Prefix.FullName, "drive_c", "windows", "syswow64"); + + if (Directory.Exists(dxvkPath32)) + { + files = Directory.GetFiles(dxvkPath32); + + foreach (string fileName in files) + { + File.Copy(fileName, Path.Combine(syswow64, Path.GetFileName(fileName)), true); + } + } + } + + private async Task InstallNvapi() + { + var dxvkPath = Path.Combine(dxvkDirectory.FullName, DxvkSettings.NvapiFolderName, "x64"); + if (!Directory.Exists(dxvkPath)) + { + Log.Information($"DXVK Nvapi does not exist, downloading {DxvkSettings.DownloadNvapiUrl}"); + await DownloadTool(dxvkDirectory, DxvkSettings.DownloadUrl).ConfigureAwait(false); + } + + var system32 = Path.Combine(Settings.Prefix.FullName, "drive_c", "windows", "system32"); + var files = Directory.GetFiles(dxvkPath); + + foreach (string fileName in files) + { + File.Copy(fileName, Path.Combine(system32, Path.GetFileName(fileName)), true); + } + + // Copy nvngx files + if (!string.IsNullOrEmpty(DxvkSettings.NvngxFolder) && Directory.Exists(DxvkSettings.NvngxFolder)) + { + files = Directory.GetFiles(DxvkSettings.NvngxFolder); + + foreach (string fileName in files) + { + File.Copy(fileName, Path.Combine(system32, Path.GetFileName(fileName)), true); + } + } + + // 32-bit files for Directx9. Only needed for external programs. var dxvkPath32 = Path.Combine(dxvkDirectory.FullName, DxvkSettings.FolderName, "x32"); var syswow64 = Path.Combine(Settings.Prefix.FullName, "drive_c", "windows", "syswow64"); @@ -105,7 +152,7 @@ private async Task InstallDxvk() { File.Copy(fileName, Path.Combine(syswow64, Path.GetFileName(fileName)), true); } - } + } } private async Task DownloadTool(DirectoryInfo installDirectory, string downloadUrl) diff --git a/src/XIVLauncher.Common.Unix/Compatibility/DxvkSettings.cs b/src/XIVLauncher.Common.Unix/Compatibility/DxvkSettings.cs index db657bbc0..24db23066 100644 --- a/src/XIVLauncher.Common.Unix/Compatibility/DxvkSettings.cs +++ b/src/XIVLauncher.Common.Unix/Compatibility/DxvkSettings.cs @@ -14,12 +14,23 @@ public class DxvkSettings public string DownloadUrl { get; } + public string NvapiFolderName { get; } + + public string NvapiDownloadUrl { get; } + + public string NvngxFolder { get; } + + public bool NvapiEnabled => !string.IsNullOrEmpty(NvapiFolderName) && Enabled; + public Dictionary Environment { get; } - public DxvkSettings(string folder, string url, string storageFolder, bool async, int maxFrameRate, bool dxvkHudEnabled, string dxvkHudString, bool mangoHudEnabled = false, bool mangoHudCustomIsFile = false, string customMangoHud = "", bool enabled = true) + public DxvkSettings(string folder, string url, string storageFolder, bool async, int maxFrameRate, bool dxvkHudEnabled, string dxvkHudString, bool mangoHudEnabled = false, bool mangoHudCustomIsFile = false, string customMangoHud = "", bool enabled = true, string nvapiFolder = "", string nvapiUrl = "", string nvngxFolder = "") { FolderName = folder; DownloadUrl = url; + NvapiFolderName = nvapiFolder; + NvapiDownloadUrl = nvapiUrl; + NvngxFolder = nvngxFolder; Enabled = enabled; var dxvkConfigPath = new DirectoryInfo(Path.Combine(storageFolder, "compatibilitytool", "dxvk")); @@ -57,6 +68,12 @@ public DxvkSettings(string folder, string url, string storageFolder, bool async, Environment.Add("MANGOHUD_CONFIG", customMangoHud); } } + + if (!string.IsNullOrEmpty(NvapiFolderName)) + { + Environment.Add("DXVK_ENABLE_NVAPI", "1"); + Environment.Add("DXKV_CONFIG", "dxgi.nvapiHack = False; dxgi.hideNvidiaGpu = False"); + } } public static bool DxvkHudStringIsValid(string customHud) From 220958de7c2923fc3ed0149de4e6671fdcde5365 Mon Sep 17 00:00:00 2001 From: Rankyn Bass Date: Sat, 31 Aug 2024 16:10:46 -0700 Subject: [PATCH 2/7] Fix variable name typo --- src/XIVLauncher.Common.Unix/Compatibility/CompatibilityTools.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/XIVLauncher.Common.Unix/Compatibility/CompatibilityTools.cs b/src/XIVLauncher.Common.Unix/Compatibility/CompatibilityTools.cs index 9fbbe7004..4d4753655 100644 --- a/src/XIVLauncher.Common.Unix/Compatibility/CompatibilityTools.cs +++ b/src/XIVLauncher.Common.Unix/Compatibility/CompatibilityTools.cs @@ -117,7 +117,7 @@ private async Task InstallNvapi() var dxvkPath = Path.Combine(dxvkDirectory.FullName, DxvkSettings.NvapiFolderName, "x64"); if (!Directory.Exists(dxvkPath)) { - Log.Information($"DXVK Nvapi does not exist, downloading {DxvkSettings.DownloadNvapiUrl}"); + Log.Information($"DXVK Nvapi does not exist, downloading {DxvkSettings.NvapiDownloadUrl}"); await DownloadTool(dxvkDirectory, DxvkSettings.DownloadUrl).ConfigureAwait(false); } From 42fb88efdf8d182338437c0cc70382714270267e Mon Sep 17 00:00:00 2001 From: Rankyn Bass Date: Sat, 31 Aug 2024 19:05:54 -0700 Subject: [PATCH 3/7] Copy nvngx files to game path instead of prefix --- .../Compatibility/CompatibilityTools.cs | 35 +++++++++++-------- .../Compatibility/DxvkSettings.cs | 16 +++++++-- 2 files changed, 34 insertions(+), 17 deletions(-) diff --git a/src/XIVLauncher.Common.Unix/Compatibility/CompatibilityTools.cs b/src/XIVLauncher.Common.Unix/Compatibility/CompatibilityTools.cs index 4d4753655..9d9c6e581 100644 --- a/src/XIVLauncher.Common.Unix/Compatibility/CompatibilityTools.cs +++ b/src/XIVLauncher.Common.Unix/Compatibility/CompatibilityTools.cs @@ -20,6 +20,8 @@ public class CompatibilityTools private DirectoryInfo dxvkDirectory; + private DirectoryInfo GamePath; + private StreamWriter logWriter; public bool IsToolReady { get; private set; } @@ -36,7 +38,7 @@ public class CompatibilityTools private Dictionary extraEnvironmentVars; - public CompatibilityTools(WineSettings wineSettings, DxvkSettings dxvkSettings, bool? gamemodeOn, DirectoryInfo toolsFolder, bool isFlatpak, Dictionary extraEnvVars = null) + public CompatibilityTools(WineSettings wineSettings, DxvkSettings dxvkSettings, bool? gamemodeOn, DirectoryInfo toolsFolder, DirectoryInfo gamePath, bool isFlatpak, Dictionary extraEnvVars = null) { this.Settings = wineSettings; this.DxvkSettings = dxvkSettings; @@ -49,6 +51,8 @@ public CompatibilityTools(WineSettings wineSettings, DxvkSettings dxvkSettings, this.wineDirectory = new DirectoryInfo(Path.Combine(toolsFolder.FullName, "wine")); this.dxvkDirectory = new DirectoryInfo(Path.Combine(toolsFolder.FullName, "dxvk")); + this.GamePath = gamePath; + this.logWriter = new StreamWriter(wineSettings.LogFile.FullName); if (!this.wineDirectory.Exists) @@ -71,11 +75,10 @@ public async Task EnsureTool(DirectoryInfo tempPath) EnsurePrefix(); if (DxvkSettings.Enabled) - { await InstallDxvk().ConfigureAwait(false); - if (DxvkSettings.NvapiEnabled) - await InstallNvapi().ConfigureAwait(false); - } + + if (DxvkSettings.NvapiEnabled) + await InstallNvapi().ConfigureAwait(false); IsToolReady = true; } @@ -118,7 +121,9 @@ private async Task InstallNvapi() if (!Directory.Exists(dxvkPath)) { Log.Information($"DXVK Nvapi does not exist, downloading {DxvkSettings.NvapiDownloadUrl}"); - await DownloadTool(dxvkDirectory, DxvkSettings.DownloadUrl).ConfigureAwait(false); + var nvapiFolder = new DirectoryInfo(Path.Combine(dxvkDirectory.FullName, DxvkSettings.NvapiFolderName)); + nvapiFolder.Create(); + await DownloadTool(nvapiFolder, DxvkSettings.NvapiDownloadUrl).ConfigureAwait(false); } var system32 = Path.Combine(Settings.Prefix.FullName, "drive_c", "windows", "system32"); @@ -129,19 +134,15 @@ private async Task InstallNvapi() File.Copy(fileName, Path.Combine(system32, Path.GetFileName(fileName)), true); } - // Copy nvngx files + // Copy nvngx.dll and _nvngx.dll to the GamePath. For some reason it doesn't work if you put them in system32. if (!string.IsNullOrEmpty(DxvkSettings.NvngxFolder) && Directory.Exists(DxvkSettings.NvngxFolder)) { - files = Directory.GetFiles(DxvkSettings.NvngxFolder); - - foreach (string fileName in files) - { - File.Copy(fileName, Path.Combine(system32, Path.GetFileName(fileName)), true); - } + File.Copy(Path.Combine(DxvkSettings.NvngxFolder, "nvngx.dll"), Path.Combine(GamePath.FullName, "game", "nvngx.dll"), true); + File.Copy(Path.Combine(DxvkSettings.NvngxFolder, "_nvngx.dll"), Path.Combine(GamePath.FullName, "game", "_nvngx.dll"), true); } // 32-bit files for Directx9. Only needed for external programs. - var dxvkPath32 = Path.Combine(dxvkDirectory.FullName, DxvkSettings.FolderName, "x32"); + var dxvkPath32 = Path.Combine(dxvkDirectory.FullName, DxvkSettings.NvapiFolderName, "x32"); var syswow64 = Path.Combine(Settings.Prefix.FullName, "drive_c", "windows", "syswow64"); if (Directory.Exists(dxvkPath32)) @@ -155,6 +156,12 @@ private async Task InstallNvapi() } } + private void UninstallNvngx() + { + File.Delete(Path.Combine(GamePath.FullName, "game", "nvngx.dll")); + File.Delete(Path.Combine(GamePath.FullName, "game", "_nvngx.dll")); + } + private async Task DownloadTool(DirectoryInfo installDirectory, string downloadUrl) { using var client = new HttpClient(); diff --git a/src/XIVLauncher.Common.Unix/Compatibility/DxvkSettings.cs b/src/XIVLauncher.Common.Unix/Compatibility/DxvkSettings.cs index 24db23066..4dc9f6e0d 100644 --- a/src/XIVLauncher.Common.Unix/Compatibility/DxvkSettings.cs +++ b/src/XIVLauncher.Common.Unix/Compatibility/DxvkSettings.cs @@ -20,7 +20,7 @@ public class DxvkSettings public string NvngxFolder { get; } - public bool NvapiEnabled => !string.IsNullOrEmpty(NvapiFolderName) && Enabled; + public bool NvapiEnabled { get; } public Dictionary Environment { get; } @@ -33,6 +33,11 @@ public DxvkSettings(string folder, string url, string storageFolder, bool async, NvngxFolder = nvngxFolder; Enabled = enabled; + // Disable Nvapi if the NvapiFolderName is empty, if Dxvk is not enabled, or if the dxvk version is dxvk-1.x or dxvk-async-1.x + NvapiEnabled = (!string.IsNullOrEmpty(NvapiFolderName) && DxvkAllowsNvapi(FolderName) && Enabled); + System.Console.WriteLine($"NvapiEnabled = {NvapiEnabled}"); + + var dxvkConfigPath = new DirectoryInfo(Path.Combine(storageFolder, "compatibilitytool", "dxvk")); Environment = new Dictionary { @@ -69,10 +74,9 @@ public DxvkSettings(string folder, string url, string storageFolder, bool async, } } - if (!string.IsNullOrEmpty(NvapiFolderName)) + if (NvapiEnabled) { Environment.Add("DXVK_ENABLE_NVAPI", "1"); - Environment.Add("DXKV_CONFIG", "dxgi.nvapiHack = False; dxgi.hideNvidiaGpu = False"); } } @@ -91,6 +95,12 @@ public static bool DxvkHudStringIsValid(string customHud) return hudvars.All(hudvar => Regex.IsMatch(hudvar, ALLOWED_WORDS)); } + public static bool DxvkAllowsNvapi(string dxvkVersion) + { + var pattern = @"^dxvk-(async-)?1\.\d{1,2}(\.\d)?$"; + return !Regex.IsMatch(dxvkVersion, pattern); + } + public static bool MangoHudIsInstalled() { var usrLib = Path.Combine("/", "usr", "lib", "mangohud", "libMangoHud.so"); // fedora uses this From 4d70a8e8a133f0f91202044909c8f63f16cbf06c Mon Sep 17 00:00:00 2001 From: Rankyn Bass Date: Sat, 31 Aug 2024 19:11:37 -0700 Subject: [PATCH 4/7] Get rid of debug console line --- src/XIVLauncher.Common.Unix/Compatibility/DxvkSettings.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/XIVLauncher.Common.Unix/Compatibility/DxvkSettings.cs b/src/XIVLauncher.Common.Unix/Compatibility/DxvkSettings.cs index 4dc9f6e0d..440b0441f 100644 --- a/src/XIVLauncher.Common.Unix/Compatibility/DxvkSettings.cs +++ b/src/XIVLauncher.Common.Unix/Compatibility/DxvkSettings.cs @@ -35,8 +35,6 @@ public DxvkSettings(string folder, string url, string storageFolder, bool async, // Disable Nvapi if the NvapiFolderName is empty, if Dxvk is not enabled, or if the dxvk version is dxvk-1.x or dxvk-async-1.x NvapiEnabled = (!string.IsNullOrEmpty(NvapiFolderName) && DxvkAllowsNvapi(FolderName) && Enabled); - System.Console.WriteLine($"NvapiEnabled = {NvapiEnabled}"); - var dxvkConfigPath = new DirectoryInfo(Path.Combine(storageFolder, "compatibilitytool", "dxvk")); Environment = new Dictionary From 33f8b423d03be2103f8386759a152b21dc9c8825 Mon Sep 17 00:00:00 2001 From: Rankyn Bass Date: Sun, 1 Sep 2024 13:26:14 -0700 Subject: [PATCH 5/7] Forgot to stage some changes --- .../Compatibility/CompatibilityTools.cs | 37 +++++++++++++++++-- .../Compatibility/DxvkSettings.cs | 5 ++- 2 files changed, 37 insertions(+), 5 deletions(-) diff --git a/src/XIVLauncher.Common.Unix/Compatibility/CompatibilityTools.cs b/src/XIVLauncher.Common.Unix/Compatibility/CompatibilityTools.cs index 9d9c6e581..6e437b2be 100644 --- a/src/XIVLauncher.Common.Unix/Compatibility/CompatibilityTools.cs +++ b/src/XIVLauncher.Common.Unix/Compatibility/CompatibilityTools.cs @@ -134,11 +134,40 @@ private async Task InstallNvapi() File.Copy(fileName, Path.Combine(system32, Path.GetFileName(fileName)), true); } - // Copy nvngx.dll and _nvngx.dll to the GamePath. For some reason it doesn't work if you put them in system32. - if (!string.IsNullOrEmpty(DxvkSettings.NvngxFolder) && Directory.Exists(DxvkSettings.NvngxFolder)) + // Create symlinks to nvngx.dll and _nvngx.dll in the GamePath/game folder. For some reason it doesn't work if you put them in system32. + // If NvngxOverride is set, assume the files/symlinks are already there. For Nix compatibility, mostly. + if (!string.IsNullOrEmpty(DxvkSettings.NvngxFolder) && Directory.Exists(DxvkSettings.NvngxFolder) && !DxvkSettings.NvngxOverride) { - File.Copy(Path.Combine(DxvkSettings.NvngxFolder, "nvngx.dll"), Path.Combine(GamePath.FullName, "game", "nvngx.dll"), true); - File.Copy(Path.Combine(DxvkSettings.NvngxFolder, "_nvngx.dll"), Path.Combine(GamePath.FullName, "game", "_nvngx.dll"), true); + string[] targets = { "nvngx.dll", "_nvngx.dll"}; + foreach (var target in targets) + { + var source = new FileInfo(Path.Combine(DxvkSettings.NvngxFolder, target)); + var destination = new FileInfo(Path.Combine(GamePath.FullName, "game", target)); + if (source.Exists) + { + if (!destination.Exists) // No file, create link. + { + destination.CreateAsSymbolicLink(source.FullName); + Log.Verbose($"Making symbolic link at {destination.FullName} to {source.FullName}"); + } + else if (destination.ResolveLinkTarget(false) is null) // File exists, is not a symlink. Delete and create link. + { + destination.Delete(); + destination.CreateAsSymbolicLink(source.FullName); + Log.Verbose($"Replacing file at {destination.FullName} with symbolic link to {source.FullName}"); + } + else if (destination.ResolveLinkTarget(true).FullName != source.FullName) // Link exists, but does not point to source. Replace. + { + destination.Delete(); + destination.CreateAsSymbolicLink(source.FullName); + Log.Verbose($"Symbolic link at {destination.FullName} incorrectly links to {destination.ResolveLinkTarget(true).FullName}. Replacing with link to {source.FullName}"); + } + else + Log.Verbose($"Symbolic link at {destination.FullName} to {source.FullName} is correct."); + } + else + Log.Error($"Missing Nvidia dll! DLSS may not work. {target} not found in {DxvkSettings.NvngxFolder}"); + } } // 32-bit files for Directx9. Only needed for external programs. diff --git a/src/XIVLauncher.Common.Unix/Compatibility/DxvkSettings.cs b/src/XIVLauncher.Common.Unix/Compatibility/DxvkSettings.cs index 440b0441f..33f01ffa9 100644 --- a/src/XIVLauncher.Common.Unix/Compatibility/DxvkSettings.cs +++ b/src/XIVLauncher.Common.Unix/Compatibility/DxvkSettings.cs @@ -22,9 +22,11 @@ public class DxvkSettings public bool NvapiEnabled { get; } + public bool NvngxOverride { get; } + public Dictionary Environment { get; } - public DxvkSettings(string folder, string url, string storageFolder, bool async, int maxFrameRate, bool dxvkHudEnabled, string dxvkHudString, bool mangoHudEnabled = false, bool mangoHudCustomIsFile = false, string customMangoHud = "", bool enabled = true, string nvapiFolder = "", string nvapiUrl = "", string nvngxFolder = "") + public DxvkSettings(string folder, string url, string storageFolder, bool async, int maxFrameRate, bool dxvkHudEnabled, string dxvkHudString, bool mangoHudEnabled = false, bool mangoHudCustomIsFile = false, string customMangoHud = "", bool enabled = true, string nvapiFolder = "", string nvapiUrl = "", string nvngxFolder = "", bool nvngxOverride = false) { FolderName = folder; DownloadUrl = url; @@ -32,6 +34,7 @@ public DxvkSettings(string folder, string url, string storageFolder, bool async, NvapiDownloadUrl = nvapiUrl; NvngxFolder = nvngxFolder; Enabled = enabled; + NvngxOverride = nvngxOverride; // Disable Nvapi if the NvapiFolderName is empty, if Dxvk is not enabled, or if the dxvk version is dxvk-1.x or dxvk-async-1.x NvapiEnabled = (!string.IsNullOrEmpty(NvapiFolderName) && DxvkAllowsNvapi(FolderName) && Enabled); From 7dc92a110f2f04e915145945371bea034ee67f5a Mon Sep 17 00:00:00 2001 From: Rankyn Bass Date: Mon, 2 Sep 2024 13:27:16 -0700 Subject: [PATCH 6/7] Code cleanup --- .../Compatibility/CompatibilityTools.cs | 2 +- src/XIVLauncher.Common.Unix/Compatibility/DxvkSettings.cs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/XIVLauncher.Common.Unix/Compatibility/CompatibilityTools.cs b/src/XIVLauncher.Common.Unix/Compatibility/CompatibilityTools.cs index 6e437b2be..1cadfab6b 100644 --- a/src/XIVLauncher.Common.Unix/Compatibility/CompatibilityTools.cs +++ b/src/XIVLauncher.Common.Unix/Compatibility/CompatibilityTools.cs @@ -184,7 +184,7 @@ private async Task InstallNvapi() } } } - + private void UninstallNvngx() { File.Delete(Path.Combine(GamePath.FullName, "game", "nvngx.dll")); diff --git a/src/XIVLauncher.Common.Unix/Compatibility/DxvkSettings.cs b/src/XIVLauncher.Common.Unix/Compatibility/DxvkSettings.cs index 33f01ffa9..29957ad48 100644 --- a/src/XIVLauncher.Common.Unix/Compatibility/DxvkSettings.cs +++ b/src/XIVLauncher.Common.Unix/Compatibility/DxvkSettings.cs @@ -26,7 +26,7 @@ public class DxvkSettings public Dictionary Environment { get; } - public DxvkSettings(string folder, string url, string storageFolder, bool async, int maxFrameRate, bool dxvkHudEnabled, string dxvkHudString, bool mangoHudEnabled = false, bool mangoHudCustomIsFile = false, string customMangoHud = "", bool enabled = true, string nvapiFolder = "", string nvapiUrl = "", string nvngxFolder = "", bool nvngxOverride = false) + public DxvkSettings(string folder, string url, string storageFolder, bool async, int maxFrameRate, bool dxvkHudEnabled, string dxvkHudString, bool mangoHudEnabled = false, bool mangoHudCustomIsFile = false, string customMangoHud = "", bool enabled = true, string nvapiFolder = "", string nvapiUrl = "", string nvngxFolder = "") { FolderName = folder; DownloadUrl = url; @@ -34,7 +34,7 @@ public DxvkSettings(string folder, string url, string storageFolder, bool async, NvapiDownloadUrl = nvapiUrl; NvngxFolder = nvngxFolder; Enabled = enabled; - NvngxOverride = nvngxOverride; + NvngxOverride = !string.IsNullOrEmpty(NvapiFolderName) && string.IsNullOrEmpty(NvngxFolder); // Disable Nvapi if the NvapiFolderName is empty, if Dxvk is not enabled, or if the dxvk version is dxvk-1.x or dxvk-async-1.x NvapiEnabled = (!string.IsNullOrEmpty(NvapiFolderName) && DxvkAllowsNvapi(FolderName) && Enabled); From a7a266c7356cbe3fab6dbeb2510cc02e780110a8 Mon Sep 17 00:00:00 2001 From: Rankyn Bass Date: Sat, 7 Sep 2024 16:54:47 -0700 Subject: [PATCH 7/7] Add extra WINEDLLOVERRIDE handling --- .../Compatibility/CompatibilityTools.cs | 3 ++- .../Compatibility/WineSettings.cs | 20 ++++++++++++++++++- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/src/XIVLauncher.Common.Unix/Compatibility/CompatibilityTools.cs b/src/XIVLauncher.Common.Unix/Compatibility/CompatibilityTools.cs index 1cadfab6b..10ced48c7 100644 --- a/src/XIVLauncher.Common.Unix/Compatibility/CompatibilityTools.cs +++ b/src/XIVLauncher.Common.Unix/Compatibility/CompatibilityTools.cs @@ -284,7 +284,8 @@ private Process RunInPrefix(ProcessStartInfo psi, string workingDirectory, IDict var wineEnvironmentVariables = new Dictionary(); wineEnvironmentVariables.Add("WINEPREFIX", Settings.Prefix.FullName); - wineEnvironmentVariables.Add("WINEDLLOVERRIDES", $"msquic=,mscoree=n,b;d3d9,d3d11,d3d10core,dxgi={(wineD3D ? "b" : "n,b")}"); + wineEnvironmentVariables.Add("WINEDLLOVERRIDES", $"msquic=,mscoree=n,b;d3d9,d3d11,d3d10core,dxgi={(wineD3D ? "b" : "n,b")};{Settings.ExtraWineDLLOverrides}"); + Console.WriteLine("WINEDLLOVERRIDES=\"" + wineEnvironmentVariables["WINEDLLOVERRIDES"] + "\""); if (!string.IsNullOrEmpty(Settings.DebugVars)) { diff --git a/src/XIVLauncher.Common.Unix/Compatibility/WineSettings.cs b/src/XIVLauncher.Common.Unix/Compatibility/WineSettings.cs index ed8d16df8..dddd61346 100644 --- a/src/XIVLauncher.Common.Unix/Compatibility/WineSettings.cs +++ b/src/XIVLauncher.Common.Unix/Compatibility/WineSettings.cs @@ -1,4 +1,7 @@ using System.IO; +using System.Text.RegularExpressions; +using System.Linq; + namespace XIVLauncher.Common.Unix.Compatibility; @@ -16,6 +19,8 @@ public class WineSettings public string DownloadUrl; + public string ExtraWineDLLOverrides; + public string EsyncOn { get; private set; } public string FsyncOn { get; private set; } @@ -26,13 +31,14 @@ public class WineSettings public DirectoryInfo Prefix { get; private set; } - public WineSettings(bool isManaged, string customBinPath, string managedFolder, string managedUrl, DirectoryInfo storageFolder, string debugVars, FileInfo logFile, DirectoryInfo prefix, bool? esyncOn, bool? fsyncOn) + public WineSettings(bool isManaged, string customBinPath, string managedFolder, string managedUrl, string extraDLLOverrides, DirectoryInfo storageFolder, string debugVars, FileInfo logFile, DirectoryInfo prefix, bool? esyncOn, bool? fsyncOn) { // storageFolder is the path to .xlcore folder. managedFolder is the foldername inside the tarball that will be downloaded from managedUrl. IsManaged = isManaged; FolderName = managedFolder; DownloadUrl = managedUrl; BinPath = (isManaged) ? Path.Combine(storageFolder.FullName, "compatibilitytool", "wine", managedFolder, "bin") : customBinPath; + ExtraWineDLLOverrides = WineDLLOverrideIsValid(extraDLLOverrides) ? extraDLLOverrides ?? "" : ""; this.EsyncOn = (esyncOn ?? false) ? "1" : "0"; this.FsyncOn = (fsyncOn ?? false) ? "1" : "0"; @@ -40,4 +46,16 @@ public WineSettings(bool isManaged, string customBinPath, string managedFolder, this.LogFile = logFile; this.Prefix = prefix; } + + public static bool WineDLLOverrideIsValid(string dlls) + { + string[] invalid = { "msquic", "mscoree", "d3d9", "d3d11", "d3d10core", "dxgi" }; + var format = @"^(?:(?:[a-zA-Z0-9_\-\.]+,?)+=(?:n,b|b,n|n|b|d|,|);?)+$"; + + if (string.IsNullOrEmpty(dlls)) return true; + if (invalid.Any(s => dlls.Contains(s))) return false; + if (Regex.IsMatch(dlls, format)) return true; + + return false; + } } \ No newline at end of file