From 9ccec08204a0e09d4f6d931d18a6c2a10abfe9a6 Mon Sep 17 00:00:00 2001 From: Emilian Roman Date: Mon, 13 Feb 2023 09:02:29 +0800 Subject: [PATCH] Implement XIV & GShade path localisation procedures This commit integrates a few procedures for figuring out the paths for the XIV game directory, and the GShade installation directory. Issue #1 on GitHub will benefit from this update. ----------------------------------------------------------------------- XIV --- 1. Attempt to retrieve value from the GShade registry key. 2. Attempt to check the default non-Steam installation path. 3. Attempt to check the current working directory. GSHADE ------ 1. Attempt to retrieve value from the GShade registry key. 2. Attempt to check the default Program Files installation path. ----------------------------------------------------------------------- Signed-off-by: Emilian Roman --- src/Paths.cs | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/Program.cs | 41 ++++++++++++++++++++++-- 2 files changed, 122 insertions(+), 3 deletions(-) diff --git a/src/Paths.cs b/src/Paths.cs index 4070f94..ceb2290 100755 --- a/src/Paths.cs +++ b/src/Paths.cs @@ -17,8 +17,11 @@ * along with GShade.Nuke. If not, see . */ +using System; using System.Collections.Generic; using System.IO; +using System.Linq; +using static System.Console; using static System.Environment; using static System.Environment.SpecialFolder; using static System.IO.Path; @@ -29,6 +32,87 @@ public static class Paths { public static readonly string GShade = "GShade"; + /** + * Attempts to figure out the XIV game directory path using the following methods: + * + * 1. Retrieving the location path from the GShade registry key. + * 2. Asserting the existence of the game in the default non-Steam installation path. + * 3. Asserting the existence of the game in the current directory. + */ + public static DirectoryInfo Game() + { + try + { + return Registry.Infer(Registry.Type.Game); + } + catch (Exception e) + { + WriteLine(e.Message + "-- Attempting next XIV game path detection method."); + } + + var defaultPath = Combine(GetFolderPath(ProgramFilesX86), + "SquareEnix", + "FINAL FANTASY XIV - A Realm Reborn", + "game"); + + var executables = new List + { + new(Combine(defaultPath, "ffxiv.exe")), + new(Combine(defaultPath, "ffxiv_dx11.exe")), + new(Combine(CurrentDirectory, "ffxiv.exe")), + new(Combine(CurrentDirectory, "ffxiv_dx11.exe")) + }; + + var path = new DirectoryInfo(string.Empty); + + foreach (var executable in executables.Where(executable => executable.Exists)) + path = executable.Directory; + + if (path is not {Exists: true}) + throw new DirectoryNotFoundException("Could not find the XIV game directory."); + + return path; + } + + /** + * Attempts to figure out the GShade installation directory path using the following methods: + * + * 1. Retrieving the location path from the GShade registry key. + * 2. Asserting the existence of assets in the default installation path. + */ + public static DirectoryInfo Root() + { + try + { + return Registry.Infer(Registry.Type.Install); + } + catch (Exception e) + { + WriteLine(e.Message + "-- Attempting next GShade installation path detection method."); + } + + var defaultPath = Combine(GetFolderPath(ProgramFiles), + "GShade"); + + var assets = new List + { + new(Combine(defaultPath, "GShade32.dll")), + new(Combine(defaultPath, "GShade64.dll")), + new(Combine(CurrentDirectory, "inject32.exe")), + new(Combine(CurrentDirectory, "inject75.exe")) + }; + + var path = new DirectoryInfo(string.Empty); + + foreach (var asset in assets.Where(asset => asset.Exists)) + path = asset.Directory; + + if (path is not {Exists: true}) + throw new DirectoryNotFoundException("Could not find the GShade installation directory."); + + return path; + } + /** * Principal Post-Processing directories, along with presets. These are the most important user files! */ diff --git a/src/Program.cs b/src/Program.cs index 4d701f7..3259697 100755 --- a/src/Program.cs +++ b/src/Program.cs @@ -18,7 +18,9 @@ */ using System; +using System.Collections.Generic; using System.IO; +using System.Linq; using Mono.Options; using static System.Console; using static System.DateTime; @@ -51,9 +53,9 @@ internal class Program } }; - private static DirectoryInfo Root { get; set; } = Registry.Infer(Registry.Type.Install); - private static DirectoryInfo Game { get; set; } = Registry.Infer(Registry.Type.Game); - private static bool Force { get; set; } + private static DirectoryInfo Root { get; set; } + private static DirectoryInfo Game { get; set; } + private static bool Force { get; set; } private static bool Migrate { get; set; } private static string Backup { get; set; } = @@ -114,6 +116,7 @@ private static void Main(string[] args) try { + Localise(); Archive(); Uninstall(); Rename(); @@ -123,10 +126,42 @@ private static void Main(string[] args) var log = Combine(GetFolderPath(Desktop), "GShade.Nuke.log"); WriteAllText(log, e.StackTrace); WriteLine($"An error has occurred: {e.Message}. Refer to the log file for more details: {log}"); + Exit(1); } WriteLine("Press any key to continue..."); ReadLine(); } + + private static void Localise() + { + if (!Game.Exists) + try + { + Game = Paths.Game(); + } + catch (Exception) + { + WriteLine("XIV path not found. Perhaps you've ran the GShade uninstaller before?"); + WriteLine("Either move gshade-nuke.exe to your XIV 'game' folder, or the path:"); + WriteLine(@" gshade-nuke.exe --game 'C:\Path\To\XIV\game\folder'"); + WriteLine("GShade Nuke will still try to delete any other known GShade files."); + ReadLine(); + } + + if (!Root.Exists) + try + { + Root = Paths.Root(); + } + catch (Exception) + { + WriteLine("GShade path not found. Perhaps you've ran the GShade uninstaller before?"); + WriteLine("Either manually delete the GShade folder, or specify the GShade install path:"); + WriteLine(@" gshade-nuke.exe --install 'C:\Path\To\GShade\installation'"); + WriteLine("GShade Nuke will still try to delete any other known GShade files."); + ReadLine(); + } + } } } \ No newline at end of file