diff --git a/GameLauncher_Console/GameLauncher_Console/Dock.cs b/GameLauncher_Console/GameLauncher_Console/Dock.cs index 0449771..2a4da52 100644 --- a/GameLauncher_Console/GameLauncher_Console/Dock.cs +++ b/GameLauncher_Console/GameLauncher_Console/Dock.cs @@ -97,16 +97,19 @@ public void MainLoop(string[] args) platforms.AddSupportedPlatform(new PlatformGOG()); platforms.AddSupportedPlatform(new PlatformIGClient()); platforms.AddSupportedPlatform(new PlatformItch()); -#if DEBUG - // an experiment for now - platforms.AddSupportedPlatform(new PlatformMicrosoft()); -#endif platforms.AddSupportedPlatform(new PlatformOculus()); platforms.AddSupportedPlatform(new PlatformOrigin()); platforms.AddSupportedPlatform(new PlatformParadox()); platforms.AddSupportedPlatform(new PlatformRockstar()); platforms.AddSupportedPlatform(new PlatformSteam()); platforms.AddSupportedPlatform(new PlatformUplay()); +#if DEBUG + // experiments for now + platforms.AddSupportedPlatform(new PlatformArc()); + platforms.AddSupportedPlatform(new PlatformMicrosoft()); + //platforms.AddSupportedPlatform(new PlatformPlarium()); + //platforms.AddSupportedPlatform(new PlatformWargaming()); +#endif bool import, parseError = false; import = CJsonWrapper.ImportFromINI(out CConfig.ConfigVolatile cfgv, out CConfig.Hotkeys keys, out CConfig.Colours cols); if (!import) parseError = true; @@ -893,11 +896,8 @@ from part in newTags.Split('|') case GamePlatform.BigFish: PlatformBigFish.Launch(); break; - case GamePlatform.Arc: // TODO? - if (OperatingSystem.IsWindows()) - StartShellExecute(CPlatform.ARC_PROTOCOL); - else - Process.Start(CPlatform.ARC_PROTOCOL); + case GamePlatform.Arc: + PlatformArc.Launch(); break; case GamePlatform.Itch: PlatformItch.Launch(); @@ -906,18 +906,13 @@ from part in newTags.Split('|') PlatformParadox.Launch(); break; case GamePlatform.Plarium: // TODO? - if (OperatingSystem.IsWindows()) - StartShellExecute(CPlatform.PLARIUM_PROTOCOL); - else - Process.Start(CPlatform.PLARIUM_PROTOCOL); + //PlatformPlarium.Launch(); break; case GamePlatform.Twitch: // TODO? + //PlatformTwitch.Launch(); break; case GamePlatform.Wargaming: // TODO? - if (OperatingSystem.IsWindows()) - StartShellExecute(CPlatform.WARGAMING_PROTOCOL); - else - Process.Start(CPlatform.WARGAMING_PROTOCOL); + //PlatformWargaming.Launch(); break; case GamePlatform.IGClient: PlatformIGClient.Launch(); diff --git a/GameLauncher_Console/GameLauncher_Console/GameData.cs b/GameLauncher_Console/GameLauncher_Console/GameData.cs index a5f6b69..ddf3103 100644 --- a/GameLauncher_Console/GameLauncher_Console/GameData.cs +++ b/GameLauncher_Console/GameLauncher_Console/GameData.cs @@ -51,7 +51,7 @@ public enum GamePlatform Amazon = 13, [Description("Big Fish")] BigFish = 14, - [Description("Arc")] // TODO + [Description("Arc")] Arc = 15, [Description("itch")] Itch = 16, @@ -67,7 +67,7 @@ public enum GamePlatform IGClient = 21, [Description("New games")] New = 22, - [Description("Not installed")] // TODO + [Description("Not installed")] NotInstalled = 23, [Description("Microsoft Store")] // TODO Microsoft = 24, diff --git a/GameLauncher_Console/GameLauncher_Console/Platform.cs b/GameLauncher_Console/GameLauncher_Console/Platform.cs index ca742d4..77c2274 100644 --- a/GameLauncher_Console/GameLauncher_Console/Platform.cs +++ b/GameLauncher_Console/GameLauncher_Console/Platform.cs @@ -83,18 +83,6 @@ public enum Platform // POTENTIAL FUTURE PLATFORMS: - // Arc - public const string ARC_NAME = "Arc"; - public const string ARC_NAME_LONG = "Arc"; - public const string ARC_PROTOCOL = "arc://"; - //private const string ARC_UNREG = "{CED8E25B-122A-4E80-B612-7F99B93284B3}"; // HKLM32 Uninstall - - // Plarium Play - public const string PLARIUM_NAME = "Plarium"; - public const string PLARIUM_NAME_LONG = "Plarium Play"; - public const string PLARIUM_PROTOCOL = "plariumplay://"; - //private const string PLARIUM_UNREG = "{970D6975-3C2A-4AF9-B190-12AF8837331F}"; // HKLM32 Uninstall - // Twitch [deprecated, now Amazon Games] /* public const string TWITCH_NAME = "Twitch"; @@ -102,12 +90,6 @@ public enum Platform private const string TWITCH_UNREG = "{DEE70742-F4E9-44CA-B2B9-EE95DCF37295}"; // HKCU64 Uninstall */ - // Wargaming.net Game Center - public const string WARGAMING_NAME = "Wargaming"; - public const string WARGAMING_NAME_LONG = "Wargaming.net Game Center"; - public const string WARGAMING_PROTOCOL = "wgc://"; - //private const string WARGAMING_UNREG = "Wargaming.net Game Center"; // HKCU64 Uninstall - #region Query definitions /// diff --git a/GameLauncher_Console/GameLauncher_Console/Platforms/Arc.cs b/GameLauncher_Console/GameLauncher_Console/Platforms/Arc.cs new file mode 100644 index 0000000..22a1820 --- /dev/null +++ b/GameLauncher_Console/GameLauncher_Console/Platforms/Arc.cs @@ -0,0 +1,134 @@ +using Logger; +using Microsoft.Win32; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Runtime.Versioning; +using static GameLauncher_Console.CGameData; +using static GameLauncher_Console.CRegScanner; +using static System.Environment; + +namespace GameLauncher_Console +{ + // Arc + // [installed games only] + public class PlatformArc : IPlatform + { + public const GamePlatform ENUM = GamePlatform.Arc; + public const string PROTOCOL = "arc://"; + private const string ARC_REG = @"SOFTWARE\WOW6432Node\Perfect World Entertainment"; // HKLM32 + //private const string ARC_UNREG = "{CED8E25B-122A-4E80-B612-7F99B93284B3}"; // HKLM32 Uninstall + private const string ARC_GAMES = "Core"; + private const string ARC_ID = "APP_ABBR"; + private const string ARC_PATH = "INSTALL_PATH"; + private const string ARC_EXEPATH = "CLIENT_PATH"; + private const string ARC_INST = "installed"; + //[strLaunch] CLIENT_PATH in e.g., HKLM\SOFTWARE\WOW6432Node\Perfect World Entertainment\Core\1400en + //[strId?] APP_ABBR + //[installed] installed + + private static readonly string _name = Enum.GetName(typeof(GamePlatform), ENUM); + + GamePlatform IPlatform.Enum => ENUM; + + string IPlatform.Name => _name; + + string IPlatform.Description => GetPlatformString(ENUM); + + public static void Launch() + { + if (OperatingSystem.IsWindows()) + CDock.StartShellExecute(PROTOCOL); + else + Process.Start(PROTOCOL); + } + + public static void InstallGame(CGame game) => throw new NotImplementedException(); + + [SupportedOSPlatform("windows")] + public void GetGames(List gameDataList, bool expensiveIcons = false) + { + List keyList = new(); + //string arcFolder = Path.Combine(GetFolderPath(SpecialFolder.ApplicationData), "Arc"); // AppData\Roaming + /* + string launcherPath = ""; + + using (RegistryKey launcherKey = Registry.LocalMachine.OpenSubKey(Path.Combine(ARC_REG, "Arc"), RegistryKeyPermissionCheck.ReadSubTree)) // HKLM32 + { + if (launcherKey == null) + { + CLogger.LogInfo("{0} client not found in the registry.", _name.ToUpper()); + return; + } + launcherPath = GetRegStrVal(launcherKey, "client"); + } + */ + + using (RegistryKey key = Registry.LocalMachine.OpenSubKey(Path.Combine(ARC_REG, ARC_GAMES), RegistryKeyPermissionCheck.ReadSubTree)) // HKLM32 + { + foreach (string subKey in key.GetSubKeyNames()) // Add subkeys to search list + { + try + { + if (subKey.IndexOf("en") > -1) + keyList.Add(key.OpenSubKey(subKey, RegistryKeyPermissionCheck.ReadSubTree)); + } + catch (Exception e) + { + CLogger.LogError(e); + } + } + CLogger.LogInfo("{0} {1} games found", keyList.Count, _name.ToUpper()); + foreach (var data in keyList) + { + string id = GetRegStrVal(data, ARC_ID); + if (string.IsNullOrEmpty(id)) + { + id = Path.GetFileName(data.Name); + int idIndex = id.IndexOf("en"); + if (idIndex > -1) + id = id.Substring(0, idIndex); + } + string name = Path.GetFileName(GetRegStrVal(data, ARC_PATH).Trim(new char[] { '"', '\\', '/' })); + int nameIndex = name.IndexOf("_en"); + if (nameIndex > -1) + name = name.Substring(0, nameIndex); + string strID = ""; + string strTitle = ""; + string strLaunch = ""; + string strAlias = ""; + bool bInstalled = true; + string strPlatform = GetPlatformString(ENUM); + + try + { + strID = "arc_" + id; + if (!string.IsNullOrEmpty(name)) + strTitle = name; + else + strTitle = id; + CLogger.LogDebug($"- {strTitle}"); + strLaunch = GetRegStrVal(data, ARC_EXEPATH); + strAlias = GetAlias(Path.GetFileNameWithoutExtension(strLaunch)); + if (strAlias.Length > strTitle.Length) + strAlias = GetAlias(strTitle); + if (strAlias.Equals(strTitle, CDock.IGNORE_CASE)) + strAlias = ""; + int? installed = GetRegDWORDVal(data, ARC_INST); + if (installed != null && installed == 0) + bInstalled = false; + } + catch (Exception e) + { + CLogger.LogError(e); + } + if (!(string.IsNullOrEmpty(strLaunch))) + gameDataList.Add( + new ImportGameData(strID, strTitle, strLaunch, strLaunch, "", strAlias, bInstalled, strPlatform)); + } + } + CLogger.LogDebug("------------------------"); + } + } +} \ No newline at end of file diff --git a/GameLauncher_Console/GameLauncher_Console/RegScanner.cs b/GameLauncher_Console/GameLauncher_Console/RegScanner.cs index c269e31..3dd9c6e 100644 --- a/GameLauncher_Console/GameLauncher_Console/RegScanner.cs +++ b/GameLauncher_Console/GameLauncher_Console/RegScanner.cs @@ -28,11 +28,11 @@ public static class CRegScanner /// Looks for a key-value pair inside the specified root. /// /// Root folder that will be scanned - /// The target value in the subkey - /// The target key that should contain the target value + /// A substring of the target value data in the subkey + /// The target value name that should contain the target value data /// Function will ignore these subkey names (used to ignore things like launchers) /// List of game registry keys - public static List FindGameKeys(RegistryKey root, string strValue, string strKeyName, string[] ignoreKeys) + public static List FindGameKeys(RegistryKey root, string strValData, string strValName, string[] ignoreKeys) { LinkedList toCheck = new(); List gameKeys = new(); @@ -48,9 +48,9 @@ public static List FindGameKeys(RegistryKey root, string strValue, { foreach(var name in root.GetValueNames()) { - if(root.GetValueKind(name) == RegistryValueKind.String && name == strKeyName) + if(root.GetValueKind(name) == RegistryValueKind.String && name.Equals(strValName)) { - if(((string)root.GetValue(name)).Contains(strValue, CDock.IGNORE_CASE)) + if(((string)root.GetValue(name)).Contains(strValData, CDock.IGNORE_CASE)) { gameKeys.Add(root); break;