Added GOG Game Library Support

Added initial GOG library support.

Also refactored the GameLibraries so that
they also start the game themselves, as
each library is different in how it starts the
game. This is the simplest way to handle that.
This commit is contained in:
Terry MacDonald 2021-06-05 22:41:29 +12:00
parent 0cb5119d62
commit bfb164fd41
20 changed files with 922 additions and 113 deletions

View File

@ -96,6 +96,8 @@
<ItemGroup>
<Compile Include="DesktopNotificationActivator.cs" />
<Compile Include="DesktopNotificationManagerCompat.cs" />
<Compile Include="GameLibraries\GOGGame.cs" />
<Compile Include="GameLibraries\GOGLibrary.cs" />
<Compile Include="GameLibraries\Game.cs" />
<Compile Include="GameLibraries\GameLibrary.cs" />
<Compile Include="GameLibraries\GameUtils.cs" />
@ -325,16 +327,6 @@
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
<None Include="Resources\Steam.ico" />
</ItemGroup>
<ItemGroup>
<None Include="Resources\Uplay.ico" />
</ItemGroup>
<ItemGroup>
<None Include="Resources\Origin.ico" />
</ItemGroup>
<ItemGroup>
<None Include="Resources\Epic.ico" />
</ItemGroup>
<ItemGroup>
<None Include="Resources\Steam.png" />
@ -347,6 +339,7 @@
<None Include="Resources\error.png" />
<None Include="Resources\Epic.png" />
<None Include="Resources\Origin.png" />
<None Include="Resources\GOG.png" />
<Content Include="Resources\redarrows.png" />
</ItemGroup>
<ItemGroup>

View File

@ -141,21 +141,6 @@ namespace DisplayMagician.GameLibraries
}
}
public override GameStartMode StartMode
{
get => GameStartMode.URI;
}
public override string GetStartURI(string gameArguments = "")
{
string address = $@"com.epicgames.launcher://apps/{_epicGameId}?action=launch&silent=true";
if (String.IsNullOrWhiteSpace(gameArguments))
{
address += "/" + gameArguments;
}
return address;
}
public bool CopyTo(EpicGame EpicGame)
{
if (!(EpicGame is EpicGame))

View File

@ -515,14 +515,6 @@ namespace DisplayMagician.GameLibraries
epicGame.Id = installedAppManifest?.MainGameAppName?? installedApp.AppName;
epicGame.ProcessName = Path.GetFileNameWithoutExtension(epicGame.ExePath);
/* _epicGameId = epicGameId;
_epicGameName = epicGameName;
_epicGameExePath = epicGameExePath;
_epicGameDir = Path.GetDirectoryName(epicGameExePath);
_epicGameExe = Path.GetFileName(_epicGameExePath);
_epicGameProcessName = Path.GetFileNameWithoutExtension(_epicGameExePath);
_epicGameIconPath = epicGameIconPath;
*/
// Add the Epic Game to the list of Epic Games
_allEpicGames.Add(epicGame);
@ -564,6 +556,17 @@ namespace DisplayMagician.GameLibraries
return true;
}
public override Process StartGame(Game game, string gameArguments = "")
{
string address = $@"com.epicgames.launcher://apps/{game.Id}?action=launch&silent=true";
if (String.IsNullOrWhiteSpace(gameArguments))
{
address += "/" + gameArguments;
}
Process gameProcess = Process.Start(address);
return gameProcess;
}
#endregion
}

View File

