From 2dbe21447ae0bb5da71d34ca40ba3767965759fd Mon Sep 17 00:00:00 2001 From: David Socha Date: Sun, 2 Feb 2025 00:19:36 -0600 Subject: [PATCH] Improve handling of variables and relative paths when reading paths from env vars --- C7/Util.cs | 45 ++++----------------------------------- QueryCiv3/Civ3Location.cs | 39 ++++++++++++++++++++++++++------- 2 files changed, 35 insertions(+), 49 deletions(-) diff --git a/C7/Util.cs b/C7/Util.cs index bc1c5cda..51d01f72 100644 --- a/C7/Util.cs +++ b/C7/Util.cs @@ -1,57 +1,20 @@ using System; -using System.Linq; using System.Collections.Generic; +using System.Linq; using System.Runtime.InteropServices; using C7Engine; -using Godot; using ConvertCiv3Media; -using C7GameData; +using Godot; using QueryCiv3; public partial class Util { static public string Civ3Root = Civ3Location.GetCiv3Path(); - static private string SteamCommonDir() { - string home = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal); - if (home == null) { return null; } - return System.IO.Path.Combine(home, "Library/Application Support/Steam/steamapps/common"); - } - - static private bool FolderIsCiv3(System.IO.DirectoryInfo di) { - return di.EnumerateFiles().Any(f => f.Name == "civ3id.mb"); - } - static public string GetCiv3Path() { - // Use CIV3_HOME env var if present - string path = System.Environment.GetEnvironmentVariable("CIV3_HOME"); - if (path != null) { return path; } - - // Use settings value if present - path = C7Settings.GetSettingValue("locations", "civ3InstallDir"); + string path = C7Settings.GetSettingValue("locations", "civ3InstallDir"); if (path != null) return path; - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { - // Look up in Windows registry if present - path = Civ3PathFromRegistry(); - if (path != null) { return path; } - } else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX) || RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) { - // Check for a civ3 folder in steamapps/common - System.IO.DirectoryInfo root = new System.IO.DirectoryInfo(Util.SteamCommonDir()); - foreach (System.IO.DirectoryInfo di in root.GetDirectories()) { - if (Util.FolderIsCiv3(di)) { - return di.FullName; - } - } - } - - return "/civ3/path/not/found"; - } - - static public string Civ3PathFromRegistry() { - // Assuming 64-bit platform, get vanilla Civ3 install folder from registry - // Return null if value not present or if key not found - object path = Microsoft.Win32.Registry.GetValue(@"HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Infogrames Interactive\Civilization III", "install_path", null); - return path == null ? null : (string)path; + return Civ3Location.GetCiv3Path(); } // Checks if a file exists ignoring case on the latter parts of its path. If the file is found, returns its full path re-capitalized as diff --git a/QueryCiv3/Civ3Location.cs b/QueryCiv3/Civ3Location.cs index e92231c0..77ed73e4 100644 --- a/QueryCiv3/Civ3Location.cs +++ b/QueryCiv3/Civ3Location.cs @@ -1,5 +1,8 @@ +using System; +using System.IO; using System.Linq; using System.Runtime.InteropServices; +using System.Text.RegularExpressions; namespace QueryCiv3 { public class Civ3Location { @@ -7,20 +10,38 @@ public class Civ3Location { private static string SteamCommonDir() { if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { - string programFilesX86 = System.Environment.GetFolderPath(System.Environment.SpecialFolder.ProgramFilesX86); - return System.IO.Path.Join(programFilesX86, "Steam\\steamapps\\common"); + string programFilesX86 = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86); + return Path.Join(programFilesX86, "Steam\\steamapps\\common"); } - string home = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal); - return home == null ? null : System.IO.Path.Combine(home, "Library/Application Support/Steam/steamapps/common"); + string home = GetHome(); + return home == null ? null : Path.Combine(home, "Library/Application Support/Steam/steamapps/common"); } - private static bool FolderIsCiv3(System.IO.DirectoryInfo di) { + private static string GetHome() => Environment.GetFolderPath(Environment.SpecialFolder.UserProfile); + + private static bool FolderIsCiv3(DirectoryInfo di) { return di.EnumerateFiles().Any(f => f.Name == "civ3id.mb"); } + private static string ConvertUnixVarsToWindowsVars(string input) { + if (string.IsNullOrEmpty(input)) return input; + + // Replace all instances of $VARIABLE with %VARIABLE% + return Regex.Replace(input, @"\$(\w+)", match => $"%{match.Groups[1].Value}%"); + } + + private static string GetExpandedPath(string path) { + bool isUnixLike = !RuntimeInformation.IsOSPlatform(OSPlatform.Windows); + if (isUnixLike && path[0] == '~') path = GetHome() + path.Substring(1); + if (isUnixLike) path = ConvertUnixVarsToWindowsVars(path); + path = Environment.ExpandEnvironmentVariables(path); + path = Path.GetFullPath(path); + return path; + } + public static string GetCiv3Path() { // Use CIV3_HOME env var if present - string path = System.Environment.GetEnvironmentVariable("CIV3_HOME"); + string path = GetExpandedPath(Environment.GetEnvironmentVariable("CIV3_HOME")); if (path != null) { return path; } if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { @@ -30,16 +51,18 @@ public static string GetCiv3Path() { return path; } } + // Check for a civ3 folder in steamapps/common string steam = SteamCommonDir(); if (!string.IsNullOrEmpty(steam)) { - System.IO.DirectoryInfo root = new(steam); - foreach (System.IO.DirectoryInfo di in root.GetDirectories()) { + DirectoryInfo root = new(steam); + foreach (DirectoryInfo di in root.GetDirectories()) { if (FolderIsCiv3(di)) { return di.FullName; } } } + return "/civ3/path/not/found"; } }