diff --git a/src/Abstractions/NexusMods.Abstractions.GameLocators/Stores/GOG/GOGLocatorResultMetadata.cs b/src/Abstractions/NexusMods.Abstractions.GameLocators/Stores/GOG/GOGLocatorResultMetadata.cs index d5cba47d39..1c471ca5cb 100644 --- a/src/Abstractions/NexusMods.Abstractions.GameLocators/Stores/GOG/GOGLocatorResultMetadata.cs +++ b/src/Abstractions/NexusMods.Abstractions.GameLocators/Stores/GOG/GOGLocatorResultMetadata.cs @@ -14,3 +14,6 @@ public record GOGLocatorResultMetadata : IGameLocatorResultMetadata /// public required long Id { get; init; } } + +[PublicAPI] +public record HeroicGOGLocatorResultMetadata : GOGLocatorResultMetadata; diff --git a/src/Abstractions/NexusMods.Abstractions.Games/RunGameTool.cs b/src/Abstractions/NexusMods.Abstractions.Games/RunGameTool.cs index 39c9851350..ff255d097b 100644 --- a/src/Abstractions/NexusMods.Abstractions.Games/RunGameTool.cs +++ b/src/Abstractions/NexusMods.Abstractions.Games/RunGameTool.cs @@ -5,6 +5,7 @@ using Microsoft.Extensions.Logging; using NexusMods.Abstractions.GameLocators; using NexusMods.Abstractions.Games.DTO; +using NexusMods.Abstractions.Games.Stores.GOG; using NexusMods.Abstractions.Games.Stores.Steam; using NexusMods.Abstractions.Loadouts; using NexusMods.CrossPlatform.Process; @@ -60,10 +61,18 @@ public async Task Execute(Loadout.ReadOnly loadout, CancellationToken cancellati var program = await GetGamePath(loadout); var primaryFile = _game.GetPrimaryFile(loadout.InstallationInstance.Store).CombineChecked(loadout.InstallationInstance); - if (OSInformation.Shared.IsLinux && program.Equals(primaryFile) && loadout.InstallationInstance.LocatorResultMetadata is SteamLocatorResultMetadata steamLocatorResultMetadata) + if (OSInformation.Shared.IsLinux && program.Equals(primaryFile)) { - await RunThroughSteam(steamLocatorResultMetadata.AppId, cancellationToken); - return; + var locator = loadout.InstallationInstance.LocatorResultMetadata; + switch (locator) + { + case SteamLocatorResultMetadata steamLocatorResultMetadata: + await RunThroughSteam(steamLocatorResultMetadata.AppId, cancellationToken); + return; + case HeroicGOGLocatorResultMetadata heroicGOGLocatorResultMetadata: + await RunThroughHeroic("gog", heroicGOGLocatorResultMetadata.Id, cancellationToken); + return; + } } var names = new HashSet @@ -177,6 +186,14 @@ private async Task RunThroughSteam(uint appId, CancellationToken cancellationTok await reaper.WaitForExitAsync(cancellationToken); } + private async Task RunThroughHeroic(string type, long appId, CancellationToken cancellationToken) + { + Debug.Assert(OSInformation.Shared.IsLinux); + + // TODO: track process + await _osInterop.OpenUrl(new Uri($"heroic://launch/{type}/{appId.ToString(CultureInfo.InvariantCulture)}"), fireAndForget: false, cancellationToken: cancellationToken); + } + private async ValueTask WaitForProcessToStart( string processName, TimeSpan timeout, diff --git a/src/NexusMods.StandardGameLocators/HeroicGogLocator.cs b/src/NexusMods.StandardGameLocators/HeroicGogLocator.cs index 9a9f5abbcb..e7e80b1947 100644 --- a/src/NexusMods.StandardGameLocators/HeroicGogLocator.cs +++ b/src/NexusMods.StandardGameLocators/HeroicGogLocator.cs @@ -44,7 +44,7 @@ public IEnumerable Find(ILocatableGame game) foreach (var id in tg.GogIds) { if (!_cachedGames.TryGetValue(GOGGameId.From(id), out var found)) continue; - yield return new GameLocatorResult(found.Path, GameStore.GOG, new GOGLocatorResultMetadata + yield return new GameLocatorResult(found.Path, GameStore.GOG, new HeroicGOGLocatorResultMetadata { Id = id, });