@ -0,0 +1,181 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using DisplayMagician.Resources;
using System.Diagnostics;
namespace DisplayMagician.GameLibraries
{
public class GogGame : Game
{
private string _gogGameId;
private string _gogGameName;
private string _gogGameExePath;
private string _gogGameDir;
private string _gogGameExe;
private string _gogGameProcessName;
private string _gogGameIconPath;
//private string _gogURI;
private static readonly GogLibrary _gogGameLibrary = GogLibrary.GetLibrary();
private static readonly NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
static GogGame()
{
ServicePointManager.ServerCertificateValidationCallback +=
(send, certificate, chain, sslPolicyErrors) => true;
}
public GogGame() { }
public GogGame(string gogGameId, string gogGameName, string gogGameExePath, string gogGameIconPath)
{
//_gameRegistryKey = $@"{GogLibrary.registryGogInstallsKey}\\{GogGameId}";
_gogGameId = gogGameId;
_gogGameName = gogGameName;
_gogGameExePath = gogGameExePath;
_gogGameDir = Path.GetDirectoryName(gogGameExePath);
_gogGameExe = Path.GetFileName(_gogGameExePath);
_gogGameProcessName = Path.GetFileNameWithoutExtension(_gogGameExePath);
_gogGameIconPath = gogGameIconPath;
}
public override string Id
{
get => _gogGameId;
set => _gogGameId = value;
}
public override string Name
{
get => _gogGameName;
set => _gogGameName = value;
}
public override SupportedGameLibraryType GameLibrary
{
get => SupportedGameLibraryType.GOG;
}
public override string IconPath
{
get => _gogGameIconPath;
set => _gogGameIconPath = value;
}
public override string ExePath
{
get => _gogGameExePath;
set => _gogGameExePath = value;
}
public override string Directory
{
get => _gogGameDir;
set => _gogGameDir = value;
}
public override string Executable
{
get => _gogGameExe;
set => _gogGameExe = value;
}
public override string ProcessName
{
get => _gogGameProcessName;
set => _gogGameProcessName = value;
}
public override bool IsRunning
{
get
{
int numGameProcesses = 0;
List<Process> gameProcesses = Process.GetProcessesByName(_gogGameProcessName).ToList();
foreach (Process gameProcess in gameProcesses)
{
try
{
if (gameProcess.ProcessName.Equals(_gogGameProcessName))
numGameProcesses++;
}
catch (Exception ex)
{
logger.Debug(ex, $"GogGame/IsRunning: Accessing Process.ProcessName caused exception. Trying GameUtils.GetMainModuleFilepath instead");
// If there is a race condition where MainModule isn't available, then we
// instead try the much slower GetMainModuleFilepath (which does the same thing)
string filePath = GameUtils.GetMainModuleFilepath(gameProcess.Id);
if (filePath == null)
{
// if we hit this bit then GameUtils.GetMainModuleFilepath failed,
// so we just assume that the process is a game process
// as it matched the gogal process search
numGameProcesses++;
continue;
}
else
{
if (filePath.StartsWith(_gogGameExePath))
numGameProcesses++;
}
}
}
if (numGameProcesses > 0)
return true;
else
return false;
}
}
// Have to do much more research to figure out how to detect when Gog is updating a game
public override bool IsUpdating
{
get
{
return false;
}
}
public bool CopyTo(GogGame GogGame)
{
if (!(GogGame is GogGame))
return false;
// Copy all the game data over to the other game
GogGame.IconPath = IconPath;
GogGame.Id = Id;
GogGame.Name = Name;
GogGame.ExePath = ExePath;
GogGame.Directory = Directory;
return true;
}
public override string ToString()
{
var name = _gogGameName;
if (string.IsNullOrWhiteSpace(name))
{
name = Language.Unknown;
}
if (IsRunning)
{
return name + " " + Language.Running;
}
/*if (IsUpdating)
{
return name + " " + Language.Updating;
}*/
return name;
}
}
}

View File

