heroic games launcher support
This commit is contained in:
parent
d08c7c50a7
commit
0974f78889
5 changed files with 94 additions and 29 deletions
|
@ -9,6 +9,7 @@ using System.Threading.Tasks;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
using CreamInstaller.Components;
|
using CreamInstaller.Components;
|
||||||
using CreamInstaller.Platforms.Epic;
|
using CreamInstaller.Platforms.Epic;
|
||||||
|
using CreamInstaller.Platforms.Epic.Heroic;
|
||||||
using CreamInstaller.Platforms.Paradox;
|
using CreamInstaller.Platforms.Paradox;
|
||||||
using CreamInstaller.Platforms.Steam;
|
using CreamInstaller.Platforms.Steam;
|
||||||
using CreamInstaller.Platforms.Ubisoft;
|
using CreamInstaller.Platforms.Ubisoft;
|
||||||
|
@ -647,7 +648,7 @@ internal sealed partial class SelectForm : CustomForm
|
||||||
=> !Program.IsGameBlocked(g.name, g.gameDirectory)))
|
=> !Program.IsGameBlocked(g.name, g.gameDirectory)))
|
||||||
gameChoices.Add((Platform.Steam, appId, name,
|
gameChoices.Add((Platform.Steam, appId, name,
|
||||||
programsToScan is not null && programsToScan.Any(p => p.platform is Platform.Steam && p.id == appId)));
|
programsToScan is not null && programsToScan.Any(p => p.platform is Platform.Steam && p.id == appId)));
|
||||||
if (EpicLibrary.EpicManifestsPath.DirectoryExists())
|
if (EpicLibrary.EpicManifestsPath.DirectoryExists() || HeroicLibrary.HeroicLibraryPath.DirectoryExists())
|
||||||
gameChoices.AddRange((await EpicLibrary.GetGames()).Where(m => !Program.IsGameBlocked(m.DisplayName, m.InstallLocation)).Select(manifest
|
gameChoices.AddRange((await EpicLibrary.GetGames()).Where(m => !Program.IsGameBlocked(m.DisplayName, m.InstallLocation)).Select(manifest
|
||||||
=> (Platform.Epic, manifest.CatalogNamespace, manifest.DisplayName,
|
=> (Platform.Epic, manifest.CatalogNamespace, manifest.DisplayName,
|
||||||
programsToScan is not null && programsToScan.Any(p => p.platform is Platform.Epic && p.id == manifest.CatalogNamespace))));
|
programsToScan is not null && programsToScan.Any(p => p.platform is Platform.Epic && p.id == manifest.CatalogNamespace))));
|
||||||
|
@ -659,7 +660,7 @@ internal sealed partial class SelectForm : CustomForm
|
||||||
using SelectDialogForm form = new(this);
|
using SelectDialogForm form = new(this);
|
||||||
DialogResult selectResult = form.QueryUser("Choose which programs and/or games to scan:", gameChoices,
|
DialogResult selectResult = form.QueryUser("Choose which programs and/or games to scan:", gameChoices,
|
||||||
out List<(Platform platform, string id, string name)> choices);
|
out List<(Platform platform, string id, string name)> choices);
|
||||||
if (selectResult == DialogResult.Abort) // will be an uninstall all button
|
if (selectResult == DialogResult.Abort)
|
||||||
{
|
{
|
||||||
int maxProgress = 0;
|
int maxProgress = 0;
|
||||||
int curProgress = 0;
|
int curProgress = 0;
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using CreamInstaller.Platforms.Epic.Heroic;
|
||||||
using CreamInstaller.Utility;
|
using CreamInstaller.Utility;
|
||||||
using Microsoft.Win32;
|
using Microsoft.Win32;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
@ -29,29 +30,31 @@ internal static class EpicLibrary
|
||||||
=> await Task.Run(async () => await gameDirectory.GetExecutableDirectories(true));
|
=> await Task.Run(async () => await gameDirectory.GetExecutableDirectories(true));
|
||||||
|
|
||||||
internal static async Task<HashSet<Manifest>> GetGames()
|
internal static async Task<HashSet<Manifest>> GetGames()
|
||||||
=> await Task.Run(() =>
|
=> await Task.Run(async () =>
|
||||||
{
|
{
|
||||||
HashSet<Manifest> games = new();
|
HashSet<Manifest> games = new();
|
||||||
string manifests = EpicManifestsPath;
|
string manifests = EpicManifestsPath;
|
||||||
if (!manifests.DirectoryExists())
|
if (manifests.DirectoryExists())
|
||||||
|
foreach (string item in manifests.EnumerateDirectory("*.item"))
|
||||||
|
{
|
||||||
|
if (Program.Canceled)
|
||||||
|
return games;
|
||||||
|
string json = item.ReadFile();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Manifest manifest = JsonConvert.DeserializeObject<Manifest>(json);
|
||||||
|
if (manifest is not null && !games.Any(g
|
||||||
|
=> g.CatalogNamespace == manifest.CatalogNamespace && g.InstallLocation == manifest.InstallLocation))
|
||||||
|
_ = games.Add(manifest);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
// ignored
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (Program.Canceled)
|
||||||
return games;
|
return games;
|
||||||
foreach (string file in manifests.EnumerateDirectory("*.item"))
|
await HeroicLibrary.GetGames(games);
|
||||||
{
|
|
||||||
if (Program.Canceled)
|
|
||||||
return games;
|
|
||||||
string json = file.ReadFile();
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Manifest manifest = JsonConvert.DeserializeObject<Manifest>(json);
|
|
||||||
if (manifest is not null && manifest.CatalogItemId == manifest.MainGameCatalogItemId && !games.Any(g
|
|
||||||
=> g.CatalogItemId == manifest.CatalogItemId && g.InstallLocation == manifest.InstallLocation))
|
|
||||||
_ = games.Add(manifest);
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
// ignored
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return games;
|
return games;
|
||||||
});
|
});
|
||||||
}
|
}
|
19
CreamInstaller/Platforms/Epic/Heroic/HeroicAppData.cs
Normal file
19
CreamInstaller/Platforms/Epic/Heroic/HeroicAppData.cs
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
|
namespace CreamInstaller.Platforms.Epic.Heroic;
|
||||||
|
|
||||||
|
public class HeroicInstall
|
||||||
|
{
|
||||||
|
[JsonProperty("install_path")] public string InstallPath { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class HeroicAppData
|
||||||
|
{
|
||||||
|
[JsonProperty("install")] public HeroicInstall Install { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("namespace")] public string Namespace { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("title")] public string Title { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("runner")] public string Runner { get; set; }
|
||||||
|
}
|
50
CreamInstaller/Platforms/Epic/Heroic/HeroicLibrary.cs
Normal file
50
CreamInstaller/Platforms/Epic/Heroic/HeroicLibrary.cs
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using CreamInstaller.Utility;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
|
||||||
|
namespace CreamInstaller.Platforms.Epic.Heroic;
|
||||||
|
|
||||||
|
internal static class HeroicLibrary
|
||||||
|
{
|
||||||
|
internal static readonly string HeroicLibraryPath
|
||||||
|
= Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + @"\heroic\store_cache\legendary_library.json";
|
||||||
|
|
||||||
|
internal static async Task GetGames(HashSet<Manifest> games)
|
||||||
|
=> await Task.Run(() =>
|
||||||
|
{
|
||||||
|
string libraryPath = HeroicLibraryPath;
|
||||||
|
if (!libraryPath.FileExists())
|
||||||
|
return;
|
||||||
|
string libraryJson = libraryPath.ReadFile();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
JObject library = JObject.Parse(libraryJson);
|
||||||
|
if (!library.TryGetValue("library", out JToken libraryToken) || libraryToken is not JArray libraryArray)
|
||||||
|
return;
|
||||||
|
foreach (JToken token in libraryArray)
|
||||||
|
try
|
||||||
|
{
|
||||||
|
HeroicAppData appData = token.ToObject<HeroicAppData>();
|
||||||
|
if (appData is null || appData.Runner != "legendary" || string.IsNullOrWhiteSpace(appData.Install.InstallPath))
|
||||||
|
continue;
|
||||||
|
Manifest manifest = new()
|
||||||
|
{
|
||||||
|
DisplayName = appData.Title, CatalogNamespace = appData.Namespace, InstallLocation = appData.Install.InstallPath
|
||||||
|
};
|
||||||
|
if (!games.Any(g => g.CatalogNamespace == manifest.CatalogNamespace && g.InstallLocation == manifest.InstallLocation))
|
||||||
|
_ = games.Add(manifest);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
// ignored
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
// ignored
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
|
@ -6,13 +6,5 @@ public class Manifest
|
||||||
|
|
||||||
public string InstallLocation { get; set; }
|
public string InstallLocation { get; set; }
|
||||||
|
|
||||||
public string LaunchExecutable { get; set; }
|
|
||||||
|
|
||||||
public string CatalogNamespace { get; set; }
|
public string CatalogNamespace { get; set; }
|
||||||
|
|
||||||
public string CatalogItemId { get; set; }
|
|
||||||
|
|
||||||
public string MainGameCatalogNamespace { get; set; }
|
|
||||||
|
|
||||||
public string MainGameCatalogItemId { get; set; }
|
|
||||||
}
|
}
|
Loading…
Reference in a new issue