internal GameMetadata ProcessField( Game game, MetadataFieldSettings fieldSettings, MetadataField gameField, Func <GameMetadata, object> propertySelector, Dictionary <Guid, GameMetadata> existingStoreData, Dictionary <Guid, OnDemandMetadataProvider> existingPluginData) { if (fieldSettings.Sources.Any() == false) { return(null); } foreach (var source in fieldSettings.Sources) { try { // Skip Store source for manually added games. if (source == Guid.Empty && game.PluginId == Guid.Empty) { continue; } // Check if metadata from this source are already downloaded. if (existingStoreData.ContainsKey(source)) { if (existingStoreData[source] != null && propertySelector(existingStoreData[source]) != null) { return(existingStoreData[source]); } else { continue; } } // Check if downloader supports this game field. if (source != Guid.Empty) { var downloader = metadataDownloaders.FirstOrDefault(a => a.Id == source); if (downloader == null) { continue; } else if (downloader.SupportedFields?.Contains(gameField) != true) { continue; } } // Download metadata. GameMetadata metadata = null; if (source == Guid.Empty) { metadata = ProcessStoreDownload(game); existingStoreData.Add(source, metadata); } else { var downloader = metadataDownloaders.FirstOrDefault(a => a.Id == source); if (downloader == null) { continue; } OnDemandMetadataProvider provider = null; if (existingPluginData.ContainsKey(source)) { provider = existingPluginData[source]; } else { provider = downloader.GetMetadataProvider(new MetadataRequestOptions(game, true)); existingPluginData.Add(source, provider); } if (provider == null) { continue; } if (!provider.AvailableFields.Contains(gameField)) { continue; } var gameInfo = new GameInfo(); metadata = new GameMetadata { GameInfo = gameInfo }; switch (gameField) { case MetadataField.Name: gameInfo.Name = provider.GetName(); break; case MetadataField.Genres: gameInfo.Genres = provider.GetGenres(); break; case MetadataField.ReleaseDate: gameInfo.ReleaseDate = provider.GetReleaseDate(); break; case MetadataField.Developers: gameInfo.Developers = provider.GetDevelopers(); break; case MetadataField.Publishers: gameInfo.Publishers = provider.GetPublishers(); break; case MetadataField.Tags: gameInfo.Tags = provider.GetTags(); break; case MetadataField.Description: gameInfo.Description = provider.GetDescription(); break; case MetadataField.Links: gameInfo.Links = provider.GetLinks(); break; case MetadataField.CriticScore: gameInfo.CriticScore = provider.GetCriticScore(); break; case MetadataField.CommunityScore: gameInfo.CommunityScore = provider.GetCommunityScore(); break; case MetadataField.Icon: metadata.Icon = provider.GetIcon(); break; case MetadataField.CoverImage: metadata.CoverImage = provider.GetCoverImage(); break; case MetadataField.BackgroundImage: metadata.BackgroundImage = provider.GetBackgroundImage(); break; case MetadataField.Features: gameInfo.Features = provider.GetFeatures(); break; case MetadataField.AgeRating: gameInfo.AgeRating = provider.GetAgeRating(); break; case MetadataField.Region: gameInfo.Region = provider.GetRegion(); break; case MetadataField.Series: gameInfo.Series = provider.GetSeries(); break; case MetadataField.Platform: gameInfo.Platform = provider.GetPlatform(); break; default: throw new NotImplementedException(); } } if (metadata != null && propertySelector(metadata) != null) { return(metadata); } else { continue; } } catch (Exception e) when(!PlayniteEnvironment.ThrowAllErrors) { logger.Error(e, $"Failed to process metadata download: {gameField}, {source}"); } } return(null); }