@ -0,0 +1,603 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using Microsoft.Win32;
using System.IO;
using System.Security;
using System.Xml;
using System.Xml.Linq;
using System.Xml.XPath;
using System.Web;
using System.Diagnostics;
using Newtonsoft.Json;
namespace DisplayMagician.GameLibraries
{
public sealed class GogLibrary : GameLibrary
{
#region Class Variables
// Static members are 'eagerly initialized', that is,
// immediately when class is loaded for the first time.
// .NET guarantees thread safety for static initialization
private static readonly GogLibrary _instance = new GogLibrary();
// Common items to the class
private List<Game> _allGogGames = new List<Game>();
private string GogAppIdRegex = @"/^[0-9A-F]{1,10}$";
private string _gogExe;
private string _gogPath;
private string _gogLocalContent = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), "GOG.com");
private string _gogProgramFiles = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86), "GOG Galaxy");
private bool _isGogInstalled = false;
private List<string> _gogProcessList = new List<string>(){ "GalaxyClient" };
internal string registryGogGalaxyClientKey = @"SOFTWARE\WOW6432Node\GOG.com\GalaxyClient";
internal string registryGogGalaxyClientPathKey = @"SOFTWARE\WOW6432Node\GOG.com\GalaxyClient\paths";
internal string registryGogGalaxyGamesKey = @"SOFTWARE\WOW6432Node\GOG.com\Games\";
//internal string registryGogLauncherKey = @"SOFTWARE\WOW6432Node\Gog";
private readonly NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
// Other constants that are useful
#endregion
#region Class Constructors
static GogLibrary() { }
private GogLibrary()
{
try
{
logger.Trace($"GogLibrary/GogLibrary: Gog Online Services registry key = HKLM\\{registryGogGalaxyClientKey}");
// Find the GogExe location, and the GogPath for later
RegistryKey GogGalaxyClientKey = Registry.LocalMachine.OpenSubKey(registryGogGalaxyClientKey, RegistryKeyPermissionCheck.ReadSubTree);
if (GogGalaxyClientKey == null)
{
logger.Info($"GogLibrary/GogLibrary: GOG library is not installed!");
return;
}
string gogClientExeFilename = GogGalaxyClientKey.GetValue("clientExecutable", @"GalaxyClient.exe").ToString();
RegistryKey GogGalaxyClientPathKey = Registry.LocalMachine.OpenSubKey(registryGogGalaxyClientPathKey, RegistryKeyPermissionCheck.ReadSubTree);
string gogClientPath = GogGalaxyClientKey.GetValue("client", @"C:\Program Files (x86)\GOG Galaxy").ToString();
_gogPath = Path.GetDirectoryName(gogClientPath);
_gogExe = Path.Combine(gogClientPath, gogClientExeFilename);
if (File.Exists(_gogExe))
{
logger.Info($"GogLibrary/GogLibrary: GOG library is installed in {_gogPath}. Found {_gogExe}");
_isGogInstalled = true;
}
else
{
logger.Info($"GogLibrary/GogLibrary: GOG library is not installed!");
}
}
catch (SecurityException ex)
{
logger.Warn(ex, "GogLibrary/GogLibrary: The user does not have the permissions required to read the Gog Online Services registry key.");
}
catch(ObjectDisposedException ex)
{
logger.Warn(ex, "GogLibrary/GogLibrary: The Microsoft.Win32.RegistryKey is closed when trying to access the Gog Online Services registry key (closed keys cannot be accessed).");
}
catch (IOException ex)
{
logger.Warn(ex, "GogLibrary/GogLibrary: The Gog Online Services registry key has been marked for deletion so we cannot access the value dueing the GogLibrary check.");
}
catch (UnauthorizedAccessException ex)
{
logger.Warn(ex, "GogLibrary/GogLibrary: The user does not have the necessary registry rights to check whether Gog is installed.");
}
}
#endregion
#region Class Properties
public override List<Game> AllInstalledGames
{
get
{
// Load the Gog Games from Gog Client if needed
if (_allGogGames.Count == 0)
LoadInstalledGames();
return _allGogGames;
}
}
public override int InstalledGameCount
{
get
{
return _allGogGames.Count;
}
}
public override string GameLibraryName
{
get
{
return "GOG";
}
}
public override SupportedGameLibraryType GameLibraryType
{
get
{
return SupportedGameLibraryType.GOG;
}
}
public override string GameLibraryExe
{
get
{
return _gogExe;
}
}
public override string GameLibraryPath
{
get
{
return _gogPath;
}
}
public override bool IsGameLibraryInstalled
{
get
{
return _isGogInstalled;
}
}
public override bool IsRunning
{
get
{
List<Process> gogLibraryProcesses = new List<Process>();
foreach (string gogLibraryProcessName in _gogProcessList)
{
// Look for the processes with the ProcessName we sorted out earlier
gogLibraryProcesses.AddRange(Process.GetProcessesByName(gogLibraryProcessName));
}
// If we have found one or more processes then we should be good to go
// so let's break, and get to the next step....
if (gogLibraryProcesses.Count > 0)
return true;
else
return false;
}
}
public override bool IsUpdating
{
get
{
// Not implemeted at present
// so we just return a false
// TODO Implement Gog specific detection for updating the game client
return false;
}
}
public override List<string> GameLibraryProcesses
{
get
{
return _gogProcessList;
}
}
#endregion
#region Class Methods
public static GogLibrary GetLibrary()
{
return _instance;
}
public override bool AddGame(Game gogGame)
{
if (!(gogGame is GogGame))
return false;
// Doublecheck if it already exists
// Because then we just update the one that already exists
if (ContainsGame(gogGame))
{
logger.Debug($"GogLibrary/AddGogGame: Updating Gog game {gogGame.Name} in our Gog library");
// We update the existing Shortcut with the data over
GogGame gogGameToUpdate = (GogGame)GetGame(gogGame.Id.ToString());
gogGame.CopyTo(gogGameToUpdate);
}
else
{
logger.Debug($"GogLibrary/AddGogGame: Adding Gog game {gogGame.Name} to our Gog library");
// Add the GogGame to the list of GogGames
_allGogGames.Add(gogGame);
}
//Doublecheck it's been added
if (ContainsGame(gogGame))
{
return true;
}
else
return false;
}
public override bool RemoveGame(Game gogGame)
{
if (!(gogGame is GogGame))
return false;
logger.Debug($"GogLibrary/RemoveGogGame: Removing Gog game {gogGame.Name} from our Gog library");
// Remove the GogGame from the list.
int numRemoved = _allGogGames.RemoveAll(item => item.Id.Equals(gogGame.Id));
if (numRemoved == 1)
{
logger.Debug($"GogLibrary/RemoveGogGame: Removed Gog game with name {gogGame.Name}");
return true;
}
else if (numRemoved == 0)
{
logger.Debug($"GogLibrary/RemoveGogGame: Didn't remove Gog game with ID {gogGame.Name} from the Gog Library");
return false;
}
else
throw new GogLibraryException();
}
public override bool RemoveGameById(string gogGameId)
{
if (gogGameId.Equals(0))
return false;
logger.Debug($"GogLibrary/RemoveGogGame2: Removing Gog game with ID {gogGameId} from the Gog library");
// Remove the GogGame from the list.
int numRemoved = _allGogGames.RemoveAll(item => item.Id.Equals(gogGameId));
if (numRemoved == 1)
{
logger.Debug($"GogLibrary/RemoveGogGame2: Removed Gog game with ID {gogGameId}");
return true;
}
else if (numRemoved == 0)
{
logger.Debug($"GogLibrary/RemoveGogGame2: Didn't remove Gog game with ID {gogGameId} from the Gog Library");
return false;
}
else
throw new GogLibraryException();
}
public override bool RemoveGame(string gogGameNameOrId)
{
if (String.IsNullOrWhiteSpace(gogGameNameOrId))
return false;
logger.Debug($"GogLibrary/RemoveGogGame3: Removing Gog game with Name or ID {gogGameNameOrId} from the Gog library");
int numRemoved;
Match match = Regex.Match(gogGameNameOrId, GogAppIdRegex, RegexOptions.IgnoreCase);
if (match.Success)
numRemoved = _allGogGames.RemoveAll(item => gogGameNameOrId.Equals(item.Id));
else
numRemoved = _allGogGames.RemoveAll(item => gogGameNameOrId.Equals(item.Name));
if (numRemoved == 1)
{
logger.Debug($"GogLibrary/RemoveGogGame3: Removed Gog game with Name or UUID {gogGameNameOrId} ");
return true;
}
else if (numRemoved == 0)
{
logger.Debug($"GogLibrary/RemoveGogGame3: Didn't remove Gog game with Name or UUID {gogGameNameOrId} from the Gog Library");
return false;
}
else
throw new GogLibraryException();
}
public override bool ContainsGame(Game gogGame)
{
if (!(gogGame is GogGame))
return false;
foreach (GogGame testGogGame in _allGogGames)
{
if (testGogGame.Id.Equals(gogGame.Id))
return true;
}
return false;
}
public override bool ContainsGameById(string gogGameId)
{
foreach (GogGame testGogGame in _allGogGames)
{
if (gogGameId == testGogGame.Id)
return true;
}
return false;
}
public override bool ContainsGame(string gogGameNameOrId)
{
if (String.IsNullOrWhiteSpace(gogGameNameOrId))
return false;
Match match = Regex.Match(gogGameNameOrId, GogAppIdRegex, RegexOptions.IgnoreCase);
if (match.Success)
{
foreach (GogGame testGogGame in _allGogGames)
{
if (gogGameNameOrId.Equals(Convert.ToInt32(testGogGame.Id)))
return true;
}
}
else
{
foreach (GogGame testGogGame in _allGogGames)
{
if (gogGameNameOrId.Equals(testGogGame.Name))
return true;
}
}
return false;
}
public override Game GetGame(string gogGameNameOrId)
{
if (String.IsNullOrWhiteSpace(gogGameNameOrId))
return null;
Match match = Regex.Match(gogGameNameOrId, GogAppIdRegex, RegexOptions.IgnoreCase);
if (match.Success)
{
foreach (GogGame testGogGame in _allGogGames)
{
if (gogGameNameOrId.Equals(Convert.ToInt32(testGogGame.Id)))
return testGogGame;
}
}
else
{
foreach (GogGame testGogGame in _allGogGames)
{
if (gogGameNameOrId.Equals(testGogGame.Name))
return testGogGame;
}
}
return null;
}
public override Game GetGameById(string gogGameId)
{
foreach (GogGame testGogGame in _allGogGames)
{
if (gogGameId == testGogGame.Id)
return testGogGame;
}
return null;
}
public override bool LoadInstalledGames()
{
try
{
if (!_isGogInstalled)
{
// Gog isn't installed, so we return an empty list.
logger.Info($"GogLibrary/LoadInstalledGames: Gog library is not installed");
return false;
}
string gogSupportInstallerDir = Path.Combine(_gogLocalContent, "supportInstaller");
logger.Trace($"GogLibrary/LoadInstalledGames: supportInstaller Directory {gogSupportInstallerDir} exists!");
string[] gogSupportInstallerGameDirs = Directory.GetDirectories(gogSupportInstallerDir, "*", SearchOption.AllDirectories);
logger.Trace($"GogLibrary/LoadInstalledGames: Found game directories in supportInstaller Directory {gogSupportInstallerDir}: {gogSupportInstallerGameDirs.ToString()}");
// If there are no games installed then return false
if (gogSupportInstallerGameDirs.Length == 0)
{
logger.Warn($"GogLibrary/LoadInstalledGames: No GOG games installed in the GOG Galaxy library");
return false;
}
foreach (string gogSupportInstallerGameDir in gogSupportInstallerGameDirs)
{
logger.Trace($"GogLibrary/LoadInstalledGames: Parsing {gogSupportInstallerGameDir} name to find GameID");
Match match = Regex.Match(gogSupportInstallerGameDir, @"(\d{10})$");
if (!match.Success)
{
logger.Warn($"GogLibrary/LoadInstalledGames: Failed to match the 10 digit game id from directory name {gogSupportInstallerGameDir} so ignoring game");
continue;
}
string gameID = match.Groups[1].Value;
logger.Trace($"GogLibrary/LoadInstalledGames: Found GameID {gameID} matching pattern in game directory name");
string gogGameInfoFilename = Path.Combine(gogSupportInstallerGameDir, $"goggame-{gameID}.info");
logger.Trace($"GogLibrary/LoadInstalledGames: Looking for games info file {gogGameInfoFilename}");
if (!File.Exists(gogGameInfoFilename))
{
logger.Warn($"GogLibrary/LoadInstalledGames: Couldn't find games info file {gogGameInfoFilename}. There seems to be a problem with your GOG installation.");
continue;
}
// Now we get the information from the Gog Info file to parse it
GogGameInfo gogGameInfo;
try
{
gogGameInfo = JsonConvert.DeserializeObject<GogGameInfo>(File.ReadAllText(gogGameInfoFilename));
}
catch (Exception ex)
{
logger.Warn(ex, $"GogLibrary/LoadInstalledGames: Exception trying to convert the {gogGameInfoFilename} to a JSON object to read the installed games. There seems to be a problem with your GOG installation.");
continue;
}
// Now we check this is a 'Root Game' i.e. it is a base game, not something else
if (gogGameInfo.gameId != gogGameInfo.rootGameId)
{
logger.Trace($"GogLibrary/LoadInstalledGames: Game {gogGameInfo.name} is not a base game (probably DLC) so we're skipping it.");
}
// Now we check the Gog game registry key too, to get some more information that we need
string registryGogGalaxyGameKey = registryGogGalaxyGamesKey + gogGameInfo.gameId;
logger.Trace($"GogLibrary/GogLibrary: GOG Galaxy Games registry key = HKLM\\{registryGogGalaxyGameKey}");
RegistryKey GogGalaxyGameKey = Registry.LocalMachine.OpenSubKey(registryGogGalaxyGameKey, RegistryKeyPermissionCheck.ReadSubTree);
if (GogGalaxyGameKey == null)
{
logger.Info($"GogLibrary/GogLibrary: Could not find the GOG Galaxy Games registry key {registryGogGalaxyGamesKey} so can't get all the information about the game we need! There seems to be a problem with your GOG installation.");
continue;
}
string gameDirectory = GogGalaxyGameKey.GetValue("path", "").ToString();
string gameExePath = GogGalaxyGameKey.GetValue("exe", "").ToString();
if (!File.Exists(gameExePath))
{
logger.Info($"GogLibrary/GogLibrary: Could not find the GOG Galaxy Game file {gameExePath} so can't run the game later! There seems to be a problem with your GOG installation.");
continue;
}
/*string gameIconPath = Path.Combine(gameDirectory, $"goggame-{gameID}.ico");
if (!File.Exists(gameIconPath))
{
gameIconPath = gameExePath;
}*/
// Extract the info into a game object
GogGame gogGame = new GogGame();
gogGame.Id = gogGameInfo.gameId;
gogGame.Name = gogGameInfo.name;
gogGame.Directory = gameDirectory;
gogGame.Executable = GogGalaxyGameKey.GetValue("exeFile", "").ToString();
gogGame.ExePath = gameExePath;
//gogGame.IconPath = gameIconPath;
gogGame.IconPath = gameExePath;
gogGame.ProcessName = Path.GetFileNameWithoutExtension(gogGame.ExePath);
// Add the Gog Game to the list of Gog Games
_allGogGames.Add(gogGame);
}
logger.Info($"GogLibrary/LoadInstalledGames: Found {_allGogGames.Count} installed GOG games");
}
catch (ArgumentNullException ex)
{
logger.Warn(ex, "GogLibrary/GetAllInstalledGames: An argument supplied to the function is null.");
}
catch (NotSupportedException ex)
{
logger.Warn(ex, "GogLibrary/GetAllInstalledGames: The invoked method is not supported or reading, seeking or writing to a stream that isn't supported.");
}
catch (PathTooLongException ex)
{
logger.Warn(ex, "GogLibrary/GetAllInstalledGames: The path is longer than the maximum allowed by the operating system.");
}
catch (SecurityException ex)
{
logger.Warn(ex, "GogLibrary/GetAllInstalledGames: The user does not have the permissions required to read the GOG InstallDir registry key.");
}
catch (ObjectDisposedException ex)
{
logger.Warn(ex, "GogLibrary/GetAllInstalledGames: The Microsoft.Win32.RegistryKey is closed when trying to access the GOG InstallDir registry key (closed keys cannot be accessed).");
}
catch (IOException ex)
{
logger.Warn(ex, "GogLibrary/GetAllInstalledGames: The GOG InstallDir registry key has been marked for deletion so we cannot access the value dueing the GogLibrary check.");
}
catch (UnauthorizedAccessException ex)
{
logger.Warn(ex, "GogLibrary/GetAllInstalledGames: The user does not have the necessary registry rights to check whether Gog is installed.");
}
return true;
}
public override Process StartGame(Game game, string gameArguments = "")
{
string args = $@"/command=runGame /gameId={game.Id} /path=""{game.Directory}""";
if (String.IsNullOrWhiteSpace(gameArguments))
{
args += gameArguments;
}
Process gameProcess = Process.Start(_gogExe,args);
return gameProcess;
}
#endregion
}
public class GogPlayTask
{
public string category;
public string compatibilityFlags;
public bool isPrimary;
public List<string> languages;
public string name;
public string path;
public string type;
}
public class GogGameInfo
{
public string buildId;
public string clientId;
public string gameId;
public string language;
public List<string> languages;
public string name;
public List<GogPlayTask> playTasks;
public string rootGameId;
public int version;
}
[global::System.Serializable]
public class GogLibraryException : GameLibraryException
{
public GogLibraryException() { }
public GogLibraryException(string message) : base(message) { }
public GogLibraryException(string message, Exception inner) : base(message, inner) { }
protected GogLibraryException(
System.Runtime.Serialization.SerializationInfo info,
System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
}
}

