mirror of
https://github.com/terrymacdonald/DisplayMagician.git
synced 2024-08-30 18:32:20 +00:00
734 lines
35 KiB
C#
734 lines
35 KiB
C#
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;
|
|
|
|
namespace DisplayMagician.GameLibraries
|
|
{
|
|
public sealed class OriginLibrary : 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 OriginLibrary _instance = new OriginLibrary();
|
|
|
|
|
|
// Common items to the class
|
|
private List<Game> _allOriginGames = new List<Game>();
|
|
private string OriginAppIdRegex = @"/^[0-9A-F]{1,10}$";
|
|
private string _originExe;
|
|
private string _originPath;
|
|
private string _originLocalContent = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), "Origin");
|
|
private bool _isOriginInstalled = false;
|
|
private List<string> _originProcessList = new List<string>(){ "origin" };
|
|
|
|
//private string _originConfigVdfFile;
|
|
internal string registryOriginLauncherKey = @"SOFTWARE\WOW6432Node\Origin";
|
|
//internal string registryOriginInstallsKey = @"SOFTWARE\WOW6432Node\Ubisoft\Launcher\Installs";
|
|
//internal string registryOriginOpenCmdKey = @"SOFTWARE\Classes\Origin\Shell\Open\Command";
|
|
private readonly NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
|
|
|
|
|
|
// Other constants that are useful
|
|
#endregion
|
|
|
|
#region Class Constructors
|
|
static OriginLibrary() { }
|
|
|
|
private OriginLibrary()
|
|
{
|
|
try
|
|
{
|
|
logger.Trace($"OriginLibrary/OriginLibrary: Origin launcher registry key = HKLM\\{registryOriginLauncherKey}");
|
|
// Find the OriginExe location, and the OriginPath for later
|
|
RegistryKey OriginInstallKey = Registry.LocalMachine.OpenSubKey(registryOriginLauncherKey, RegistryKeyPermissionCheck.ReadSubTree);
|
|
if (OriginInstallKey == null)
|
|
return;
|
|
_originExe = OriginInstallKey.GetValue("ClientPath", @"C:\Program Files (x86)\Origin\Origin.exe").ToString();
|
|
_originPath = _originExe;
|
|
_originPath = _originPath.Replace(@"\Origin.exe", "");
|
|
if (File.Exists(_originExe))
|
|
{
|
|
logger.Info($"OriginLibrary/OriginLibrary: Origin library is installed in {_originPath}. Found {_originExe}");
|
|
_isOriginInstalled = true;
|
|
}
|
|
else
|
|
{
|
|
logger.Info($"OriginLibrary/OriginLibrary: Origin library is not installed!");
|
|
}
|
|
|
|
}
|
|
catch (SecurityException ex)
|
|
{
|
|
logger.Warn(ex, "OriginLibrary/OriginLibrary: The user does not have the permissions required to read the Origin ClientPath registry key.");
|
|
}
|
|
catch(ObjectDisposedException ex)
|
|
{
|
|
logger.Warn(ex, "OriginLibrary/OriginLibrary: The Microsoft.Win32.RegistryKey is closed when trying to access the Origin ClientPath registry key (closed keys cannot be accessed).");
|
|
}
|
|
catch (IOException ex)
|
|
{
|
|
logger.Warn(ex, "OriginLibrary/OriginLibrary: The Origin ClientPath registry key has been marked for deletion so we cannot access the value dueing the OriginLibrary check.");
|
|
}
|
|
catch (UnauthorizedAccessException ex)
|
|
{
|
|
logger.Warn(ex, "OriginLibrary/OriginLibrary: The user does not have the necessary registry rights to check whether Origin is installed.");
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
#region Class Properties
|
|
public override List<Game> AllInstalledGames
|
|
{
|
|
get
|
|
{
|
|
// Load the Origin Games from Origin Client if needed
|
|
if (_allOriginGames.Count == 0)
|
|
LoadInstalledGames();
|
|
return _allOriginGames;
|
|
}
|
|
}
|
|
|
|
|
|
public override int InstalledGameCount
|
|
{
|
|
get
|
|
{
|
|
return _allOriginGames.Count;
|
|
}
|
|
}
|
|
|
|
public override string GameLibraryName
|
|
{
|
|
get
|
|
{
|
|
return "Origin";
|
|
}
|
|
}
|
|
|
|
public override SupportedGameLibraryType GameLibraryType
|
|
{
|
|
get
|
|
{
|
|
return SupportedGameLibraryType.Origin;
|
|
}
|
|
}
|
|
|
|
public override string GameLibraryExe
|
|
{
|
|
get
|
|
{
|
|
return _originExe;
|
|
}
|
|
}
|
|
|
|
public override string GameLibraryPath
|
|
{
|
|
get
|
|
{
|
|
return _originPath;
|
|
}
|
|
}
|
|
|
|
public override bool IsGameLibraryInstalled
|
|
{
|
|
get
|
|
{
|
|
return _isOriginInstalled;
|
|
}
|
|
|
|
}
|
|
|
|
public override bool IsRunning
|
|
{
|
|
get
|
|
{
|
|
List<Process> originLibraryProcesses = new List<Process>();
|
|
|
|
foreach (string originLibraryProcessName in _originProcessList)
|
|
{
|
|
// Look for the processes with the ProcessName we sorted out earlier
|
|
originLibraryProcesses.AddRange(Process.GetProcessesByName(originLibraryProcessName));
|
|
}
|
|
|
|
// 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 (originLibraryProcesses.Count > 0)
|
|
return true;
|
|
else
|
|
return false;
|
|
}
|
|
|
|
}
|
|
|
|
public override List<string> GameLibraryProcesses
|
|
{
|
|
get
|
|
{
|
|
return _originProcessList;
|
|
}
|
|
}
|
|
|
|
|
|
#endregion
|
|
|
|
#region Class Methods
|
|
public static OriginLibrary GetLibrary()
|
|
{
|
|
return _instance;
|
|
}
|
|
|
|
|
|
public override bool AddGame(Game originGame)
|
|
{
|
|
if (!(originGame is OriginGame))
|
|
return false;
|
|
|
|
// Doublecheck if it already exists
|
|
// Because then we just update the one that already exists
|
|
if (ContainsGame(originGame))
|
|
{
|
|
logger.Debug($"OriginLibrary/AddOriginGame: Updating Origin game {originGame.Name} in our Origin library");
|
|
// We update the existing Shortcut with the data over
|
|
OriginGame originGameToUpdate = (OriginGame)GetGame(originGame.Id.ToString());
|
|
originGame.CopyTo(originGameToUpdate);
|
|
}
|
|
else
|
|
{
|
|
logger.Debug($"OriginLibrary/AddOriginGame: Adding Origin game {originGame.Name} to our Origin library");
|
|
// Add the OriginGame to the list of OriginGames
|
|
_allOriginGames.Add(originGame);
|
|
}
|
|
|
|
//Doublecheck it's been added
|
|
if (ContainsGame(originGame))
|
|
{
|
|
return true;
|
|
}
|
|
else
|
|
return false;
|
|
|
|
}
|
|
|
|
public override bool RemoveGame(Game originGame)
|
|
{
|
|
if (!(originGame is OriginGame))
|
|
return false;
|
|
|
|
logger.Debug($"OriginLibrary/RemoveOriginGame: Removing Origin game {originGame.Name} from our Origin library");
|
|
|
|
// Remove the OriginGame from the list.
|
|
int numRemoved = _allOriginGames.RemoveAll(item => item.Id.Equals(originGame.Id));
|
|
|
|
if (numRemoved == 1)
|
|
{
|
|
logger.Debug($"OriginLibrary/RemoveOriginGame: Removed Origin game with name {originGame.Name}");
|
|
return true;
|
|
}
|
|
else if (numRemoved == 0)
|
|
{
|
|
logger.Debug($"OriginLibrary/RemoveOriginGame: Didn't remove Origin game with ID {originGame.Name} from the Origin Library");
|
|
return false;
|
|
}
|
|
else
|
|
throw new OriginLibraryException();
|
|
}
|
|
|
|
public override bool RemoveGameById(string originGameId)
|
|
{
|
|
if (originGameId.Equals(0))
|
|
return false;
|
|
|
|
logger.Debug($"OriginLibrary/RemoveOriginGame2: Removing Origin game with ID {originGameId} from the Origin library");
|
|
|
|
// Remove the OriginGame from the list.
|
|
int numRemoved = _allOriginGames.RemoveAll(item => item.Id.Equals(originGameId));
|
|
|
|
if (numRemoved == 1)
|
|
{
|
|
logger.Debug($"OriginLibrary/RemoveOriginGame2: Removed Origin game with ID {originGameId}");
|
|
return true;
|
|
}
|
|
else if (numRemoved == 0)
|
|
{
|
|
logger.Debug($"OriginLibrary/RemoveOriginGame2: Didn't remove Origin game with ID {originGameId} from the Origin Library");
|
|
return false;
|
|
}
|
|
else
|
|
throw new OriginLibraryException();
|
|
}
|
|
|
|
public override bool RemoveGame(string originGameNameOrId)
|
|
{
|
|
if (String.IsNullOrWhiteSpace(originGameNameOrId))
|
|
return false;
|
|
|
|
logger.Debug($"OriginLibrary/RemoveOriginGame3: Removing Origin game with Name or ID {originGameNameOrId} from the Origin library");
|
|
|
|
int numRemoved;
|
|
Match match = Regex.Match(originGameNameOrId, OriginAppIdRegex, RegexOptions.IgnoreCase);
|
|
if (match.Success)
|
|
numRemoved = _allOriginGames.RemoveAll(item => originGameNameOrId.Equals(item.Id));
|
|
else
|
|
numRemoved = _allOriginGames.RemoveAll(item => originGameNameOrId.Equals(item.Name));
|
|
|
|
if (numRemoved == 1)
|
|
{
|
|
logger.Debug($"OriginLibrary/RemoveOriginGame3: Removed Origin game with Name or UUID {originGameNameOrId} ");
|
|
return true;
|
|
}
|
|
else if (numRemoved == 0)
|
|
{
|
|
logger.Debug($"OriginLibrary/RemoveOriginGame3: Didn't remove Origin game with Name or UUID {originGameNameOrId} from the Origin Library");
|
|
return false;
|
|
}
|
|
else
|
|
throw new OriginLibraryException();
|
|
|
|
}
|
|
|
|
public override bool ContainsGame(Game originGame)
|
|
{
|
|
if (!(originGame is OriginGame))
|
|
return false;
|
|
|
|
foreach (OriginGame testOriginGame in _allOriginGames)
|
|
{
|
|
if (testOriginGame.Id.Equals(originGame.Id))
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public override bool ContainsGameById(string originGameId)
|
|
{
|
|
foreach (OriginGame testOriginGame in _allOriginGames)
|
|
{
|
|
if (originGameId == testOriginGame.Id)
|
|
return true;
|
|
}
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
public override bool ContainsGame(string originGameNameOrId)
|
|
{
|
|
if (String.IsNullOrWhiteSpace(originGameNameOrId))
|
|
return false;
|
|
|
|
|
|
Match match = Regex.Match(originGameNameOrId, OriginAppIdRegex, RegexOptions.IgnoreCase);
|
|
if (match.Success)
|
|
{
|
|
foreach (OriginGame testOriginGame in _allOriginGames)
|
|
{
|
|
if (originGameNameOrId.Equals(Convert.ToInt32(testOriginGame.Id)))
|
|
return true;
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
foreach (OriginGame testOriginGame in _allOriginGames)
|
|
{
|
|
if (originGameNameOrId.Equals(testOriginGame.Name))
|
|
return true;
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
public override Game GetGame(string originGameNameOrId)
|
|
{
|
|
if (String.IsNullOrWhiteSpace(originGameNameOrId))
|
|
return null;
|
|
|
|
Match match = Regex.Match(originGameNameOrId, OriginAppIdRegex, RegexOptions.IgnoreCase);
|
|
if (match.Success)
|
|
{
|
|
foreach (OriginGame testOriginGame in _allOriginGames)
|
|
{
|
|
if (originGameNameOrId.Equals(Convert.ToInt32(testOriginGame.Id)))
|
|
return testOriginGame;
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
foreach (OriginGame testOriginGame in _allOriginGames)
|
|
{
|
|
if (originGameNameOrId.Equals(testOriginGame.Name))
|
|
return testOriginGame;
|
|
}
|
|
|
|
}
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
public override Game GetGameById(string originGameId)
|
|
{
|
|
foreach (OriginGame testOriginGame in _allOriginGames)
|
|
{
|
|
if (originGameId == testOriginGame.Id)
|
|
return testOriginGame;
|
|
}
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
private Dictionary<string, string> ParseOriginManifest(string path)
|
|
{
|
|
string encodedContents = File.ReadAllText(path);
|
|
Dictionary<string, string> parameters = Regex.Matches(encodedContents, "([^?=&]+)(=([^&]*))?").Cast<Match>().ToDictionary(x => x.Groups[1].Value, x => x.Groups[3].Value);
|
|
return parameters;
|
|
}
|
|
|
|
|
|
public override bool LoadInstalledGames()
|
|
{
|
|
try
|
|
{
|
|
|
|
if (!_isOriginInstalled)
|
|
{
|
|
// Origin isn't installed, so we return an empty list.
|
|
logger.Info($"OriginLibrary/LoadInstalledGames: Origin library is not installed");
|
|
return false;
|
|
}
|
|
|
|
var localContentPath = Path.Combine(_originLocalContent, "LocalContent");
|
|
//var games = new Dictionary<string, GameInfo>();
|
|
|
|
if (Directory.Exists(localContentPath))
|
|
{
|
|
string[] packages = Directory.GetFiles(localContentPath, "*.mfst", SearchOption.AllDirectories);
|
|
foreach (string package in packages)
|
|
{
|
|
try
|
|
{
|
|
GameAppInfo originGame = new GameAppInfo();
|
|
originGame.GameID = Path.GetFileNameWithoutExtension(package);
|
|
if (!originGame.GameID.StartsWith("Origin"))
|
|
{
|
|
// If the gameId doesn't start with origin, then we need to find it!
|
|
// Get game id by fixing file via adding : before integer part of the name
|
|
// for example OFB-EAST52017 converts to OFB-EAST:52017
|
|
Match match = Regex.Match(originGame.GameID, @"^(.*?)(\d+)$");
|
|
if (!match.Success)
|
|
{
|
|
logger.Warn("Failed to get game id from file " + package);
|
|
continue;
|
|
}
|
|
|
|
originGame.GameID = match.Groups[1].Value + ":" + match.Groups[2].Value;
|
|
}
|
|
|
|
// Now we get the rest of the game information out of the manifest file
|
|
Dictionary<string, string> manifestInfo = ParseOriginManifest(package);
|
|
|
|
if (manifestInfo.ContainsKey("ddinitialdownload") && manifestInfo["ddinitialdownload"] == "1")
|
|
{
|
|
// Origin is downloading and installing the game so we skip it
|
|
continue;
|
|
}
|
|
if (manifestInfo.ContainsKey("downloading") && manifestInfo["downloading"] == "1")
|
|
{
|
|
// Origin is downloading some new content so we can't play it at the moment
|
|
// but we can still configure it
|
|
continue;
|
|
}
|
|
|
|
originGame.GameInstallDir = null;
|
|
if (manifestInfo.ContainsKey("dipinstallpath"))
|
|
{
|
|
// This is where Origin has installed this game
|
|
originGame.GameInstallDir = HttpUtility.UrlDecode(manifestInfo["dipinstallpath"]);
|
|
if (!Directory.Exists(originGame.GameInstallDir))
|
|
{
|
|
logger.Debug($"OriginLibrary/LoadInstalledGames: Origin game with ID {originGame.GameID} found but no valid directory found at {originGame.GameInstallDir}");
|
|
continue;
|
|
}
|
|
}
|
|
|
|
|
|
// Now we want to look in the dinstallpath location for the game info
|
|
// for the __Installer\installerdata.xml
|
|
if (String.IsNullOrEmpty(originGame.GameInstallDir))
|
|
{
|
|
// then we have a problem and we need to continue and ignore this game
|
|
logger.Warn($"OriginLibrary/LoadInstalledGames: Origin game with ID {originGame.GameID} has registry but we can't find install dir!");
|
|
continue;
|
|
}
|
|
|
|
string gameInstallerData = Path.Combine(originGame.GameInstallDir, @"__Installer", @"installerdata.xml");
|
|
|
|
if (File.Exists(gameInstallerData))
|
|
{
|
|
// Now we parse the XML
|
|
XDocument xdoc = XDocument.Load(gameInstallerData);
|
|
originGame.GameName = xdoc.XPathSelectElement("/DiPManifest/gameTitles/gameTitle[@locale='en_US']").Value;
|
|
string gameFilePath = xdoc.XPathSelectElement("/DiPManifest/runtime/launcher/filePath").Value;
|
|
// Check whether gameFilePath contains a registry key! Cause if it does we need to lookup the path there instead
|
|
if (gameFilePath.StartsWith("[HKEY_LOCAL_MACHINE"))
|
|
{
|
|
// The filePath contains a registry key lookup that we need to execute and replace
|
|
MatchCollection mc = Regex.Matches(gameFilePath, @"\[HKEY_LOCAL_MACHINE\\(.*)\](.*)");
|
|
string originGameInstallKeyNameAndValue = mc[0].Groups[1].ToString();
|
|
string originGameRestOfFile = mc[0].Groups[2].ToString();
|
|
if (originGameInstallKeyNameAndValue == null)
|
|
{
|
|
// then we have a problem and we need to continue and ignore this game
|
|
logger.Warn($"OriginLibrary/LoadInstalledGames: Origin game with ID {originGame.GameID} has registry but we can't match it! gameFilePath is {gameFilePath}.");
|
|
continue;
|
|
}
|
|
|
|
mc = Regex.Matches(originGameInstallKeyNameAndValue, @"(.*)\\([^\\]*)");
|
|
string originGameInstallKeyName = mc[0].Groups[1].ToString();
|
|
string originGameInstallKeyValue = mc[0].Groups[2].ToString();
|
|
|
|
try
|
|
{
|
|
RegistryKey originGameInstallKey = Registry.LocalMachine.OpenSubKey(originGameInstallKeyName, RegistryKeyPermissionCheck.ReadSubTree);
|
|
if (originGameInstallKey == null)
|
|
{
|
|
// then we have a problem as we cannot find the game exe location!
|
|
logger.Warn($"OriginLibrary/LoadInstalledGames: Origin game with ID {originGame.GameID} has a install reg key we cannot find! originGameInstallKey is {gameFilePath} and originGameInstallKeyValue is {originGameInstallKeyValue}.");
|
|
continue;
|
|
}
|
|
string originGameInstallLocation = originGameInstallKey.GetValue(originGameInstallKeyValue).ToString();
|
|
originGameInstallLocation = Path.Combine(originGameInstallLocation, originGameRestOfFile);
|
|
if (!File.Exists(originGameInstallLocation))
|
|
{
|
|
// then we have a problem as we cannot locate the game exe file to start!
|
|
logger.Warn($"OriginLibrary/LoadInstalledGames: Origin game with ID {originGame.GameID} has gameexe we cannot find! originGameInstallLocation is {originGameInstallLocation}.");
|
|
continue;
|
|
}
|
|
originGame.GameExePath = originGameInstallLocation;
|
|
|
|
}
|
|
catch (SecurityException ex)
|
|
{
|
|
logger.Warn(ex, "OriginLibrary/LoadInstalledGames: The user does not have the permissions required to read the Origin Game location registry key {}.");
|
|
}
|
|
catch (ObjectDisposedException ex)
|
|
{
|
|
logger.Warn(ex, "OriginLibrary/LoadInstalledGames: The Microsoft.Win32.RegistryKey is closed when trying to access the Origin ClientPath registry key (closed keys cannot be accessed).");
|
|
}
|
|
catch (IOException ex)
|
|
{
|
|
logger.Warn(ex, "OriginLibrary/LoadInstalledGames: The Origin ClientPath registry key has been marked for deletion so we cannot access the value dueing the OriginLibrary check.");
|
|
}
|
|
catch (UnauthorizedAccessException ex)
|
|
{
|
|
logger.Warn(ex, "OriginLibrary/LoadInstalledGames: The user does not have the necessary registry rights to check whether Origin is installed.");
|
|
}
|
|
}
|
|
else if (gameFilePath.StartsWith("[HKEY_CURRENT_USER"))
|
|
{
|
|
// The filePath contains a registry key lookup that we need to execute and replace
|
|
MatchCollection mc = Regex.Matches(gameFilePath, @"\[HKEY_CURRENT_USER\\(.*)\](.*)");
|
|
string originGameInstallKeyNameAndValue = mc[0].Groups[1].ToString();
|
|
string originGameRestOfFile = mc[0].Groups[2].ToString();
|
|
if (originGameInstallKeyNameAndValue == null)
|
|
{
|
|
// then we have a problem and we need to continue and ignore this game
|
|
logger.Warn($"OriginLibrary/LoadInstalledGames: Origin game with ID {originGame.GameID} has registry but we can't match it! gameFilePath is {gameFilePath}.");
|
|
continue;
|
|
}
|
|
|
|
mc = Regex.Matches(originGameInstallKeyNameAndValue, @"(.*)\\([^\\]*)");
|
|
string originGameInstallKeyName = mc[0].Groups[1].ToString();
|
|
string originGameInstallKeyValue = mc[0].Groups[2].ToString();
|
|
|
|
try
|
|
{
|
|
RegistryKey originGameInstallKey = Registry.LocalMachine.OpenSubKey(originGameInstallKeyName, RegistryKeyPermissionCheck.ReadSubTree);
|
|
if (originGameInstallKey == null)
|
|
{
|
|
// then we have a problem as we cannot find the game exe location!
|
|
logger.Warn($"OriginLibrary/LoadInstalledGames: Origin game with ID {originGame.GameID} has a install reg key we cannot find! originGameInstallKey is {gameFilePath} and originGameInstallKeyValue is {originGameInstallKeyValue}.");
|
|
continue;
|
|
}
|
|
string originGameInstallLocation = originGameInstallKey.GetValue(originGameInstallKeyValue).ToString();
|
|
originGameInstallLocation = Path.Combine(originGameInstallLocation, originGameRestOfFile);
|
|
if (!File.Exists(originGameInstallLocation))
|
|
{
|
|
// then we have a problem as we cannot locate the game exe file to start!
|
|
logger.Warn($"OriginLibrary/LoadInstalledGames: Origin game with ID {originGame.GameID} has gameexe we cannot find! originGameInstallLocation is {originGameInstallLocation}.");
|
|
continue;
|
|
}
|
|
originGame.GameExePath = originGameInstallLocation;
|
|
|
|
}
|
|
catch (SecurityException ex)
|
|
{
|
|
logger.Warn(ex, "OriginLibrary/LoadInstalledGames: The user does not have the permissions required to read the Origin Game location registry key {}.");
|
|
}
|
|
catch (ObjectDisposedException ex)
|
|
{
|
|
logger.Warn(ex, "OriginLibrary/LoadInstalledGames: The Microsoft.Win32.RegistryKey is closed when trying to access the Origin ClientPath registry key (closed keys cannot be accessed).");
|
|
}
|
|
catch (IOException ex)
|
|
{
|
|
logger.Warn(ex, "OriginLibrary/LoadInstalledGames: The Origin ClientPath registry key has been marked for deletion so we cannot access the value dueing the OriginLibrary check.");
|
|
}
|
|
catch (UnauthorizedAccessException ex)
|
|
{
|
|
logger.Warn(ex, "OriginLibrary/LoadInstalledGames: The user does not have the necessary registry rights to check whether Origin is installed.");
|
|
}
|
|
}
|
|
|
|
|
|
if (!File.Exists(originGame.GameExePath))
|
|
{
|
|
logger.Debug($"OriginLibrary/LoadInstalledGames: Origin game with ID {originGame.GameID} found but no game exe found at {originGame.GameExePath}");
|
|
continue;
|
|
}
|
|
|
|
// TODO check for icon! For now we will just use the exe one
|
|
originGame.GameIconPath = originGame.GameExePath;
|
|
|
|
// If we reach here we add the Game to the list of games we have!
|
|
_allOriginGames.Add(new OriginGame(originGame.GameID, originGame.GameName, originGame.GameExePath, originGame.GameIconPath));
|
|
}
|
|
else
|
|
{
|
|
// If we can't find the __Installer\installerdata.xml file then we ignore this game
|
|
continue;
|
|
}
|
|
|
|
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
logger.Error(ex, $"OriginLibrary/LoadInstalledGames: Failed to import installed Origin game {package}.");
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
logger.Warn($"OriginLibrary/LoadInstalledGames: No Origin games installed in the Origin library");
|
|
return false;
|
|
}
|
|
|
|
// up to here
|
|
|
|
|
|
|
|
/* if (gotGameRegistryKey)
|
|
{
|
|
// Now we need to lookup the game install path in registry using the game reg we got above
|
|
// We assume its 64-bit OS too (not 32bit)
|
|
using (RegistryKey OriginGameInstallKey = Registry.LocalMachine.OpenSubKey(gameRegistryKey, RegistryKeyPermissionCheck.ReadSubTree))
|
|
{
|
|
// If the key doesn't exist we skip it as the game isn't installed any longer!
|
|
if (OriginGameInstallKey == null)
|
|
{
|
|
logger.Trace($"OriginLibrary/LoadInstalledGames: Skipping Origin Game {OriginGameAppInfo.GameName} as it isn't installed at the moment (it was uninstalled at some point)");
|
|
continue;
|
|
}
|
|
|
|
// If we get here, then we have a real game.
|
|
foreach (string regKeyName in OriginGameInstallKey.GetValueNames())
|
|
{
|
|
logger.Trace($"OriginLibrary/LoadInstalledGames: OriginGameInstallKey[{regKeyName}] = {OriginGameInstallKey.GetValue(regKeyName)}");
|
|
}
|
|
|
|
// From that we lookup the actual game path
|
|
string gameInstallDir = OriginGameInstallKey.GetValue("InstallDir", "").ToString();
|
|
logger.Trace($"OriginLibrary/LoadInstalledGames: gameInstallDir found = {gameInstallDir}");
|
|
if (!String.IsNullOrWhiteSpace(gameInstallDir))
|
|
{
|
|
OriginGameAppInfo.GameInstallDir = Path.GetFullPath(gameInstallDir).TrimEnd('\\');
|
|
logger.Trace($"OriginLibrary/LoadInstalledGames: OriginGameAppInfo.GameInstallDir = {OriginGameAppInfo.GameInstallDir }");
|
|
OriginGameAppInfo.GameExe = Path.Combine(OriginGameAppInfo.GameInstallDir, gameFileName);
|
|
logger.Trace($"OriginLibrary/LoadInstalledGames: OriginGameAppInfo.GameExe = {OriginGameAppInfo.GameExePath }");
|
|
OriginGameAppInfo.GameID = gameId;
|
|
logger.Trace($"OriginLibrary/LoadInstalledGames: OriginGameAppInfo.GameID = {OriginGameAppInfo.GameID }");
|
|
}
|
|
else
|
|
{
|
|
logger.Warn($"OriginLibrary/LoadInstalledGames: gameInstallDir is null or all whitespace!");
|
|
}
|
|
|
|
// Then we have the gameID, the thumbimage, the icon, the name, the exe path
|
|
// And we add the Game to the list of games we have!
|
|
_allOriginGames.Add(new OriginGame(OriginGameAppInfo.GameID, OriginGameAppInfo.GameName, OriginGameAppInfo.GameExePath, OriginGameAppInfo.GameOriginIconPath));
|
|
logger.Debug($"OriginLibrary/LoadInstalledGames: Adding Origin Game with game id {OriginGameAppInfo.GameID}, name {OriginGameAppInfo.GameName}, game exe {OriginGameAppInfo.GameExePath} and icon path {OriginGameAppInfo.GameOriginIconPath}");
|
|
}
|
|
}
|
|
|
|
}*/
|
|
|
|
logger.Info($"OriginLibrary/LoadInstalledGames: Found {_allOriginGames.Count} installed Origin games");
|
|
|
|
}
|
|
|
|
catch (ArgumentNullException ex)
|
|
{
|
|
logger.Warn(ex, "OriginLibrary/GetAllInstalledGames: An argument supplied to the function is null.");
|
|
}
|
|
catch (NotSupportedException ex)
|
|
{
|
|
logger.Warn(ex, "OriginLibrary/GetAllInstalledGames: The invoked method is not supported or reading, seeking or writing tp a stream that isn't supported.");
|
|
}
|
|
catch (PathTooLongException ex)
|
|
{
|
|
logger.Warn(ex, "OriginLibrary/GetAllInstalledGames: The path is longer than the maximum allowed by the operating system.");
|
|
}
|
|
catch (SecurityException ex)
|
|
{
|
|
logger.Warn(ex, "OriginLibrary/GetAllInstalledGames: The user does not have the permissions required to read the Origin InstallDir registry key.");
|
|
}
|
|
catch (ObjectDisposedException ex)
|
|
{
|
|
logger.Warn(ex, "OriginLibrary/GetAllInstalledGames: The Microsoft.Win32.RegistryKey is closed when trying to access the Origin InstallDir registry key (closed keys cannot be accessed).");
|
|
}
|
|
catch (IOException ex)
|
|
{
|
|
logger.Warn(ex, "OriginLibrary/GetAllInstalledGames: The Origin InstallDir registry key has been marked for deletion so we cannot access the value dueing the OriginLibrary check.");
|
|
}
|
|
catch (UnauthorizedAccessException ex)
|
|
{
|
|
logger.Warn(ex, "OriginLibrary/GetAllInstalledGames: The user does not have the necessary registry rights to check whether Origin is installed.");
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
#endregion
|
|
|
|
}
|
|
|
|
[global::System.Serializable]
|
|
public class OriginLibraryException : GameLibraryException
|
|
{
|
|
public OriginLibraryException() { }
|
|
public OriginLibraryException(string message) : base(message) { }
|
|
public OriginLibraryException(string message, Exception inner) : base(message, inner) { }
|
|
protected OriginLibraryException(
|
|
System.Runtime.Serialization.SerializationInfo info,
|
|
System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
|
|
}
|
|
|
|
}
|