11using System ;
22using System . Collections . Generic ;
3+ using System . Diagnostics . CodeAnalysis ;
34using System . Globalization ;
45using System . IO ;
56using System . Linq ;
@@ -20,6 +21,7 @@ public class HeroicGOGHandler : AHandler<GOGGame, GOGGameId>
2021 private static readonly JsonSerializerOptions JsonSerializerOptions = new ( )
2122 {
2223 AllowTrailingCommas = true ,
24+ ReadCommentHandling = JsonCommentHandling . Skip ,
2325 } ;
2426
2527 /// <summary>
@@ -39,24 +41,25 @@ public HeroicGOGHandler(IFileSystem fileSystem)
3941 /// <inheritdoc/>
4042 public override IEnumerable < OneOf < GOGGame , ErrorMessage > > FindAllGames ( )
4143 {
42- var installedJsonFile = FindConfigDirectory ( _fileSystem )
43- . Select ( GetInstalledJsonFilePath )
44- . FirstOrDefault ( path => path . FileExists ) ;
44+ var configDirectory = FindConfigDirectory ( _fileSystem )
45+ . FirstOrDefault ( path => path . DirectoryExists ( ) ) ;
4546
46- if ( installedJsonFile == default )
47+ if ( configDirectory == default )
4748 {
4849 yield return new ErrorMessage ( "Didn't find any heroic files, this can be ignored if heroic isn't installed" ) ;
4950 yield break ;
5051 }
5152
52- var games = ParseInstalledJsonFile ( installedJsonFile ) ;
53+ var installedJsonFile = GetInstalledJsonFilePath ( configDirectory ) ;
54+
55+ var games = ParseInstalledJsonFile ( installedJsonFile , configDirectory ) ;
5356 foreach ( var x in games )
5457 {
5558 yield return x ;
5659 }
5760 }
5861
59- internal static IEnumerable < OneOf < GOGGame , ErrorMessage > > ParseInstalledJsonFile ( AbsolutePath path )
62+ internal static IEnumerable < OneOf < GOGGame , ErrorMessage > > ParseInstalledJsonFile ( AbsolutePath path , AbsolutePath configPath )
6063 {
6164 using var stream = path . Open ( FileMode . Open , FileAccess . Read , FileShare . Read ) ;
6265 var root = JsonSerializer . Deserialize < DTOs . Root > ( stream , JsonSerializerOptions ) ;
@@ -71,7 +74,7 @@ internal static IEnumerable<OneOf<GOGGame, ErrorMessage>> ParseInstalledJsonFile
7174 OneOf < GOGGame , ErrorMessage > res ;
7275 try
7376 {
74- res = Parse ( installed , path . FileSystem ) ;
77+ res = Parse ( installed , configPath , path . FileSystem ) ;
7578 }
7679 catch ( Exception e )
7780 {
@@ -82,15 +85,40 @@ internal static IEnumerable<OneOf<GOGGame, ErrorMessage>> ParseInstalledJsonFile
8285 }
8386 }
8487
85- internal static OneOf < GOGGame , ErrorMessage > Parse ( DTOs . Installed installed , IFileSystem fileSystem )
88+ [ RequiresUnreferencedCode ( "Calls System.Text.Json.JsonSerializer.Deserialize<TValue>(JsonSerializerOptions)" ) ]
89+ internal static OneOf < GOGGame , ErrorMessage > Parse (
90+ DTOs . Installed installed ,
91+ AbsolutePath configPath ,
92+ IFileSystem fileSystem )
8693 {
8794 if ( ! long . TryParse ( installed . AppName , NumberStyles . Integer , CultureInfo . InvariantCulture , out var id ) )
8895 {
8996 return new ErrorMessage ( $ "The value \" appName\" is not a number: \" { installed . AppName } \" ") ;
9097 }
9198
99+ var gamesConfigFile = GetGamesConfigJsonFile ( configPath , id . ToString ( CultureInfo . InvariantCulture ) ) ;
100+ if ( ! gamesConfigFile . FileExists ) return new ErrorMessage ( $ "File `{ gamesConfigFile } ` doesn't exist!") ;
101+
102+ using var stream = gamesConfigFile . Open ( FileMode . Open , FileAccess . Read , FileShare . Read ) ;
103+ using var doc = JsonDocument . Parse ( stream , new JsonDocumentOptions
104+ {
105+ AllowTrailingCommas = true ,
106+ CommentHandling = JsonCommentHandling . Skip ,
107+ } ) ;
108+
109+ var element = doc . RootElement . GetProperty ( id . ToString ( CultureInfo . InvariantCulture ) ) ;
110+ var gameConfig = element . Deserialize < DTOs . GameConfig > ( ) ;
111+ if ( gameConfig is null ) return new ErrorMessage ( $ "Unable to deserialize `{ gamesConfigFile } `") ;
112+
92113 var path = fileSystem . FromUnsanitizedFullPath ( installed . InstallPath ) ;
93- return new GOGGame ( GOGGameId . From ( id ) , installed . AppName , path ) ;
114+ var winePrefixPath = fileSystem . FromUnsanitizedFullPath ( gameConfig . WinePrefix ) ;
115+
116+ return new HeroicGOGGame ( GOGGameId . From ( id ) , installed . AppName , path , winePrefixPath , gameConfig . WineVersion ) ;
117+ }
118+
119+ internal static AbsolutePath GetGamesConfigJsonFile ( AbsolutePath configPath , string name )
120+ {
121+ return configPath . Combine ( "GamesConfig" ) . Combine ( $ "{ name } .json") ;
94122 }
95123
96124 internal static AbsolutePath GetInstalledJsonFilePath ( AbsolutePath configPath )
0 commit comments