View File

@ -6,11 +6,6 @@ namespace DisplayMagician.GameLibraries
public class Game
{
public enum GameStartMode
{
URI
}
private static readonly NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
#region Properties
@ -34,18 +29,12 @@ namespace DisplayMagician.GameLibraries
public virtual string ProcessName { get; set; }
public virtual GameStartMode StartMode { get; set; }
public Bitmap GameBitmap { get; set; }
#endregion
#region Methods
public virtual string GetStartURI(string gameArguments = "")
{
return "";
}
public virtual bool CopyTo(Game steamGame)
{

View File

@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
namespace DisplayMagician.GameLibraries
{
@ -9,7 +10,8 @@ namespace DisplayMagician.GameLibraries
Steam,
Uplay,
Origin,
Epic
Epic,
GOG
}
public class GameLibrary
@ -100,6 +102,11 @@ namespace DisplayMagician.GameLibraries
return false;
}
public virtual Process StartGame(Game game, string gameArguments = "")
{
return null;
}
#endregion
}

View File

@ -140,21 +140,6 @@ namespace DisplayMagician.GameLibraries
}
}
public override GameStartMode StartMode
{
get => GameStartMode.URI;
}
public override string GetStartURI(string gameArguments = "")
{
string address = $"origin2://game/launch?offerIds={_originGameId}";
if (String.IsNullOrWhiteSpace(gameArguments))
{
address += "/" + gameArguments;
}
return address;
}
public bool CopyTo(OriginGame OriginGame)
{
if (!(OriginGame is OriginGame))

View File

@ -738,6 +738,16 @@ namespace DisplayMagician.GameLibraries
return true;
}
public override Process StartGame(Game game, string gameArguments = "")
{
string address = $"origin2://game/launch?offerIds={game.Id}";
if (String.IsNullOrWhiteSpace(gameArguments))
{
address += "/" + gameArguments;
}
Process gameProcess = Process.Start(address);
return gameProcess;
}
#endregion
}

