forked from SubnauticaNitrox/Nitrox
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Game finders overhaul (SubnauticaNitrox#2121)
* Modified namespace to be file-scoped by default in editorconfig * Reworked installation finders * Refactored GameFinders to use GameFinderResult * Added NotFound/Ok result to GameFinderResult type * Added GetUniqueNonCombinatoryFlags extension for Enums --------- Co-authored-by: Measurity <[email protected]>
- Loading branch information
Showing
39 changed files
with
827 additions
and
358 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
using System; | ||
using System; | ||
using System.IO; | ||
using System.Linq; | ||
using System.Text; | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,59 +1,55 @@ | ||
using System; | ||
using System; | ||
using System.Collections.Generic; | ||
using System.IO; | ||
using System.Linq; | ||
using NitroxModel.Discovery.InstallationFinders; | ||
using NitroxModel.Discovery.InstallationFinders.Core; | ||
using NitroxModel.Discovery.Models; | ||
|
||
namespace NitroxModel.Discovery | ||
namespace NitroxModel.Discovery; | ||
|
||
/// <summary> | ||
/// Main game installation finder that will use all available methods of detection to find the game installation directory | ||
/// </summary> | ||
public sealed class GameInstallationFinder | ||
{ | ||
private static readonly Lazy<GameInstallationFinder> instance = new(() => new GameInstallationFinder()); | ||
public static GameInstallationFinder Instance => instance.Value; | ||
|
||
private readonly Dictionary<GameLibraries, IGameFinder> finders = new() | ||
{ | ||
{ GameLibraries.STEAM, new SteamFinder() }, | ||
{ GameLibraries.EPIC, new EpicGamesFinder() }, | ||
{ GameLibraries.DISCORD, new DiscordFinder() }, | ||
{ GameLibraries.MICROSOFT, new MicrosoftFinder() }, | ||
{ GameLibraries.ENVIRONMENT, new EnvironmentFinder() }, | ||
{ GameLibraries.CONFIG, new ConfigFinder() } | ||
}; | ||
|
||
/// <summary> | ||
/// Main game installation finder that will use all available methods of detection to find the Subnautica installation | ||
/// directory. | ||
/// Searches for the game install directory given its <see cref="GameInfo"/>. | ||
/// </summary> | ||
public class GameInstallationFinder : IFindGameInstallation | ||
/// <param name="gameInfo">Info object of a game.</param> | ||
/// <param name="gameLibraries">Known game libraries to search through</param> | ||
/// <returns>Positive and negative results from the search</returns> | ||
public IEnumerable<GameFinderResult> FindGame(GameInfo gameInfo, GameLibraries gameLibraries = GameLibraries.ALL) | ||
{ | ||
private static readonly Lazy<GameInstallationFinder> instance = new(() => new GameInstallationFinder()); | ||
public static GameInstallationFinder Instance => instance.Value; | ||
|
||
/// <summary> | ||
/// The order of these finders is VERY important. Only change if you know what you're doing. | ||
/// </summary> | ||
private readonly IFindGameInstallation[] finders = { | ||
new GameInCurrentDirectoryFinder(), | ||
new ConfigGameFinder(), | ||
new SteamGameRegistryFinder(), | ||
new EpicGamesInstallationFinder(), | ||
new DiscordGameFinder(), | ||
new EnvironmentGameFinder() | ||
}; | ||
|
||
public string FindGame(IList<string> errors = null) | ||
if (gameInfo is null || !gameLibraries.IsDefined()) | ||
{ | ||
errors ??= new List<string>(); | ||
foreach (IFindGameInstallation finder in finders) | ||
{ | ||
string path = finder.FindGame(errors); | ||
if (path == null) | ||
{ | ||
continue; | ||
} | ||
|
||
errors.Clear(); | ||
return Path.GetFullPath(path); | ||
} | ||
|
||
return null; | ||
yield break; | ||
} | ||
|
||
public static bool IsSubnauticaDirectory(string directory) | ||
foreach (GameLibraries wantedFinder in gameLibraries.GetUniqueNonCombinatoryFlags()) | ||
{ | ||
if (string.IsNullOrWhiteSpace(directory)) | ||
if (!finders.TryGetValue(wantedFinder, out IGameFinder finder)) | ||
{ | ||
return false; | ||
continue; | ||
} | ||
|
||
return Directory.EnumerateFiles(directory, "*.exe") | ||
.Any(file => Path.GetFileName(file)?.Equals("subnautica.exe", StringComparison.OrdinalIgnoreCase) ?? false); | ||
GameFinderResult result = finder.FindGame(gameInfo); | ||
if (!result.IsOk && string.IsNullOrWhiteSpace(result.ErrorMessage)) | ||
{ | ||
result = result with { ErrorMessage = $"It appears you don't have {gameInfo.Name} installed" }; | ||
} | ||
yield return result; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
using System.IO; | ||
|
||
namespace NitroxModel.Discovery; | ||
|
||
public static class GameInstallationHelper | ||
{ | ||
public static bool HasGameExecutable(string path, GameInfo gameInfo) | ||
{ | ||
if (string.IsNullOrWhiteSpace(path)) | ||
{ | ||
return false; | ||
} | ||
return File.Exists(Path.Combine(path, gameInfo.ExeName)); | ||
} | ||
|
||
public static bool HasValidGameFolder(string path, GameInfo gameInfo) | ||
{ | ||
if (string.IsNullOrWhiteSpace(path)) | ||
{ | ||
return false; | ||
} | ||
if (!Directory.Exists(path)) | ||
{ | ||
return false; | ||
} | ||
if (!HasGameExecutable(path, gameInfo)) | ||
{ | ||
return false; | ||
} | ||
if (!Directory.Exists(Path.Combine(path, gameInfo.DataFolder, "Managed"))) | ||
{ | ||
return false; | ||
} | ||
|
||
return true; | ||
} | ||
} |
Oops, something went wrong.