From e3c283753b534bf4af67ac7e05c7412679b670db Mon Sep 17 00:00:00 2001 From: FlameHorizon Date: Tue, 2 Mar 2021 17:46:29 +0100 Subject: [PATCH] Refactored how location of the game is aquired to a simpler version. --- Core/Core.csproj | 10 +- Core/GameDirectoryFinder.cs | 111 ++++++++++++++++++ Core/Memory.cs | 7 +- .../Environment/Game/Location/GameLocation.cs | 43 ------- .../Location/HardcodedGameLocationProvider.cs | 42 ------- .../Game/Location/IGameLocationProvider.cs | 7 -- .../Location/LinuxGameLocationProvider.cs | 24 ---- .../Location/WindowsGameLocationProvider.cs | 82 ------------- 8 files changed, 119 insertions(+), 207 deletions(-) create mode 100644 Core/GameDirectoryFinder.cs delete mode 100644 Core/Sources/Environment/Game/Location/GameLocation.cs delete mode 100644 Core/Sources/Environment/Game/Location/HardcodedGameLocationProvider.cs delete mode 100644 Core/Sources/Environment/Game/Location/IGameLocationProvider.cs delete mode 100644 Core/Sources/Environment/Game/Location/LinuxGameLocationProvider.cs delete mode 100644 Core/Sources/Environment/Game/Location/WindowsGameLocationProvider.cs diff --git a/Core/Core.csproj b/Core/Core.csproj index 58476b41..bacc600a 100644 --- a/Core/Core.csproj +++ b/Core/Core.csproj @@ -393,6 +393,7 @@ + @@ -1117,11 +1118,6 @@ - - - - - @@ -1295,7 +1291,9 @@ PreserveNewest - + + + {a9b33bf4-9b03-4e3d-bf6a-181521046ee8} diff --git a/Core/GameDirectoryFinder.cs b/Core/GameDirectoryFinder.cs new file mode 100644 index 00000000..4fb29783 --- /dev/null +++ b/Core/GameDirectoryFinder.cs @@ -0,0 +1,111 @@ +using Microsoft.Win32; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; + +namespace OpenVIII.Core { + + /// + /// Class is resposible for finding the root directory where Final Fantasy VIII is stored. + /// + public static class GameDirectoryFinder + { + /// + /// Looks for root directory where the game is installed. + /// + /// Path to a directory where the game is installed. + public static string FindRootGameDirectory() + { + return RuntimeEnvironment.Platform switch + { + RuntimePlatform.Windows => WindowsRootGameDirectory(), + RuntimePlatform.Linux => LinuxRootGameDirectory(), + _ => throw new NotSupportedException(RuntimeEnvironment.Platform.ToString()), + }; + } + + private static string WindowsRootGameDirectory() + { + var commonRoots = new string[] + { + @"C:\Program Files (x86)\Steam\steamapps\common\FINAL FANTASY VIII", + @"D:\SteamLibrary\steamapps\common\FINAL FANTASY VIII", + @"D:\Steam\steamapps\common\FINAL FANTASY VIII", + }; + + if (commonRoots.Where(path => Directory.Exists(path)).Any()) + return commonRoots.Where(path => Directory.Exists(path)).First(); + + var registryRoots = RootsFromRegistry(); + + if (registryRoots.Where(path => Directory.Exists(path)).Any()) + return registryRoots.Where(path => Directory.Exists(path)).First(); + + throw new DirectoryNotFoundException($"Cannot find game directory." + + $"Add your own path to the {nameof(WindowsRootGameDirectory)}."); + } + + private static List RootsFromRegistry() + { + // Now, we are looking into registers. + #region Registries paths and tags + + // Steam 2013 + const string SteamRegistryPath = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Steam App 39150"; + const string SteamGamePathTag = @"InstallLocation"; + + // Supplied from LordUrQuan + const string CD2000RegistryPath = @"SOFTWARE\Wow6432Node\Square Soft, Inc\FINAL FANTASY VIII\1.00"; + const string CD2000GamePathTag = @"AppPath"; + + // Steam Remaster + const string SteamRERegistryPath = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Steam App 1026680"; + const string SteamREGamePathTag = @"InstallLocation"; + #endregion + + var regs = new Dictionary() + { + {SteamRegistryPath, SteamGamePathTag}, + {CD2000RegistryPath, CD2000GamePathTag}, + {SteamRERegistryPath, SteamREGamePathTag} + }; + + var regValues = new List(); + foreach (var pair in regs) + { + regValues.Add(ValueFromRegistry(pair.Key, pair.Value, RegistryView.Registry32)); + regValues.Add(ValueFromRegistry(pair.Key, pair.Value, RegistryView.Registry64)); + } + + return regValues; + } + + private static string ValueFromRegistry(string subKey, string valueName, RegistryView view) + { + using var baseKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, view); + using var key = baseKey.OpenSubKey(subKey); + + // Starting from C# 6 we can use Null-conditional operator (?.) + // https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/member-access-operators#null-conditional-operators--and- + return (string)key?.GetValue(valueName); + } + + private static string LinuxRootGameDirectory() + { + var commonRoots = new string[] + { + @"/home/robert/Final Fantasy VIII", + @"/media/griever/Data/SteamLibrary/steamapps/common/FINAL FANTASY VIII", + @"/home/griever/.PlayOnLinux/wineprefix/Steam/drive_c/Program Files/Steam/steamapps/common/FINAL FANTASY VIII", + @"/home/parallels/src/ff8/steam" + }; + + if (commonRoots.Where(path => Directory.Exists(path)).Any()) + return commonRoots.Where(path => Directory.Exists(path)).First(); + + throw new DirectoryNotFoundException($"Cannot find game directory." + + $"Add your own path to the {nameof(LinuxRootGameDirectory)}."); + } + } +} \ No newline at end of file diff --git a/Core/Memory.cs b/Core/Memory.cs index d9c34a99..5189c270 100644 --- a/Core/Memory.cs +++ b/Core/Memory.cs @@ -1,6 +1,8 @@ using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Content; using Microsoft.Xna.Framework.Graphics; +using OpenVIII; +using OpenVIII.Core; using OpenVIII.Kernel; using System; using System.Collections.Concurrent; @@ -833,9 +835,8 @@ public static void Init(GraphicsDeviceManager graphics, SpriteBatch spriteBatch, Log.WriteLine($"{nameof(Memory)} :: {nameof(MainThreadOnlyActions)}"); MainThreadOnlyActions = new ConcurrentQueue(); - FF8Dir = GameLocation.Current.DataPath; - void SetData() => - FF8DirData = Extended.GetUnixFullPath(Path.Combine(FF8Dir, "Data")); + FF8Dir = GameDirectoryFinder.FindRootGameDirectory(); + void SetData() => FF8DirData = Extended.GetUnixFullPath(Path.Combine(FF8Dir, "Data")); SetData(); var languageSet = false; diff --git a/Core/Sources/Environment/Game/Location/GameLocation.cs b/Core/Sources/Environment/Game/Location/GameLocation.cs deleted file mode 100644 index 15ebfbb2..00000000 --- a/Core/Sources/Environment/Game/Location/GameLocation.cs +++ /dev/null @@ -1,43 +0,0 @@ -using System; - -namespace OpenVIII -{ - public sealed class GameLocation - { - private readonly static GameLocation s_current = GetCurrentLocation(); - - public string DataPath { get; private set; } - - public GameLocation(string dataPath) - { - DataPath = dataPath; - } - - public static GameLocation Current - { - get - { - return s_current; - } - } - - private static GameLocation GetCurrentLocation() - { - var provider = GetLocationProvider(); - return provider.GetGameLocation(); - } - - private static IGameLocationProvider GetLocationProvider() - { - switch (RuntimeEnvironment.Platform) - { - case RuntimePlatform.Windows: - return new WindowsGameLocationProvider(); - case RuntimePlatform.Linux: - return new LinuxGameLocationProvider(); - default: - throw new NotSupportedException(RuntimeEnvironment.Platform.ToString()); - } - } - } -} \ No newline at end of file diff --git a/Core/Sources/Environment/Game/Location/HardcodedGameLocationProvider.cs b/Core/Sources/Environment/Game/Location/HardcodedGameLocationProvider.cs deleted file mode 100644 index ea1afaf6..00000000 --- a/Core/Sources/Environment/Game/Location/HardcodedGameLocationProvider.cs +++ /dev/null @@ -1,42 +0,0 @@ -using System; -using System.IO; - -namespace OpenVIII -{ - public sealed class HardcodedGameLocationProvider - { - private readonly string[] _knownPaths; - - public HardcodedGameLocationProvider(string[] knownPaths) - { - _knownPaths = knownPaths ?? throw new ArgumentNullException(nameof(knownPaths)); - } - - public bool FindGameLocation(out GameLocation gameLocation) - { - //using (var errors = new ExceptionList()) - //{ - foreach (var path in _knownPaths) - { - try - { - if (!Directory.Exists(path)) - continue; - - gameLocation = new GameLocation(path); - //errors.Clear(); - return true; - } - catch (Exception ex) - { - ex.Rethrow(); - //errors.Add(ex); - } - } - //} - - gameLocation = null; - return false; - } - } -} \ No newline at end of file diff --git a/Core/Sources/Environment/Game/Location/IGameLocationProvider.cs b/Core/Sources/Environment/Game/Location/IGameLocationProvider.cs deleted file mode 100644 index 419c529c..00000000 --- a/Core/Sources/Environment/Game/Location/IGameLocationProvider.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace OpenVIII -{ - public interface IGameLocationProvider - { - GameLocation GetGameLocation(); - } -} \ No newline at end of file diff --git a/Core/Sources/Environment/Game/Location/LinuxGameLocationProvider.cs b/Core/Sources/Environment/Game/Location/LinuxGameLocationProvider.cs deleted file mode 100644 index ff475dda..00000000 --- a/Core/Sources/Environment/Game/Location/LinuxGameLocationProvider.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System.IO; - -namespace OpenVIII -{ - public sealed class LinuxGameLocationProvider : IGameLocationProvider - { - public GameLocation GetGameLocation() - { - if (_hardcoded.FindGameLocation(out var gameLocation)) - return gameLocation; - - throw new DirectoryNotFoundException($"Cannot find game directory." + - $"Add your own path to the {nameof(LinuxGameLocationProvider)} type."); - } - - private readonly HardcodedGameLocationProvider _hardcoded = new HardcodedGameLocationProvider(new[] - { - "/home/robert/Final Fantasy VIII", - "/media/griever/Data/SteamLibrary/steamapps/common/FINAL FANTASY VIII", - "/home/griever/.PlayOnLinux/wineprefix/Steam/drive_c/Program Files/Steam/steamapps/common/FINAL FANTASY VIII", - "/home/parallels/src/ff8/steam" - }); - } -} diff --git a/Core/Sources/Environment/Game/Location/WindowsGameLocationProvider.cs b/Core/Sources/Environment/Game/Location/WindowsGameLocationProvider.cs deleted file mode 100644 index c5c0ddcf..00000000 --- a/Core/Sources/Environment/Game/Location/WindowsGameLocationProvider.cs +++ /dev/null @@ -1,82 +0,0 @@ -using Microsoft.Win32; -using System.IO; - -namespace OpenVIII -{ - public sealed class WindowsGameLocationProvider : IGameLocationProvider - { - /// - /// Steam 2013 - /// - private const string SteamRegistyPath = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Steam App 39150"; - - /// - /// Steam 2013 - /// - private const string SteamGamePathTag = @"InstallLocation"; - - /// - /// Supplied from LordUrQuan - /// - private const string CD2000RegistyPath = @"SOFTWARE\Wow6432Node\Square Soft, Inc\FINAL FANTASY VIII\1.00"; - - /// - /// Supplied from LordUrQuan - /// - private const string CD2000GamePathTag = @"AppPath"; - - /// - /// ReMaster - /// - private const string SteamRERegistyPath = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Steam App 1026680"; - - /// - /// ReMaster - /// - private const string SteamREGamePathTag = @"InstallLocation"; - - public GameLocation GetGameLocation() - { - if (_hardcoded.FindGameLocation(out var gameLocation)) - return gameLocation; - - foreach (var registryView in new RegistryView[] { RegistryView.Registry32, RegistryView.Registry64 }) - { - GameLocation r; - if ((r = Check(SteamRegistyPath, SteamGamePathTag)) == null && - (r = Check(CD2000RegistyPath, CD2000RegistyPath)) == null && - (r = Check(SteamRERegistyPath, SteamREGamePathTag)) == null) - continue; - else - return r; - - GameLocation Check(string path, string tag) - { - using (var localMachine = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, registryView)) - using (var registryKey = localMachine.OpenSubKey(path)) - { - if (registryKey != null) - { - var installLocation = (string)registryKey.GetValue(tag); - var dataPath = installLocation; - if (Directory.Exists(dataPath)) - return new GameLocation(dataPath); - } - } - return null; - } - } - - throw new DirectoryNotFoundException($"Cannot find game directory." + - $"Add your own path to the {nameof(WindowsGameLocationProvider)} type or fix a registration in the registry:" + - $"{SteamRegistyPath}.{SteamGamePathTag}"); - } - - private readonly HardcodedGameLocationProvider _hardcoded = new HardcodedGameLocationProvider(new[] - { - @"C:\Program Files (x86)\Steam\steamapps\common\FINAL FANTASY VIII",//Data\lang-en - @"D:\SteamLibrary\steamapps\common\FINAL FANTASY VIII", - @"D:\Steam\steamapps\common\FINAL FANTASY VIII", - }); - } -} \ No newline at end of file