View File

@ -167,21 +167,6 @@ namespace DisplayMagician.GameLibraries
}
}
public override GameStartMode StartMode
{
get => GameStartMode.URI;
}
public override string GetStartURI(string gameArguments = "")
{
string address = $"steam://rungameid/{Id}";
if (String.IsNullOrWhiteSpace(gameArguments))
{
address += "/" + gameArguments;
}
return address;
}
public bool CopyInto(SteamGame steamGame)
{
if (!(steamGame is SteamGame))

View File

@ -754,6 +754,17 @@ namespace DisplayMagician.GameLibraries
return true;
}
public override Process StartGame(Game game, string gameArguments = "")
{
string address = $"steam://rungameid/{game.Id}";
if (!String.IsNullOrWhiteSpace(gameArguments))
{
address += "/" + gameArguments;
}
Process gameProcess = Process.Start(address);
return gameProcess;
}
#endregion
}

View File

@ -139,25 +139,6 @@ namespace DisplayMagician.GameLibraries
}
}
public override GameStartMode StartMode
{
get => GameStartMode.URI;
}
public override string GetStartURI(string gameArguments = "")
{
string address = $"uplay://launch/{Id}";
if (String.IsNullOrWhiteSpace(gameArguments))
{
address += "/" + gameArguments;
}
else
{
address += "/0";
}
return address;
}
public bool CopyTo(UplayGame uplayGame)
{
if (!(uplayGame is UplayGame))

View File

@ -717,6 +717,22 @@ namespace DisplayMagician.GameLibraries
return true;
}
public override Process StartGame(Game game, string gameArguments = "")
{
string address = $"uplay://launch/{game.Id}";
if (String.IsNullOrWhiteSpace(gameArguments))
{
address += "/" + gameArguments;
}
else
{
address += "/0";
}
Process gameProcess = Process.Start(address);
return gameProcess;
}
#endregion
}

