mirror of
https://github.com/terrymacdonald/DisplayMagician.git
synced 2024-08-30 18:32:20 +00:00
[WIP] Partial development of uplay support
Have reverse engineered the uplay launcher a little bit, and managed to extract some of the useful file structures to be able to parse the useful bits of teh uplay game library. Need to properly extract the games info from it though.
This commit is contained in:
parent
dd85aeb0f1
commit
b1e49aad11
@ -295,13 +295,13 @@ namespace HeliosPlus.GameLibraries
|
||||
{
|
||||
|
||||
// Find the SteamExe location, and the SteamPath for later
|
||||
using (var key = Registry.CurrentUser.OpenSubKey(_registrySteamKey, RegistryKeyPermissionCheck.ReadSubTree))
|
||||
/*using (var key = Registry.CurrentUser.OpenSubKey(_registrySteamKey, RegistryKeyPermissionCheck.ReadSubTree))
|
||||
{
|
||||
_steamExe = (string)key?.GetValue(@"SteamExe", string.Empty) ?? string.Empty;
|
||||
_steamExe = _steamExe.Replace('/', '\\');
|
||||
_steamPath = (string)key?.GetValue(@"SteamPath", string.Empty) ?? string.Empty;
|
||||
_steamPath = _steamPath.Replace('/', '\\');
|
||||
}
|
||||
}*/
|
||||
|
||||
if (_steamExe == string.Empty || !File.Exists(_steamExe))
|
||||
{
|
||||
@ -312,8 +312,8 @@ namespace HeliosPlus.GameLibraries
|
||||
//Icon _steamIcon = Icon.ExtractAssociatedIcon(_steamExe);
|
||||
//IconExtractor steamIconExtractor = new IconExtractor(_steamExe);
|
||||
//Icon _steamIcon = steamIconExtractor.GetIcon(0);
|
||||
MultiIcon _steamIcon = new MultiIcon();
|
||||
_steamIcon.Load(_steamExe);
|
||||
//MultiIcon _steamIcon = new MultiIcon();
|
||||
//_steamIcon.Load(_steamExe);
|
||||
|
||||
List<uint> steamAppIdsInstalled = new List<uint>();
|
||||
// Now look for what games app id's are actually installed on this computer
|
||||
|
@ -0,0 +1,101 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace HeliosPlus.GameLibraries.UplayConfigurationParser
|
||||
{
|
||||
class UplayConfigurationParser
|
||||
{
|
||||
|
||||
/*def _convert_data(self, data):
|
||||
# calculate object size (konrad's formula)
|
||||
if data > 256 * 256:
|
||||
data = data - (128 * 256 * math.ceil(data / (256 * 256)))
|
||||
data = data - (128 * math.ceil(data / 256))
|
||||
else:
|
||||
if data > 256:
|
||||
data = data - (128 * math.ceil(data / 256))
|
||||
return data*/
|
||||
|
||||
internal static decimal ConvertData (decimal data)
|
||||
{
|
||||
if (data > 65536)
|
||||
{
|
||||
data = data - (128 * 256 * Math.Ceiling(data / 65536));
|
||||
}
|
||||
else if (data > 256)
|
||||
{
|
||||
data = data - (128 * Math.Ceiling(data / 256));
|
||||
}
|
||||
|
||||
return data;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*def _parse_configuration_header(self, header, second_eight= False):
|
||||
try:
|
||||
offset = 1
|
||||
multiplier = 1
|
||||
record_size = 0
|
||||
tmp_size = 0
|
||||
|
||||
if second_eight:
|
||||
while header[offset] != 0x08 or(header[offset] == 0x08 and header[offset + 1] == 0x08) :
|
||||
record_size += header[offset] * multiplier
|
||||
multiplier *= 256
|
||||
offset += 1
|
||||
tmp_size += 1
|
||||
else:
|
||||
while header[offset] != 0x08 or record_size == 0:
|
||||
record_size += header[offset] * multiplier
|
||||
multiplier *= 256
|
||||
offset += 1
|
||||
tmp_size += 1
|
||||
|
||||
record_size = self._convert_data(record_size)
|
||||
|
||||
offset += 1 # skip 0x08
|
||||
|
||||
# look for launch_id
|
||||
multiplier = 1
|
||||
launch_id = 0
|
||||
|
||||
while header[offset] != 0x10 or header[offset + 1] == 0x10:
|
||||
launch_id += header[offset] * multiplier
|
||||
multiplier *= 256
|
||||
offset += 1
|
||||
|
||||
launch_id = self._convert_data(launch_id)
|
||||
|
||||
offset += 1 # skip 0x10
|
||||
|
||||
multiplier = 1
|
||||
launch_id_2 = 0
|
||||
while header[offset] != 0x1A or(header[offset] == 0x1A and header[offset + 1] == 0x1A) :
|
||||
launch_id_2 += header[offset] * multiplier
|
||||
multiplier *= 256
|
||||
offset += 1
|
||||
|
||||
launch_id_2 = self._convert_data(launch_id_2)
|
||||
|
||||
#if object size is smaller than 128b, there might be a chance that secondary size will not occupy 2b
|
||||
if record_size - offset < 128 <= record_size:
|
||||
tmp_size -= 1
|
||||
record_size += 1
|
||||
|
||||
# we end up in the middle of header, return values normalized
|
||||
# to end of record as well real yaml size and game launch_id
|
||||
return record_size - offset, launch_id, launch_id_2, offset + tmp_size + 1
|
||||
except:
|
||||
# something went horribly wrong, do not crash it,
|
||||
# just return 0s, this way it will be handled later in the code
|
||||
# 10 is to step a little in configuration file in order to find next game
|
||||
return 0, 0, 0, 10*/
|
||||
|
||||
//internal static decimal ParseConfigurationHeader(decimal data);
|
||||
}
|
||||
}
|
@ -21,36 +21,39 @@ using System.Collections.ObjectModel;
|
||||
using ValveKeyValue;
|
||||
using System.Security.Cryptography;
|
||||
using System.ServiceModel.Configuration;
|
||||
using HeliosPlus.GameLibraries.SteamAppInfoParser;
|
||||
//using HeliosPlus.GameLibraries.UplayAppInfoParser;
|
||||
using TsudaKageyu;
|
||||
using System.Drawing.IconLib;
|
||||
using System.Drawing.IconLib.Exceptions;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace HeliosPlus.GameLibraries
|
||||
{
|
||||
public class UplayGame
|
||||
public class UplayGame : Game
|
||||
{
|
||||
private static string _uplayExe;
|
||||
private static string _uplayPath;
|
||||
/*private static string UplayLibrary.UplayExe;
|
||||
private static string UplayLibrary.UplayPath;
|
||||
private static string _uplayConfigVdfFile;
|
||||
private static string _registryUplayKey = @"SOFTWARE\\Valve\\Uplay";
|
||||
private static string _registryAppsKey = $@"{_registryUplayKey}\\Apps";
|
||||
private static string _registryAppsKey = $@"{_registryUplayKey}\\Apps";*/
|
||||
private string _gameRegistryKey;
|
||||
private uint _uplayGameId;
|
||||
private string _uplayGameName;
|
||||
private string _uplayGamePath;
|
||||
private string _uplayGameExePath;
|
||||
private string _uplayGameDir;
|
||||
private string _uplayGameExe;
|
||||
private string _uplayGameProcessName;
|
||||
private string _uplayGameIconPath;
|
||||
private static List<UplayGame> _allUplayGames;
|
||||
private static List<UplayGame> _allInstalledUplayGames = null;
|
||||
|
||||
private struct UplayAppInfo
|
||||
/*private struct UplayAppInfo
|
||||
{
|
||||
public uint GameID;
|
||||
public uint GameID;
|
||||
public string GameName;
|
||||
public List<string> GameExes;
|
||||
public string GameInstallDir;
|
||||
public string GameUplayIconPath;
|
||||
}
|
||||
}*/
|
||||
|
||||
static UplayGame()
|
||||
{
|
||||
@ -59,38 +62,60 @@ namespace HeliosPlus.GameLibraries
|
||||
}
|
||||
|
||||
|
||||
public UplayGame(uint uplayGameId, string uplayGameName, string uplayGamePath, string uplayGameExe, string uplayGameIconPath)
|
||||
public UplayGame(uint uplayGameId, string uplayGameName, string uplayGameExePath, string uplayGameIconPath)
|
||||
{
|
||||
|
||||
_gameRegistryKey = $@"{_registryAppsKey}\\{uplayGameId}";
|
||||
_gameRegistryKey = $@"{UplayLibrary.registryUplayInstallsKey}\\{uplayGameId}";
|
||||
_uplayGameId = uplayGameId;
|
||||
_uplayGameName = uplayGameName;
|
||||
_uplayGamePath = uplayGamePath;
|
||||
_uplayGameExe = uplayGameExe;
|
||||
_uplayGameExePath = uplayGameExePath;
|
||||
_uplayGameDir = Path.GetDirectoryName(uplayGameExePath);
|
||||
_uplayGameExe = Path.GetFileName(_uplayGameExePath);
|
||||
_uplayGameProcessName = Path.GetFileNameWithoutExtension(_uplayGameExePath);
|
||||
_uplayGameIconPath = uplayGameIconPath;
|
||||
|
||||
// Find the UplayExe location, and the UplayPath for later
|
||||
using (var key = Registry.CurrentUser.OpenSubKey(_registryUplayKey, RegistryKeyPermissionCheck.ReadSubTree))
|
||||
{
|
||||
_uplayExe = (string)key?.GetValue(@"UplayExe", string.Empty) ?? string.Empty;
|
||||
_uplayExe = _uplayExe.Replace('/', '\\');
|
||||
_uplayPath = (string)key?.GetValue(@"UplayPath", string.Empty) ?? string.Empty;
|
||||
_uplayPath = _uplayPath.Replace('/', '\\');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public uint GameId { get => _uplayGameId; }
|
||||
public override uint Id
|
||||
{
|
||||
get => _uplayGameId;
|
||||
set => _uplayGameId = value;
|
||||
}
|
||||
|
||||
public static SupportedGameLibrary GameLibrary { get => SupportedGameLibrary.Uplay; }
|
||||
public override string Name
|
||||
{
|
||||
get => _uplayGameName;
|
||||
set => _uplayGameName = value;
|
||||
}
|
||||
|
||||
public string GameIconPath { get => _uplayGameIconPath; }
|
||||
public override SupportedGameLibrary GameLibrary
|
||||
{
|
||||
get => SupportedGameLibrary.Uplay;
|
||||
}
|
||||
|
||||
public bool IsRunning
|
||||
public override string IconPath
|
||||
{
|
||||
get => _uplayGameIconPath;
|
||||
set => _uplayGameIconPath = value;
|
||||
}
|
||||
|
||||
public override string ExePath
|
||||
{
|
||||
get => _uplayGameExePath;
|
||||
set => _uplayGameExePath = value;
|
||||
}
|
||||
|
||||
public override string Directory
|
||||
{
|
||||
get => _uplayGameExePath;
|
||||
set => _uplayGameExePath = value;
|
||||
}
|
||||
|
||||
public override bool IsRunning
|
||||
{
|
||||
get
|
||||
{
|
||||
try
|
||||
/*try
|
||||
{
|
||||
using (
|
||||
var key = Registry.CurrentUser.OpenSubKey(_gameRegistryKey, RegistryKeyPermissionCheck.ReadSubTree))
|
||||
@ -104,7 +129,7 @@ namespace HeliosPlus.GameLibraries
|
||||
}
|
||||
catch (SecurityException ex)
|
||||
{
|
||||
Console.WriteLine($"SteamGame/IsUpdating securityexception: {ex.Message}: {ex.StackTrace} - {ex.InnerException}");
|
||||
Console.WriteLine($"UplayGame/IsRunning securityexception: {ex.Message}: {ex.StackTrace} - {ex.InnerException}");
|
||||
if (ex.Source != null)
|
||||
Console.WriteLine("SecurityException source: {0} - Message: {1}", ex.Source, ex.Message);
|
||||
throw;
|
||||
@ -113,15 +138,20 @@ namespace HeliosPlus.GameLibraries
|
||||
{
|
||||
// Extract some information from this exception, and then
|
||||
// throw it to the parent method.
|
||||
Console.WriteLine($"SteamGame/IsUpdating ioexception: {ex.Message}: {ex.StackTrace} - {ex.InnerException}");
|
||||
Console.WriteLine($"UplayGame/IsRunning ioexception: {ex.Message}: {ex.StackTrace} - {ex.InnerException}");
|
||||
if (ex.Source != null)
|
||||
Console.WriteLine("IOException source: {0} - Message: {1}", ex.Source, ex.Message);
|
||||
throw;
|
||||
}
|
||||
}*/
|
||||
|
||||
bool isRunning = Process.GetProcessesByName(_uplayGameProcessName)
|
||||
.FirstOrDefault(p => p.MainModule.FileName
|
||||
.StartsWith(ExePath, StringComparison.OrdinalIgnoreCase)) != default(Process);
|
||||
return isRunning;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsUpdating
|
||||
public override bool IsUpdating
|
||||
{
|
||||
get
|
||||
{
|
||||
@ -139,7 +169,7 @@ namespace HeliosPlus.GameLibraries
|
||||
}
|
||||
catch (SecurityException ex)
|
||||
{
|
||||
Console.WriteLine($"SteamGame/IsUpdating securityexception: {ex.Message}: {ex.StackTrace} - {ex.InnerException}");
|
||||
Console.WriteLine($"UplayGame/IsUpdating securityexception: {ex.Message}: {ex.StackTrace} - {ex.InnerException}");
|
||||
if (ex.Source != null)
|
||||
Console.WriteLine("SecurityException source: {0} - Message: {1}", ex.Source, ex.Message);
|
||||
throw;
|
||||
@ -148,7 +178,7 @@ namespace HeliosPlus.GameLibraries
|
||||
{
|
||||
// Extract some information from this exception, and then
|
||||
// throw it to the parent method.
|
||||
Console.WriteLine($"SteamGame/IsUpdating ioexception: {ex.Message}: {ex.StackTrace} - {ex.InnerException}");
|
||||
Console.WriteLine($"UplayGame/IsUpdating ioexception: {ex.Message}: {ex.StackTrace} - {ex.InnerException}");
|
||||
if (ex.Source != null)
|
||||
Console.WriteLine("IOException source: {0} - Message: {1}", ex.Source, ex.Message);
|
||||
throw;
|
||||
@ -156,324 +186,17 @@ namespace HeliosPlus.GameLibraries
|
||||
}
|
||||
}
|
||||
|
||||
public string GameName { get => _uplayGameName; }
|
||||
|
||||
public static string UplayExe { get => _uplayExe; }
|
||||
|
||||
public string GamePath { get => _uplayGamePath; }
|
||||
|
||||
public static List<UplayGame> AllGames { get => _allUplayGames; }
|
||||
|
||||
public static bool UplayInstalled
|
||||
public bool CopyTo(UplayGame uplayGame)
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(UplayGame._uplayExe) && File.Exists(UplayGame._uplayExe))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (!(uplayGame is UplayGame))
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static List<UplayGame> GetAllInstalledGames()
|
||||
{
|
||||
List<UplayGame> uplayGameList = new List<UplayGame>();
|
||||
_allUplayGames = uplayGameList;
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
// Find the UplayExe location, and the UplayPath for later
|
||||
using (var key = Registry.CurrentUser.OpenSubKey(_registryUplayKey, RegistryKeyPermissionCheck.ReadSubTree))
|
||||
{
|
||||
_uplayExe = (string)key?.GetValue(@"UplayExe", string.Empty) ?? string.Empty;
|
||||
_uplayExe = _uplayExe.Replace('/', '\\');
|
||||
_uplayPath = (string)key?.GetValue(@"UplayPath", string.Empty) ?? string.Empty;
|
||||
_uplayPath = _uplayPath.Replace('/', '\\');
|
||||
}
|
||||
|
||||
if (_uplayExe == string.Empty || !File.Exists(_uplayExe))
|
||||
{
|
||||
// Uplay isn't installed, so we return an empty list.
|
||||
return uplayGameList;
|
||||
}
|
||||
|
||||
//Icon _uplayIcon = Icon.ExtractAssociatedIcon(_uplayExe);
|
||||
//IconExtractor uplayIconExtractor = new IconExtractor(_uplayExe);
|
||||
//Icon _uplayIcon = uplayIconExtractor.GetIcon(0);
|
||||
MultiIcon _uplayIcon = new MultiIcon();
|
||||
_uplayIcon.Load(_uplayExe);
|
||||
|
||||
List<uint> uplayAppIdsInstalled = new List<uint>();
|
||||
// Now look for what games app id's are actually installed on this computer
|
||||
using (RegistryKey uplayAppsKey = Registry.CurrentUser.OpenSubKey(_registryAppsKey, RegistryKeyPermissionCheck.ReadSubTree))
|
||||
{
|
||||
if (uplayAppsKey != null)
|
||||
{
|
||||
// Loop through the subKeys as they are the Uplay Game IDs
|
||||
foreach (string uplayGameKeyName in uplayAppsKey.GetSubKeyNames())
|
||||
{
|
||||
uint uplayAppId = 0;
|
||||
if (uint.TryParse(uplayGameKeyName, out uplayAppId))
|
||||
{
|
||||
string uplayGameKeyFullName = $"{_registryAppsKey}\\{uplayGameKeyName}";
|
||||
using (RegistryKey uplayGameKey = Registry.CurrentUser.OpenSubKey(uplayGameKeyFullName, RegistryKeyPermissionCheck.ReadSubTree))
|
||||
{
|
||||
// If the Installed Value is set to 1, then the game is installed
|
||||
// We want to keep track of that for later
|
||||
if ((int)uplayGameKey.GetValue(@"Installed", 0) == 1)
|
||||
{
|
||||
// Add this Uplay App ID to the list we're keeping for later
|
||||
uplayAppIdsInstalled.Add(uplayAppId);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Now we parse the uplay appinfo.vdf to get access to things like:
|
||||
// - The game name
|
||||
// - THe game installation dir
|
||||
// - Sometimes the game icon
|
||||
// - Sometimes the game executable name (from which we can get the icon)
|
||||
Dictionary<uint, UplayAppInfo> uplayAppInfo = new Dictionary<uint, UplayAppInfo>();
|
||||
|
||||
string appInfoVdfFile = Path.Combine(_uplayPath, "appcache", "appinfo.vdf");
|
||||
var newAppInfo = new AppInfo();
|
||||
newAppInfo.Read(appInfoVdfFile);
|
||||
|
||||
Console.WriteLine($"{newAppInfo.Apps.Count} apps");
|
||||
|
||||
// Chec through all the apps we've extracted
|
||||
foreach (var app in newAppInfo.Apps)
|
||||
{
|
||||
// We only care about the appIDs we have listed as actual games
|
||||
// (The AppIds include all other DLC and Uplay specific stuff too)
|
||||
if (uplayAppIdsInstalled.Contains(app.AppID))
|
||||
{
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
UplayAppInfo uplayGameAppInfo = new UplayAppInfo();
|
||||
uplayGameAppInfo.GameID = app.AppID;
|
||||
uplayGameAppInfo.GameExes = new List<string>();
|
||||
|
||||
foreach (KVObject data in app.Data)
|
||||
{
|
||||
//Console.WriteLine($"App: {app.AppID} - Data.Name: {data.Name}");
|
||||
|
||||
if (data.Name == "common")
|
||||
{
|
||||
foreach (KVObject common in data.Children)
|
||||
{
|
||||
|
||||
//Console.WriteLine($"App: {app.AppID} - Common {common.Name}: {common.Value}");
|
||||
|
||||
if (common.Name == "name")
|
||||
{
|
||||
Console.WriteLine($"App: {app.AppID} - Common {common.Name}: {common.Value}");
|
||||
uplayGameAppInfo.GameName = common.Value.ToString();
|
||||
}
|
||||
else if (common.Name == "clienticon")
|
||||
{
|
||||
Console.WriteLine($"App: {app.AppID} - Common {common.Name}: {common.Value}");
|
||||
uplayGameAppInfo.GameUplayIconPath = Path.Combine(_uplayPath, @"uplay", @"games", String.Concat(common.Value, @".ico"));
|
||||
}
|
||||
else if (common.Name == "type")
|
||||
{
|
||||
Console.WriteLine($"App: {app.AppID} - Common {common.Name}: {common.Value}");
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (data.Name == "config")
|
||||
{
|
||||
foreach (KVObject config in data.Children)
|
||||
{
|
||||
//Console.WriteLine($"App: {app.AppID} - Config {config.Name}: {config.Value}");
|
||||
|
||||
if (config.Name == "installdir")
|
||||
{
|
||||
Console.WriteLine($"App: {app.AppID} - Config {config.Name}: {config.Value}");
|
||||
uplayGameAppInfo.GameInstallDir = config.Value.ToString();
|
||||
}
|
||||
else if (config.Name == "launch")
|
||||
{
|
||||
foreach (KVObject launch in config.Children)
|
||||
{
|
||||
foreach (KVObject launch_num in launch.Children)
|
||||
{
|
||||
if (launch_num.Name == "executable")
|
||||
{
|
||||
Console.WriteLine($"App: {app.AppID} - Config - Launch {launch.Name} - {launch_num.Name}: {launch_num.Value}");
|
||||
uplayGameAppInfo.GameExes.Add(launch_num.Value.ToString());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
uplayAppInfo.Add(app.AppID, uplayGameAppInfo);
|
||||
}
|
||||
catch (ArgumentException ex)
|
||||
{
|
||||
Console.WriteLine($"UplayGame/GetAllInstalledGames argumentexception: {ex.Message}: {ex.StackTrace} - {ex.InnerException}");
|
||||
//we just want to ignore it if we try to add it twice....
|
||||
}
|
||||
|
||||
Console.WriteLine($"App: {app.AppID} - Token: {app.Token}");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Now we access the config.vdf that lives in the Uplay Config file, as that lists all
|
||||
// the UplayLibraries. We need to find out where they areso we can interrogate them
|
||||
_uplayConfigVdfFile = Path.Combine(_uplayPath, "config", "config.vdf");
|
||||
string uplayConfigVdfText = File.ReadAllText(_uplayConfigVdfFile, Encoding.UTF8);
|
||||
|
||||
List<string> uplayLibrariesPaths = new List<string>();
|
||||
// Now we have to parse the config.vdf looking for the location of the UplayLibraries
|
||||
// We look for lines similar to this: "BaseInstallFolder_1" "E:\\UplayLibrary"
|
||||
// There may be multiple so we need to check the whole file
|
||||
Regex uplayLibrariesRegex = new Regex(@"""BaseInstallFolder_\d+""\s+""(.*)""", RegexOptions.IgnoreCase);
|
||||
// Try to match all lines against the Regex.
|
||||
Match uplayLibrariesMatches = uplayLibrariesRegex.Match(uplayConfigVdfText);
|
||||
// If at least one of them matched!
|
||||
if (uplayLibrariesMatches.Success)
|
||||
{
|
||||
// Loop throug the results and add to an array
|
||||
for (int i = 1; i < uplayLibrariesMatches.Groups.Count; i++)
|
||||
{
|
||||
string uplayLibraryPath = Regex.Unescape(uplayLibrariesMatches.Groups[i].Value);
|
||||
Console.WriteLine($"Found uplay library: {uplayLibraryPath}");
|
||||
uplayLibrariesPaths.Add(uplayLibraryPath);
|
||||
}
|
||||
}
|
||||
|
||||
// Now we go off and find the details for the games in each Uplay Library
|
||||
foreach (string uplayLibraryPath in uplayLibrariesPaths)
|
||||
{
|
||||
// Work out the path to the appmanifests for this uplayLibrary
|
||||
string uplayLibraryAppManifestPath = Path.Combine(uplayLibraryPath, @"uplayapps");
|
||||
// Get the names of the App Manifests for the games installed in this UplayLibrary
|
||||
string[] uplayLibraryAppManifestFilenames = Directory.GetFiles(uplayLibraryAppManifestPath, "appmanifest_*.acf");
|
||||
// Go through each app and extract it's details
|
||||
foreach (string uplayLibraryAppManifestFilename in uplayLibraryAppManifestFilenames)
|
||||
{
|
||||
// Read in the contents of the file
|
||||
string uplayLibraryAppManifestText = File.ReadAllText(uplayLibraryAppManifestFilename);
|
||||
// Grab the appid from the file
|
||||
Regex appidRegex = new Regex(@"""appid""\s+""(\d+)""", RegexOptions.IgnoreCase);
|
||||
Match appidMatches = appidRegex.Match(uplayLibraryAppManifestText);
|
||||
if (appidMatches.Success)
|
||||
{
|
||||
|
||||
uint uplayGameId = 0;
|
||||
if (uint.TryParse(appidMatches.Groups[1].Value, out uplayGameId))
|
||||
{
|
||||
// Check if this game is one that was installed
|
||||
if (uplayAppInfo.ContainsKey(uplayGameId))
|
||||
{
|
||||
// This game is an installed game! so we start to populate it with data!
|
||||
string uplayGameExe = "";
|
||||
|
||||
string uplayGameName = uplayAppInfo[uplayGameId].GameName;
|
||||
|
||||
// Construct the full path to the game dir from the appInfo and libraryAppManifest data
|
||||
string uplayGameInstallDir = Path.Combine(uplayLibraryPath, @"uplayapps", @"common", uplayAppInfo[uplayGameId].GameInstallDir);
|
||||
|
||||
// Next, we need to get the Icons we want to use, and make sure it's the latest one.
|
||||
string uplayGameIconPath = "";
|
||||
// First of all, we attempt to use the Icon that Uplay has cached, if it's available, as that will be updated to the latest
|
||||
if (File.Exists(uplayAppInfo[uplayGameId].GameUplayIconPath))
|
||||
{
|
||||
uplayGameIconPath = uplayAppInfo[uplayGameId].GameUplayIconPath;
|
||||
}
|
||||
// If there isn't an icon for us to use, then we need to extract one from the Game Executables
|
||||
else if (uplayAppInfo[uplayGameId].GameExes.Count > 0)
|
||||
{
|
||||
foreach (string gameExe in uplayAppInfo[uplayGameId].GameExes)
|
||||
{
|
||||
uplayGameExe = Path.Combine(uplayGameInstallDir, gameExe);
|
||||
// If the game executable exists, then we can proceed
|
||||
if (File.Exists(uplayGameExe))
|
||||
{
|
||||
// Now we need to get the Icon from the app if possible if it's not in the games folder
|
||||
uplayGameIconPath = uplayGameExe;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
// The absolute worst case means we don't have an icon to use. SO we use the Uplay one.
|
||||
else
|
||||
{
|
||||
// And we have to make do with a Uplay Icon
|
||||
uplayGameIconPath = _uplayPath;
|
||||
|
||||
}
|
||||
|
||||
// And finally we try to populate the 'where', to see what gets run
|
||||
// And so we can extract the process name
|
||||
if (uplayAppInfo[uplayGameId].GameExes.Count > 0)
|
||||
{
|
||||
foreach (string gameExe in uplayAppInfo[uplayGameId].GameExes)
|
||||
{
|
||||
uplayGameExe = Path.Combine(uplayGameInstallDir, gameExe);
|
||||
// If the game executable exists, then we can proceed
|
||||
if (File.Exists(uplayGameExe))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// And we add the Game to the list of games we have!
|
||||
uplayGameList.Add(new UplayGame(uplayGameId, uplayGameName, uplayGameInstallDir, uplayGameExe, uplayGameIconPath));
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (SecurityException e)
|
||||
{
|
||||
if (e.Source != null)
|
||||
Console.WriteLine("SecurityException source: {0} - Message: {1}", e.Source, e.Message);
|
||||
throw;
|
||||
}
|
||||
catch (UnauthorizedAccessException e)
|
||||
{
|
||||
if (e.Source != null)
|
||||
Console.WriteLine("UnauthorizedAccessException source: {0} - Message: {1}", e.Source, e.Message);
|
||||
throw;
|
||||
}
|
||||
catch (ObjectDisposedException e)
|
||||
{
|
||||
if (e.Source != null)
|
||||
Console.WriteLine("ObjectDisposedException source: {0} - Message: {1}", e.Source, e.Message);
|
||||
throw;
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
// Extract some information from this exception, and then
|
||||
// throw it to the parent method.
|
||||
if (e.Source != null)
|
||||
Console.WriteLine("IOException source: {0} - Message: {1}", e.Source, e.Message);
|
||||
throw;
|
||||
}
|
||||
|
||||
return uplayGameList;
|
||||
// Copy all the game data over to the other game
|
||||
uplayGame.IconPath = IconPath;
|
||||
uplayGame.Id = Id;
|
||||
uplayGame.Name = Name;
|
||||
uplayGame.ExePath = ExePath;
|
||||
return true;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
@ -495,12 +218,7 @@ namespace HeliosPlus.GameLibraries
|
||||
return name + " " + Language.Updating;
|
||||
}
|
||||
|
||||
/*if (IsInstalled)
|
||||
{
|
||||
return name + " " + Language.Installed;
|
||||
}*/
|
||||
|
||||
return name + " " + Language.Not_Installed;
|
||||
return name;
|
||||
}
|
||||
|
||||
}
|
||||
|
436
HeliosPlus/GameLibraries/UplayLibrary.cs
Normal file
436
HeliosPlus/GameLibraries/UplayLibrary.cs
Normal file
@ -0,0 +1,436 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using ValveKeyValue;
|
||||
//using HeliosPlus.GameLibraries.UplayAppInfoParser;
|
||||
using Microsoft.Win32;
|
||||
using System.IO;
|
||||
using System.Drawing.IconLib;
|
||||
using System.Security;
|
||||
using System.Diagnostics;
|
||||
using EDIDParser;
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace HeliosPlus.GameLibraries
|
||||
{
|
||||
public static class UplayLibrary
|
||||
{
|
||||
#region Class Variables
|
||||
// Common items to the class
|
||||
private static List<UplayGame> _allUplayGames = new List<UplayGame>();
|
||||
private static string uplayAppIdRegex = @"/^[0-9A-F]{1,10}$";
|
||||
private static string _uplayExe;
|
||||
private static string _uplayPath;
|
||||
private static string _uplayConfigVdfFile;
|
||||
internal static string registryUplayLauncherKey = @"SOFTWARE\WOW6432Node\Ubisoft\Launcher";
|
||||
internal static string registryUplayInstallsKey = @"SOFTWARE\WOW6432Node\Ubisoft\Launcher\Installs";
|
||||
internal static string registryUplayOpenCmdKey = @"SOFTWARE\Classes\uplay\Shell\Open\Command";
|
||||
|
||||
// Other constants that are useful
|
||||
#endregion
|
||||
|
||||
private struct UplayAppInfo
|
||||
{
|
||||
public uint GameID;
|
||||
public string GameName;
|
||||
public List<string> GameExes;
|
||||
public string GameInstallDir;
|
||||
public string GameUplayIconPath;
|
||||
}
|
||||
|
||||
#region Class Constructors
|
||||
static UplayLibrary()
|
||||
{
|
||||
// Find the UplayExe location, and the UplayPath for later
|
||||
RegistryKey uplayInstallKey = Registry.LocalMachine.OpenSubKey(registryUplayLauncherKey, RegistryKeyPermissionCheck.ReadSubTree);
|
||||
_uplayPath = uplayInstallKey.GetValue("InstallDir", "C:\\Program Files (x86)\\Ubisoft\\Ubisoft Game Launcher\\").ToString();
|
||||
_uplayExe = $"{_uplayPath}upc.exe";
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Class Properties
|
||||
public static List<UplayGame> AllInstalledGames
|
||||
{
|
||||
get
|
||||
{
|
||||
// Load the Uplay Games from Uplay Client if needed
|
||||
if (_allUplayGames == null)
|
||||
LoadInstalledGames();
|
||||
return _allUplayGames;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static int InstalledUplayGameCount
|
||||
{
|
||||
get
|
||||
{
|
||||
return _allUplayGames.Count;
|
||||
}
|
||||
}
|
||||
|
||||
public static string UplayExe
|
||||
{
|
||||
get
|
||||
{
|
||||
return _uplayExe;
|
||||
}
|
||||
}
|
||||
|
||||
public static string UplayPath
|
||||
{
|
||||
get
|
||||
{
|
||||
return _uplayPath;
|
||||
}
|
||||
}
|
||||
|
||||
public static bool IsUplayInstalled
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(UplayExe) && File.Exists(UplayExe))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
#region Class Methods
|
||||
public static bool AddUplayGame(UplayGame uplayGame)
|
||||
{
|
||||
if (!(uplayGame is UplayGame))
|
||||
return false;
|
||||
|
||||
// Doublecheck if it already exists
|
||||
// Because then we just update the one that already exists
|
||||
if (ContainsUplayGame(uplayGame))
|
||||
{
|
||||
// We update the existing Shortcut with the data over
|
||||
UplayGame uplayGameToUpdate = GetUplayGame(uplayGame.Id.ToString());
|
||||
uplayGame.CopyTo(uplayGameToUpdate);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Add the uplayGame to the list of uplayGames
|
||||
_allUplayGames.Add(uplayGame);
|
||||
}
|
||||
|
||||
//Doublecheck it's been added
|
||||
if (ContainsUplayGame(uplayGame))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
public static bool RemoveUplayGame(UplayGame uplayGame)
|
||||
{
|
||||
if (!(uplayGame is UplayGame))
|
||||
return false;
|
||||
|
||||
// Remove the uplayGame from the list.
|
||||
int numRemoved = _allUplayGames.RemoveAll(item => item.Id.Equals(uplayGame.Id));
|
||||
|
||||
if (numRemoved == 1)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if (numRemoved == 0)
|
||||
return false;
|
||||
else
|
||||
throw new UplayLibraryException();
|
||||
}
|
||||
|
||||
|
||||
public static bool RemoveUplayGame(string uplayGameNameOrUuid)
|
||||
{
|
||||
if (String.IsNullOrWhiteSpace(uplayGameNameOrUuid))
|
||||
return false;
|
||||
|
||||
int numRemoved;
|
||||
Match match = Regex.Match(uplayGameNameOrUuid, uplayAppIdRegex, RegexOptions.IgnoreCase);
|
||||
if (match.Success)
|
||||
numRemoved = _allUplayGames.RemoveAll(item => uplayGameNameOrUuid.Equals(Convert.ToUInt32(item.Id)));
|
||||
else
|
||||
numRemoved = _allUplayGames.RemoveAll(item => uplayGameNameOrUuid.Equals(item.Name));
|
||||
|
||||
if (numRemoved == 1)
|
||||
return true;
|
||||
else if (numRemoved == 0)
|
||||
return false;
|
||||
else
|
||||
throw new UplayLibraryException();
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static bool ContainsUplayGame(UplayGame uplayGame)
|
||||
{
|
||||
if (!(uplayGame is UplayGame))
|
||||
return false;
|
||||
|
||||
foreach (UplayGame testUplayGame in _allUplayGames)
|
||||
{
|
||||
if (testUplayGame.Id.Equals(uplayGame.Id))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool ContainsUplayGame(string uplayGameNameOrUuid)
|
||||
{
|
||||
if (String.IsNullOrWhiteSpace(uplayGameNameOrUuid))
|
||||
return false;
|
||||
|
||||
|
||||
Match match = Regex.Match(uplayGameNameOrUuid, uplayAppIdRegex, RegexOptions.IgnoreCase);
|
||||
if (match.Success)
|
||||
{
|
||||
foreach (UplayGame testUplayGame in _allUplayGames)
|
||||
{
|
||||
if (uplayGameNameOrUuid.Equals(Convert.ToUInt32(testUplayGame.Id)))
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (UplayGame testUplayGame in _allUplayGames)
|
||||
{
|
||||
if (uplayGameNameOrUuid.Equals(testUplayGame.Name))
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
public static bool ContainsUplayGame(uint uplayGameId)
|
||||
{
|
||||
foreach (UplayGame testUplayGame in _allUplayGames)
|
||||
{
|
||||
if (uplayGameId == testUplayGame.Id)
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static UplayGame GetUplayGame(string uplayGameNameOrUuid)
|
||||
{
|
||||
if (String.IsNullOrWhiteSpace(uplayGameNameOrUuid))
|
||||
return null;
|
||||
|
||||
Match match = Regex.Match(uplayGameNameOrUuid, uplayAppIdRegex, RegexOptions.IgnoreCase);
|
||||
if (match.Success)
|
||||
{
|
||||
foreach (UplayGame testUplayGame in _allUplayGames)
|
||||
{
|
||||
if (uplayGameNameOrUuid.Equals(Convert.ToUInt32(testUplayGame.Id)))
|
||||
return testUplayGame;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (UplayGame testUplayGame in _allUplayGames)
|
||||
{
|
||||
if (uplayGameNameOrUuid.Equals(testUplayGame.Name))
|
||||
return testUplayGame;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
public static UplayGame GetUplayGame(uint uplayGameId)
|
||||
{
|
||||
foreach (UplayGame testUplayGame in _allUplayGames)
|
||||
{
|
||||
if (uplayGameId == testUplayGame.Id)
|
||||
return testUplayGame;
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
public static bool LoadInstalledGames()
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
if (_uplayExe == string.Empty || !File.Exists(_uplayExe))
|
||||
{
|
||||
// Uplay isn't installed, so we return an empty list.
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// Look in HKEY_LOCAL_MACHINE\\SOFTWARE\\WOW6432Node\\Ubisoft\\Launcher and check the InstallDir key
|
||||
// That returns the location of the install dir : E:\Program Files (x86)\Ubisoft\Ubisoft Game Launcher\
|
||||
|
||||
//RegistryKey uplayInstallKey = Registry.CurrentUser.OpenSubKey(registryUplayInstallsKey, RegistryKeyPermissionCheck.ReadSubTree);
|
||||
//string uplayInstallDir = uplayInstallKey.GetValue("InstallDir", "C:\\Program Files (x86)\\Ubisoft\\Ubisoft Game Launcher\\").ToString();
|
||||
|
||||
// Access {installdir}\\cache\\configuration\\configurations file
|
||||
string mypath = _uplayPath + @"cache\\configuration\\configurations";
|
||||
string uplayConfigFileString = File.ReadAllText(mypath);
|
||||
uplayConfigFileString = uplayConfigFileString.Remove(0, 12);
|
||||
// Split the file into records at the SOH unicode character
|
||||
List<string> uplayConfigFile = uplayConfigFileString.Split((Char)1).ToList();
|
||||
|
||||
// Go through every record and attempt to parse it
|
||||
foreach (string uplayEntry in uplayConfigFile) {
|
||||
// Skip any Uplay entry records that don't start with 'version:'
|
||||
if (!uplayEntry.StartsWith("version:",StringComparison.InvariantCultureIgnoreCase))
|
||||
continue;
|
||||
|
||||
//Split the record into entrylines
|
||||
List<string> uplayEntryLines = uplayEntry.Split('\n').ToList();
|
||||
|
||||
// Skip any records NOT containing an entryline with ' start_game:' (note 2 leading spaces)
|
||||
// All games contain a start_game entry
|
||||
if (!uplayEntryLines.Exists(a => a.StartsWith(" start_game:")))
|
||||
continue;
|
||||
|
||||
// Skip any records containing an entryline with ' third_party_platform:' (note 2 leading spaces)
|
||||
// We only want the native uplay games....
|
||||
if (uplayEntryLines.Exists(a => a.StartsWith(" third_party_platform:")))
|
||||
continue;
|
||||
|
||||
// if we get here then we have a real game to parse!
|
||||
// Yay us :).
|
||||
|
||||
// First we check if there are any localization CONSTANTS that we will need to map later.
|
||||
Dictionary<string, string> localizations = new Dictionary<string, string>();
|
||||
int localizationsIndex = uplayEntryLines.FindIndex(a => a == "localizations:");
|
||||
// If there are localizations, then we need to store them for later
|
||||
if (localizationsIndex != -1)
|
||||
{
|
||||
// grab the localizations: -> default: entries to use as a lookup table for the info we need
|
||||
int defaultIndex = localizationsIndex + 1;
|
||||
int currentIndex = defaultIndex + 1;
|
||||
|
||||
// Grab all EntryLines with 4 leading spaces (these are all the localizations)
|
||||
while (uplayEntryLines[currentIndex].StartsWith(" ")){
|
||||
string[] split = uplayEntryLines[currentIndex].Trim().Split(':');
|
||||
localizations.Add(split[0], split[1]);
|
||||
currentIndex++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// for each game record grab:
|
||||
// name: (lookup the id in lookup table to find the name if needed)
|
||||
|
||||
|
||||
// thumb_image: (lookup the id in lookup table to find the thumbnail)
|
||||
// icon_image: (lookup the id in lookup table to find the ICON)
|
||||
// find the exe name looking at root: -> start_game: -> online: -> executables: -> path: -> relative: (get ACU.exe)
|
||||
// Lookup the Game registry key from looking at root: -> start_game: -> online: -> executables: -> working_directory: -> register: (get HKEY_LOCAL_MACHINE\SOFTWARE\Ubisoft\Launcher\Installs\720\InstallDir)
|
||||
// Extract the GameAppID from the number in the working directory (e.g. 720)
|
||||
// Lookup the Game install path by reading the game registry key: D:/Ubisoft Game Launcher/Assassin's Creed Unity/
|
||||
// join the Game install path and the exe name to get the full game exe path: D:/Ubisoft Game Launcher/Assassin's Creed Unity/ACU.exe
|
||||
// Then we have the gameID, the thumbimage, the icon, the name, the exe path
|
||||
}
|
||||
|
||||
|
||||
List<uint> uplayAppIdsInstalled = new List<uint>();
|
||||
// Now look for what games app id's are actually installed on this computer
|
||||
using (RegistryKey uplayAppsKey = Registry.CurrentUser.OpenSubKey(registryUplayInstallsKey, RegistryKeyPermissionCheck.ReadSubTree))
|
||||
{
|
||||
if (uplayAppsKey != null)
|
||||
{
|
||||
// Loop through the subKeys as they are the Uplay Game IDs
|
||||
foreach (string uplayGameKeyName in uplayAppsKey.GetSubKeyNames())
|
||||
{
|
||||
uint uplayAppId = 0;
|
||||
if (uint.TryParse(uplayGameKeyName, out uplayAppId))
|
||||
{
|
||||
string uplayGameKeyFullName = $"{ registryUplayInstallsKey}\\{uplayGameKeyName}";
|
||||
using (RegistryKey uplayGameKey = Registry.CurrentUser.OpenSubKey(uplayGameKeyFullName, RegistryKeyPermissionCheck.ReadSubTree))
|
||||
{
|
||||
// If the Installed Value is set to 1, then the game is installed
|
||||
// We want to keep track of that for later
|
||||
if ((int)uplayGameKey.GetValue(@"Installed", 0) == 1)
|
||||
{
|
||||
// Add this Uplay App ID to the list we're keeping for later
|
||||
uplayAppIdsInstalled.Add(uplayAppId);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
catch (SecurityException ex)
|
||||
{
|
||||
Console.WriteLine($"UplayGame/GetAllInstalledGames securityexception: {ex.Message}: {ex.StackTrace} - {ex.InnerException}");
|
||||
if (ex.Source != null)
|
||||
Console.WriteLine("SecurityException source: {0} - Message: {1}", ex.Source, ex.Message);
|
||||
throw;
|
||||
}
|
||||
catch (UnauthorizedAccessException ex)
|
||||
{
|
||||
Console.WriteLine($"UplayGame/GetAllInstalledGames unauthorizedaccessexception: {ex.Message}: {ex.StackTrace} - {ex.InnerException}");
|
||||
if (ex.Source != null)
|
||||
Console.WriteLine("UnauthorizedAccessException source: {0} - Message: {1}", ex.Source, ex.Message);
|
||||
throw;
|
||||
}
|
||||
catch (ObjectDisposedException ex)
|
||||
{
|
||||
Console.WriteLine($"UplayGame/GetAllInstalledGames objectdisposedexceptions: {ex.Message}: {ex.StackTrace} - {ex.InnerException}");
|
||||
if (ex.Source != null)
|
||||
Console.WriteLine("ObjectDisposedException source: {0} - Message: {1}", ex.Source, ex.Message);
|
||||
throw;
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
Console.WriteLine($"UplayGame/GetAllInstalledGames ioexception: {ex.Message}: {ex.StackTrace} - {ex.InnerException}");
|
||||
// Extract some information from this exception, and then
|
||||
// throw it to the parent method.
|
||||
if (ex.Source != null)
|
||||
Console.WriteLine("IOException source: {0} - Message: {1}", ex.Source, ex.Message);
|
||||
throw;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
|
||||
[global::System.Serializable]
|
||||
public class UplayLibraryException : Exception
|
||||
{
|
||||
public UplayLibraryException() { }
|
||||
public UplayLibraryException(string message) : base(message) { }
|
||||
public UplayLibraryException(string message, Exception inner) : base(message, inner) { }
|
||||
protected UplayLibraryException(
|
||||
System.Runtime.Serialization.SerializationInfo info,
|
||||
System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
|
||||
}
|
||||
|
||||
}
|
@ -84,6 +84,8 @@
|
||||
<Compile Include="GameLibraries\SteamAppInfoParser\Package.cs" />
|
||||
<Compile Include="GameLibraries\SteamAppInfoParser\PackageInfo.cs" />
|
||||
<Compile Include="GameLibraries\SteamAppInfoParser\App.cs" />
|
||||
<Compile Include="GameLibraries\UplayConfigurationParser\UplayConfigurationParser.cs" />
|
||||
<Compile Include="GameLibraries\UplayLibrary.cs" />
|
||||
<Compile Include="GameLibraries\SteamLibrary.cs" />
|
||||
<Compile Include="IconFromFile.cs" />
|
||||
<Compile Include="IconUtils.cs" />
|
||||
|
@ -443,13 +443,11 @@ namespace HeliosPlus {
|
||||
{
|
||||
// Load Uplay library games
|
||||
Console.WriteLine("Program/LoadGamesInBackground : Loading Installed Uplay Games ");
|
||||
/* if (!HeliosPlus.GameLibraries.UplayLibrary.LoadInstalledGames())
|
||||
if (!HeliosPlus.GameLibraries.UplayLibrary.LoadInstalledGames())
|
||||
{
|
||||
// Somehow return that this profile topology didn't apply
|
||||
throw new LoadingInstalledGamesException("Program/LoadGamesInBackground: Cannot load installed Uplay Games!");
|
||||
}
|
||||
*/
|
||||
|
||||
});
|
||||
|
||||
// Store all the tasks in an array so we can wait on them later
|
||||
|
Loading…
Reference in New Issue
Block a user