|
11 | 11 | namespace GameFinder.StoreHandlers.EGS; |
12 | 12 |
|
13 | 13 | [UsedImplicitly] |
14 | | -internal record ManifestFile(string CatalogItemId, string DisplayName, string InstallLocation); |
| 14 | +internal record ManifestFile(string CatalogItemId, string DisplayName, string InstallLocation, string ManifestHash, string MainGameCatalogItemId); |
15 | 15 |
|
16 | 16 | /// <summary> |
17 | 17 | /// Handler for finding games installed with the Epic Games Store. |
@@ -73,13 +73,38 @@ public override IEnumerable<OneOf<EGSGame, ErrorMessage>> FindAllGames() |
73 | 73 | yield break; |
74 | 74 | } |
75 | 75 |
|
76 | | - foreach (var itemFile in itemFiles) |
| 76 | + // Parse all the files |
| 77 | + var allItems = itemFiles.Select(DeserializeItem).ToList(); |
| 78 | + |
| 79 | + // Group by the MainGameCatalogItemId, and collect all the manifest hashes |
| 80 | + // for each game. If a game has multiple DLCs, all the DLCs will reference the |
| 81 | + // same MainGameCatalogItemId. |
| 82 | + var itemsGrouped = allItems |
| 83 | + .Where(f => f.Match(f0: static _ => true, f1: static _ => false)) |
| 84 | + .Select(f => f.AsT0) |
| 85 | + .GroupBy(c => c.MainGameCatalogItemId, StringComparer.OrdinalIgnoreCase) |
| 86 | + .Select(group => |
| 87 | + { |
| 88 | + return new EGSGame( |
| 89 | + EGSGameId.From(group.Key), |
| 90 | + group.First().DisplayName, |
| 91 | + _fileSystem.FromUnsanitizedFullPath(group.First().InstallLocation), |
| 92 | + group.Select(g => g.ManifestHash).ToArray()); |
| 93 | + }); |
| 94 | + |
| 95 | + foreach (var game in itemsGrouped) |
77 | 96 | { |
78 | | - yield return DeserializeGame(itemFile); |
| 97 | + yield return game; |
| 98 | + } |
| 99 | + |
| 100 | + foreach (var errorMessage in allItems |
| 101 | + .Where(f => f.Match(f0: static _ => false, f1: static _ => true))) |
| 102 | + { |
| 103 | + yield return errorMessage.AsT1; |
79 | 104 | } |
80 | 105 | } |
81 | 106 |
|
82 | | - private OneOf<EGSGame, ErrorMessage> DeserializeGame(AbsolutePath itemFile) |
| 107 | + private OneOf<ManifestFile, ErrorMessage> DeserializeItem(AbsolutePath itemFile) |
83 | 108 | { |
84 | 109 | using var stream = _fileSystem.ReadFile(itemFile); |
85 | 110 |
|
@@ -109,13 +134,7 @@ private OneOf<EGSGame, ErrorMessage> DeserializeGame(AbsolutePath itemFile) |
109 | 134 | return new ErrorMessage($"Manifest {itemFile.GetFullPath()} does not have a value \"InstallLocation\""); |
110 | 135 | } |
111 | 136 |
|
112 | | - var game = new EGSGame( |
113 | | - EGSGameId.From(manifest.CatalogItemId), |
114 | | - manifest.DisplayName, |
115 | | - _fileSystem.FromUnsanitizedFullPath(manifest.InstallLocation) |
116 | | - ); |
117 | | - |
118 | | - return game; |
| 137 | + return manifest; |
119 | 138 | } |
120 | 139 | catch (Exception e) |
121 | 140 | { |
|
0 commit comments