View File

@ -810,7 +810,7 @@ namespace DisplayMagician {
logger.Info($"Program/LoadGamesInBackground: Loading Installed Epic Games");
if (!epicLibrary.LoadInstalledGames())
{
logger.Info($"Program/LoadGamesInBackground: Cannot load installed OrigiEpicn Games!");
logger.Info($"Program/LoadGamesInBackground: Cannot load installed Epic Games!");
}
logger.Info($"Program/LoadGamesInBackground: Loaded all Installed Epic Games (found {epicLibrary.InstalledGameCount})");
}
@ -822,6 +822,28 @@ namespace DisplayMagician {
});
// Now lets prepare loading all the GOG games we have installed
Action loadGogGamesAction = new Action(() =>
{
// Check if GOG is installed
GameLibrary gogLibrary = GogLibrary.GetLibrary();
if (gogLibrary.IsGameLibraryInstalled)
{
// Load Origin library games
logger.Info($"Program/LoadGamesInBackground: Loading Installed GOG Games");
if (!gogLibrary.LoadInstalledGames())
{
logger.Info($"Program/LoadGamesInBackground: Cannot load installed GOG Games!");
}
logger.Info($"Program/LoadGamesInBackground: Loaded all Installed GOG Games (found {gogLibrary.InstalledGameCount})");
}
else
{
logger.Info($"Program/LoadGamesInBackground: GOG not installed.");
Console.WriteLine("GOG not installed.");
}
});
// Store all the actions in a array so we can wait on them later
List<Action> loadGamesActions = new List<Action>();
@ -829,6 +851,7 @@ namespace DisplayMagician {
loadGamesActions.Add(loadUplayGamesAction);
loadGamesActions.Add(loadOriginGamesAction);
loadGamesActions.Add(loadEpicGamesAction);
loadGamesActions.Add(loadGogGamesAction);
try
{
@ -849,6 +872,7 @@ namespace DisplayMagician {
GameLibrary.AllInstalledGamesInAllLibraries.AddRange(UplayLibrary.GetLibrary().AllInstalledGames);
GameLibrary.AllInstalledGamesInAllLibraries.AddRange(OriginLibrary.GetLibrary().AllInstalledGames);
GameLibrary.AllInstalledGamesInAllLibraries.AddRange(EpicLibrary.GetLibrary().AllInstalledGames);
GameLibrary.AllInstalledGamesInAllLibraries.AddRange(GogLibrary.GetLibrary().AllInstalledGames);
// Create Game Bitmaps from the Games so the rest of the program is faster later
// Get the bitmap out of the IconPath
@ -895,6 +919,8 @@ namespace DisplayMagician {
bm = Properties.Resources.Origin;
else if (game.GameLibrary.Equals(SupportedGameLibraryType.Epic))
bm = Properties.Resources.Epic;
else if (game.GameLibrary.Equals(SupportedGameLibraryType.GOG))
bm = Properties.Resources.GOG;
else
bm = Properties.Resources.DisplayMagician.ToBitmap();
}

View File

@ -90,6 +90,16 @@ namespace DisplayMagician.Properties {
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
public static System.Drawing.Bitmap GOG {
get {
object obj = ResourceManager.GetObject("GOG", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>

View File

@ -151,4 +151,7 @@
<data name="Uplay" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\Uplay.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="GOG" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\GOG.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
</root>

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

View File

@ -1012,6 +1012,11 @@ namespace DisplayMagician
logger.Trace($"ShortcutItem/SaveShortcutIconToCache: Using the Epic icon as the icon instead.");
bm = ToBitmapOverlay(Properties.Resources.Epic, _profileToUse.ProfileIcon.ToBitmap(), 256, 256);
}
else if (_gameLibrary == SupportedGameLibraryType.GOG)
{
logger.Trace($"ShortcutItem/SaveShortcutIconToCache: Using the GOG icon as the icon instead.");
bm = ToBitmapOverlay(Properties.Resources.GOG, _profileToUse.ProfileIcon.ToBitmap(), 256, 256);
}
si.Add(bm);
logger.Trace($"ShortcutItem/SaveShortcutIconToCache: Saving the replacement icon for Shortcut '{Name}' to {_savedShortcutIconCacheFilename}.");
shortcutIcon.Save(_savedShortcutIconCacheFilename, MultiIconFormat.ICO);
@ -1063,6 +1068,11 @@ namespace DisplayMagician
logger.Trace($"ShortcutItem/SaveShortcutIconToCache: Using the Epic icon as the icon instead.");
originalBitmap = Properties.Resources.Epic;
}
else if (_gameLibrary == SupportedGameLibraryType.GOG)
{
logger.Trace($"ShortcutItem/SaveShortcutIconToCache: Using the GOG icon as the icon instead.");
originalBitmap = Properties.Resources.GOG;
}
else
{
logger.Trace($"ShortcutItem/SaveShortcutIconToCache: Unknown Game Library, so using the DisplayMagician icon as the icon instead.");
@ -1192,6 +1202,13 @@ namespace DisplayMagician
// We now need to get the Epic Game info
gameLibraryToUse = EpicLibrary.GetLibrary();
}
// If the game is an GOG Game we check for that
else if (GameLibrary.Equals(SupportedGameLibraryType.GOG))
{
logger.Trace($"ShortcutItem/RefreshValidity: The game library is GOG");
// We now need to get the GOG Game info
gameLibraryToUse = GogLibrary.GetLibrary();
}
// Check if Gamelibrary is installed and error if it isn't
if (!gameLibraryToUse.IsGameLibraryInstalled)

View File

@ -1073,6 +1073,11 @@ namespace DisplayMagician
// We now need to get the Epic Game info
gameLibraryToUse = EpicLibrary.GetLibrary();
}
else if (shortcutToUse.GameLibrary.Equals(SupportedGameLibraryType.GOG))
{
// We now need to get the GOG Game info
gameLibraryToUse = GogLibrary.GetLibrary();
}
gameToRun = gameLibraryToUse.GetGameById(shortcutToUse.GameAppId);
logger.Info($"ShortcutRepository/RunShortcut: Starting the {gameToRun.Name} {gameLibraryToUse.GameLibraryName} Game, and then we're going to monitor it to wait for it to close.");
@ -1100,24 +1105,9 @@ namespace DisplayMagician
DesktopNotifications.DesktopNotificationManagerCompat.CreateToastNotifier().Show(toast);
Process gameProcess;
if (gameToRun.StartMode.Equals(Game.GameStartMode.URI))
{
// Prepare to start the game using the URI method
string address = "";
if (shortcutToUse.GameArgumentsRequired)
{
address = gameToRun.GetStartURI(shortcutToUse.GameArguments);
logger.Debug($"ShortcutRepository/RunShortcut: Shortcut has arguments: {shortcutToUse.GameArguments}");
}
else
{
address = gameToRun.GetStartURI("");
logger.Debug($"ShortcutRepository/RunShortcut: Shortcut has no arguments");
}
logger.Debug($"ShortcutRepository/RunShortcut: Game launch URI is {address}");
gameProcess = Process.Start(address);
}
//string gameRunCmd = gameLibraryToUse.GetRunCmd(gameToRun, shortcutToUse.GameArguments);
//gameProcess = Process.Start(gameRunCmd);
gameProcess = gameLibraryToUse.StartGame(gameToRun, shortcutToUse.GameArguments);
// Delay 500ms
Thread.Sleep(500);

View File

@ -130,6 +130,10 @@ namespace DisplayMagician.UIForms
{
return SupportedGameLibraryType.Epic;
}
else if (txt_game_launcher.Text.Contains("GOG"))
{
return SupportedGameLibraryType.GOG;
}
return SupportedGameLibraryType.Unknown;
}
@ -153,6 +157,10 @@ namespace DisplayMagician.UIForms
txt_game_launcher.Text = Enum.GetName(typeof(SupportedGameLibraryType), SupportedGameLibraryType.Epic);
break;
case SupportedGameLibraryType.GOG:
txt_game_launcher.Text = Enum.GetName(typeof(SupportedGameLibraryType), SupportedGameLibraryType.GOG);
break;
case SupportedGameLibraryType.Unknown:
txt_game_launcher.Text = "No supported Game Libraries found";
break;
@ -523,6 +531,12 @@ namespace DisplayMagician.UIForms
logger.Trace($"ShortcutForm/btn_save_Click: We're saving an Epic game!");
_gameToUse.GameToPlay = (from epicGame in EpicLibrary.GetLibrary().AllInstalledGames where epicGame.Id == _gameId select epicGame).First();
}
// If the game is an GOG Game
else if (txt_game_launcher.Text == SupportedGameLibraryType.GOG.ToString())
{
logger.Trace($"ShortcutForm/btn_save_Click: We're saving an GOG game!");
_gameToUse.GameToPlay = (from gogGame in GogLibrary.GetLibrary().AllInstalledGames where gogGame.Id == _gameId select gogGame).First();
}
try
{