Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve handling of variables and relative paths when reading paths from env vars #537

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 4 additions & 41 deletions C7/Util.cs
Original file line number Diff line number Diff line change
@@ -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();
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not strictly relevant to this PR, but I was wondering if this property is truly meant to use Civ3Location.GetCiv3Path() and not the class method Util.GetCiv3Path(). Currently Util.GetCiv3Path has no refs, and the C7Settings.GetSettingValue check seems like something that might be expected when calling Util.Civ3Root. From git history it looks like this property was updated 2 years ago, but I wanted to double check if this setup was intentional

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't say one way or another if it was intentional, but if it doesn't seem needed it might be worth a separate PR to change it.


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
Expand Down
39 changes: 31 additions & 8 deletions QueryCiv3/Civ3Location.cs
Original file line number Diff line number Diff line change
@@ -1,26 +1,47 @@
using System;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;

namespace QueryCiv3 {
public class Civ3Location {
public static readonly string RegistryKey = @"HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Infogrames Interactive\Civilization III";

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)) {
Expand All @@ -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";
}
}
Expand Down