GameDirectoryFinder.cs 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. using Microsoft.Win32;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.IO;
  5. using System.Linq;
  6. namespace OpenVIII.Core {
  7. /// <summary>
  8. /// Class is resposible for finding the root directory where Final Fantasy VIII is stored.
  9. /// </summary>
  10. public static class GameDirectoryFinder
  11. {
  12. /// <summary>
  13. /// Looks for root directory where the game is installed.
  14. /// </summary>
  15. /// <returns>Path to a directory where the game is installed.</returns>
  16. public static string FindRootGameDirectory()
  17. {
  18. switch(RuntimeEnvironment.Platform)
  19. {
  20. case RuntimePlatform.Windows:
  21. return WindowsRootGameDirectory();
  22. case RuntimePlatform.Linux:
  23. return LinuxRootGameDirectory();
  24. default:
  25. throw new NotSupportedException(RuntimeEnvironment.Platform.ToString());
  26. }
  27. }
  28. private static string WindowsRootGameDirectory()
  29. {
  30. var commonRoots = new string[]
  31. {
  32. @"C:\Program Files (x86)\Steam\steamapps\common\FINAL FANTASY VIII",
  33. @"D:\SteamLibrary\steamapps\common\FINAL FANTASY VIII",
  34. @"D:\Steam\steamapps\common\FINAL FANTASY VIII",
  35. };
  36. if (commonRoots.Where(path => Directory.Exists(path)).Any())
  37. return commonRoots.Where(path => Directory.Exists(path)).First();
  38. var registryRoots = RootsFromRegistry();
  39. if (registryRoots.Where(path => Directory.Exists(path)).Any())
  40. return registryRoots.Where(path => Directory.Exists(path)).First();
  41. throw new DirectoryNotFoundException($"Cannot find game directory." +
  42. $"Add your own path to the {nameof(WindowsRootGameDirectory)}.");
  43. }
  44. private static List<string> RootsFromRegistry()
  45. {
  46. // Now, we are looking into registers.
  47. #region Registries paths and tags
  48. // Steam 2013
  49. const string SteamRegistryPath = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Steam App 39150";
  50. const string SteamGamePathTag = @"InstallLocation";
  51. // Supplied from LordUrQuan
  52. const string CD2000RegistryPath = @"SOFTWARE\Wow6432Node\Square Soft, Inc\FINAL FANTASY VIII\1.00";
  53. const string CD2000GamePathTag = @"AppPath";
  54. // Steam Remaster
  55. const string SteamRERegistryPath = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Steam App 1026680";
  56. const string SteamREGamePathTag = @"InstallLocation";
  57. #endregion
  58. var regs = new Dictionary<string, string>()
  59. {
  60. {SteamRegistryPath, SteamGamePathTag},
  61. {CD2000RegistryPath, CD2000GamePathTag},
  62. {SteamRERegistryPath, SteamREGamePathTag}
  63. };
  64. var regValues = new List<string>();
  65. foreach (var pair in regs)
  66. {
  67. regValues.Add(ValueFromRegistry(pair.Key, pair.Value, RegistryView.Registry32));
  68. regValues.Add(ValueFromRegistry(pair.Key, pair.Value, RegistryView.Registry64));
  69. }
  70. return regValues;
  71. }
  72. private static string ValueFromRegistry(string subKey, string valueName, RegistryView view)
  73. {
  74. using var baseKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, view);
  75. using var key = baseKey.OpenSubKey(subKey);
  76. // Starting from C# 6 we can use Null-conditional operator (?.)
  77. // https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/member-access-operators#null-conditional-operators--and-
  78. return (string)key?.GetValue(valueName);
  79. }
  80. private static string LinuxRootGameDirectory()
  81. {
  82. var commonRoots = new string[]
  83. {
  84. @"/home/robert/Final Fantasy VIII",
  85. @"/media/griever/Data/SteamLibrary/steamapps/common/FINAL FANTASY VIII",
  86. @"/home/griever/.PlayOnLinux/wineprefix/Steam/drive_c/Program Files/Steam/steamapps/common/FINAL FANTASY VIII",
  87. @"/home/parallels/src/ff8/steam"
  88. };
  89. if (commonRoots.Where(path => Directory.Exists(path)).Any())
  90. return commonRoots.Where(path => Directory.Exists(path)).First();
  91. throw new DirectoryNotFoundException($"Cannot find game directory." +
  92. $"Add your own path to the {nameof(LinuxRootGameDirectory)}.");
  93. }
  94. }
  95. }