示例#1
0
        private GameMetadata ProcessDownload(Game game, ref GameMetadata data)
        {
            if (data == null)
            {
                data = GetMetaProviderByProvider(game.Provider).GetMetadata(game);
            }

            return(data);
        }
示例#2
0
        private GameMetadata ProcessDownload(Game game, ref GameMetadata data)
        {
            if (data == null)
            {
                var downloader = GetMetadataDownloader(game.PluginId);
                try
                {
                    data = downloader?.GetMetadata(game);
                }
                catch (Exception e) when(!PlayniteEnvironment.ThrowAllErrors)
                {
                    logger.Error(e, $"Failed to download metadat from plugin downloader.");
                    data = null;
                }
            }

            return(data);
        }
示例#3
0
        private GameMetadata ProcessField(
            Game game,
            MetadataFieldSettings field,
            ref GameMetadata storeData,
            ref GameMetadata igdbData,
            Func <GameMetadata, object> propertySelector)
        {
            if (field.Import)
            {
                if (field.Source == MetadataSource.Store && !game.IsCustomGame)
                {
                    storeData = ProcessDownload(game, ref storeData);
                    return(storeData);
                }
                else if (field.Source == MetadataSource.IGDB)
                {
                    if (igdbData == null)
                    {
                        igdbData = igdbProvider.GetMetadata(game);
                    }

                    return(igdbData);
                }
                else if (field.Source == MetadataSource.IGDBOverStore)
                {
                    if (igdbData == null)
                    {
                        igdbData = igdbProvider.GetMetadata(game);
                    }

                    if (igdbData?.GameData == null && !game.IsCustomGame)
                    {
                        if (storeData == null)
                        {
                            storeData = ProcessDownload(game, ref storeData);
                        }

                        return(storeData);
                    }
                    else
                    {
                        var igdbValue = propertySelector(igdbData);
                        if (igdbValue != null)
                        {
                            return(igdbData);
                        }
                        else if (!game.IsCustomGame)
                        {
                            if (storeData == null)
                            {
                                storeData = ProcessDownload(game, ref storeData);
                            }

                            if (storeData?.GameData != null)
                            {
                                return(storeData);
                            }
                            else
                            {
                                return(igdbData);
                            }
                        }
                    }
                }
                else if (field.Source == MetadataSource.StoreOverIGDB)
                {
                    if (!game.IsCustomGame)
                    {
                        if (storeData == null)
                        {
                            storeData = ProcessDownload(game, ref storeData);
                        }

                        if (storeData?.GameData == null)
                        {
                            if (igdbData == null)
                            {
                                igdbData = igdbProvider.GetMetadata(game);
                            }

                            return(igdbData);
                        }
                        else
                        {
                            var storeValue = propertySelector(storeData);
                            if (storeValue != null)
                            {
                                return(storeData);
                            }
                            else
                            {
                                if (igdbData == null)
                                {
                                    igdbData = igdbProvider.GetMetadata(game);
                                }

                                return(igdbData);
                            }
                        }
                    }
                    else
                    {
                        if (igdbData == null)
                        {
                            igdbData = igdbProvider.GetMetadata(game);
                        }

                        return(igdbData);
                    }
                }
            }

            return(null);
        }
示例#4
0
        public async Task DownloadMetadataAsync(
            List <Game> games,
            GameDatabase database,
            MetadataDownloaderSettings settings,
            Action <Game, int, int> processCallback,
            CancellationTokenSource cancelToken)
        {
            await Task.Run(() =>
            {
                if (games == null || games.Count == 0)
                {
                    return;
                }

                for (int i = 0; i < games.Count; i++)
                {
                    if (cancelToken?.IsCancellationRequested == true)
                    {
                        return;
                    }

                    GameMetadata storeData = null;
                    GameMetadata igdbData  = null;
                    GameMetadata gameData  = null;

                    // We need to get new instance from DB in case game got edited or deleted.
                    // We don't want to block game editing while metadata is downloading for other games.
                    // TODO: Use Id instead of GameId once we replace LiteDB and have proper autoincrement Id
                    var game = database.GamesCollection.FindOne(a => a.PluginId == games[i].PluginId && a.GameId == games[i].GameId);
                    if (game == null)
                    {
                        logger.Warn($"Game {game.GameId} no longer in DB, skipping metadata download.");
                        processCallback?.Invoke(null, i, games.Count);
                        continue;
                    }

                    try
                    {
                        logger.Debug($"Downloading metadata for {game.PluginId} game {game.Name}, {game.GameId}");

                        // Name
                        if (!game.IsCustomGame && settings.Name.Import)
                        {
                            gameData = ProcessField(game, settings.Name, ref storeData, ref igdbData, (a) => a.GameData?.Name);
                            if (!string.IsNullOrEmpty(gameData?.GameData?.Name))
                            {
                                game.Name       = StringExtensions.RemoveTrademarks(gameData.GameData.Name);
                                var sortingName = StringExtensions.ConvertToSortableName(game.Name);
                                if (sortingName != game.Name)
                                {
                                    game.SortingName = sortingName;
                                }
                            }
                        }

                        // Genre
                        if (settings.Genre.Import)
                        {
                            if (!settings.SkipExistingValues || (settings.SkipExistingValues && ListExtensions.IsNullOrEmpty(game.Genres)))
                            {
                                gameData    = ProcessField(game, settings.Genre, ref storeData, ref igdbData, (a) => a.GameData?.Genres);
                                game.Genres = ListExtensions.IsNullOrEmpty(gameData?.GameData?.Genres) ? game.Genres : gameData.GameData.Genres;
                            }
                        }

                        // Release Date
                        if (settings.ReleaseDate.Import)
                        {
                            if (!settings.SkipExistingValues || (settings.SkipExistingValues && game.ReleaseDate == null))
                            {
                                gameData         = ProcessField(game, settings.ReleaseDate, ref storeData, ref igdbData, (a) => a.GameData?.ReleaseDate);
                                game.ReleaseDate = gameData?.GameData?.ReleaseDate ?? game.ReleaseDate;
                            }
                        }

                        // Developer
                        if (settings.Developer.Import)
                        {
                            if (!settings.SkipExistingValues || (settings.SkipExistingValues && ListExtensions.IsNullOrEmpty(game.Developers)))
                            {
                                gameData        = ProcessField(game, settings.Developer, ref storeData, ref igdbData, (a) => a.GameData?.Developers);
                                game.Developers = ListExtensions.IsNullOrEmpty(gameData?.GameData?.Developers) ? game.Developers : gameData.GameData.Developers;
                            }
                        }

                        // Publisher
                        if (settings.Publisher.Import)
                        {
                            if (!settings.SkipExistingValues || (settings.SkipExistingValues && ListExtensions.IsNullOrEmpty(game.Publishers)))
                            {
                                gameData        = ProcessField(game, settings.Publisher, ref storeData, ref igdbData, (a) => a.GameData?.Publishers);
                                game.Publishers = ListExtensions.IsNullOrEmpty(gameData?.GameData?.Publishers) ? game.Publishers : gameData.GameData.Publishers;
                            }
                        }

                        // Tags / Features
                        if (settings.Tag.Import)
                        {
                            if (!settings.SkipExistingValues || (settings.SkipExistingValues && ListExtensions.IsNullOrEmpty(game.Tags)))
                            {
                                gameData  = ProcessField(game, settings.Tag, ref storeData, ref igdbData, (a) => a.GameData?.Tags);
                                game.Tags = ListExtensions.IsNullOrEmpty(gameData?.GameData?.Tags) ? game.Tags : gameData.GameData.Tags;
                            }
                        }

                        // Description
                        if (settings.Description.Import)
                        {
                            if (!settings.SkipExistingValues || (settings.SkipExistingValues && string.IsNullOrEmpty(game.Description)))
                            {
                                gameData         = ProcessField(game, settings.Description, ref storeData, ref igdbData, (a) => a.GameData?.Description);
                                game.Description = string.IsNullOrEmpty(gameData?.GameData?.Description) == true ? game.Description : gameData.GameData.Description;
                            }
                        }

                        // Links
                        if (settings.Links.Import)
                        {
                            if (!settings.SkipExistingValues || (settings.SkipExistingValues && game.Links == null))
                            {
                                gameData   = ProcessField(game, settings.Links, ref storeData, ref igdbData, (a) => a.GameData?.Links);
                                game.Links = gameData?.GameData?.Links ?? game.Links;
                            }
                        }

                        // Critic Score
                        if (settings.CriticScore.Import)
                        {
                            if (!settings.SkipExistingValues || (settings.SkipExistingValues && game.CriticScore == null))
                            {
                                gameData         = ProcessField(game, settings.CriticScore, ref storeData, ref igdbData, (a) => a.GameData?.CriticScore);
                                game.CriticScore = gameData?.GameData?.CriticScore == null ? game.CriticScore : gameData.GameData.CriticScore;
                            }
                        }

                        // Community Score
                        if (settings.CommunityScore.Import)
                        {
                            if (!settings.SkipExistingValues || (settings.SkipExistingValues && game.CommunityScore == null))
                            {
                                gameData            = ProcessField(game, settings.CommunityScore, ref storeData, ref igdbData, (a) => a.GameData?.CommunityScore);
                                game.CommunityScore = gameData?.GameData?.CommunityScore == null ? game.CommunityScore : gameData.GameData.CommunityScore;
                            }
                        }

                        // BackgroundImage
                        if (settings.BackgroundImage.Import)
                        {
                            if (!settings.SkipExistingValues || (settings.SkipExistingValues && string.IsNullOrEmpty(game.BackgroundImage)))
                            {
                                gameData             = ProcessField(game, settings.BackgroundImage, ref storeData, ref igdbData, (a) => a.BackgroundImage);
                                game.BackgroundImage = string.IsNullOrEmpty(gameData?.BackgroundImage) ? game.BackgroundImage : gameData.BackgroundImage;
                            }
                        }

                        // Cover
                        if (settings.CoverImage.Import)
                        {
                            if (!settings.SkipExistingValues || (settings.SkipExistingValues && string.IsNullOrEmpty(game.CoverImage)))
                            {
                                gameData = ProcessField(game, settings.CoverImage, ref storeData, ref igdbData, (a) => a.Image);
                                if (gameData?.Image != null)
                                {
                                    if (!string.IsNullOrEmpty(game.CoverImage))
                                    {
                                        database.DeleteImageSafe(game.CoverImage, game);
                                    }

                                    var imageId     = database.AddFileNoDuplicate(gameData.Image);
                                    game.CoverImage = imageId;
                                }
                            }
                        }

                        // Icon
                        if (settings.Icon.Import)
                        {
                            if (!settings.SkipExistingValues || (settings.SkipExistingValues && string.IsNullOrEmpty(game.Icon)))
                            {
                                gameData = ProcessField(game, settings.Icon, ref storeData, ref igdbData, (a) => a.Icon);
                                if (gameData?.Icon != null)
                                {
                                    if (!string.IsNullOrEmpty(game.Icon))
                                    {
                                        database.DeleteImageSafe(game.Icon, game);
                                    }

                                    var iconId = database.AddFileNoDuplicate(gameData.Icon);
                                    game.Icon  = iconId;
                                }
                            }
                        }

                        // TODO make this configurable and re-downalodable manually
                        // Only update them if they don't exist yet
                        if (game.OtherActions?.Any() != true && storeData != null)
                        {
                            if (storeData?.GameData?.OtherActions?.Any() == true)
                            {
                                game.OtherActions = new System.Collections.ObjectModel.ObservableCollection <GameAction>();
                                foreach (var task in storeData.GameData.OtherActions)
                                {
                                    game.OtherActions.Add(task);
                                }
                            }
                        }

                        // Just to be sure check if somebody didn't remove game while downloading data
                        if (database.GamesCollection.FindOne(a => a.GameId == games[i].GameId) != null)
                        {
                            database.UpdateGameInDatabase(game);
                        }
                        else
                        {
                            logger.Warn($"Game {game.GameId} no longer in DB, skipping metadata update in DB.");
                        }
                    }
                    catch (Exception e) when(!PlayniteEnvironment.ThrowAllErrors)
                    {
                        logger.Error(e, $"Failed to download metadata for game {game.Name}, {game.GameId}");
                    }
                    finally
                    {
                        processCallback?.Invoke(game, i, games.Count);
                    }
                }
            });
        }
        internal GameMetadata ProcessField(
            Game game,
            MetadataFieldSettings fieldSettings,
            MetadataField gameField,
            Func <GameMetadata, object> propertySelector,
            Dictionary <Guid, GameMetadata> existingStoreData,
            Dictionary <Guid, OnDemandMetadataProvider> existingPluginData,
            CancellationToken cancelToken)
        {
            if (fieldSettings.Sources.Any() == false)
            {
                return(null);
            }

            var getFieldArgs = new GetMetadataFieldArgs {
                CancelToken = cancelToken
            };

            foreach (var source in fieldSettings.Sources)
            {
                if (cancelToken.IsCancellationRequested)
                {
                    return(null);
                }

                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;
                        }

                        metadata = new GameMetadata();
                        switch (gameField)
                        {
                        case MetadataField.Name:
                            metadata.Name = provider.GetName(getFieldArgs);
                            break;

                        case MetadataField.Genres:
                            metadata.Genres = provider.GetGenres(getFieldArgs)?.Where(a => a != null).ToHashSet();
                            break;

                        case MetadataField.ReleaseDate:
                            metadata.ReleaseDate = provider.GetReleaseDate(getFieldArgs);
                            break;

                        case MetadataField.Developers:
                            metadata.Developers = provider.GetDevelopers(getFieldArgs)?.Where(a => a != null).ToHashSet();
                            break;

                        case MetadataField.Publishers:
                            metadata.Publishers = provider.GetPublishers(getFieldArgs)?.Where(a => a != null).ToHashSet();
                            break;

                        case MetadataField.Tags:
                            metadata.Tags = provider.GetTags(getFieldArgs)?.Where(a => a != null).ToHashSet();
                            break;

                        case MetadataField.Description:
                            metadata.Description = provider.GetDescription(getFieldArgs);
                            break;

                        case MetadataField.Links:
                            metadata.Links = provider.GetLinks(getFieldArgs)?.Where(a => a != null).ToList();
                            break;

                        case MetadataField.CriticScore:
                            metadata.CriticScore = provider.GetCriticScore(getFieldArgs);
                            break;

                        case MetadataField.CommunityScore:
                            metadata.CommunityScore = provider.GetCommunityScore(getFieldArgs);
                            break;

                        case MetadataField.Icon:
                            metadata.Icon = provider.GetIcon(getFieldArgs);
                            break;

                        case MetadataField.CoverImage:
                            metadata.CoverImage = provider.GetCoverImage(getFieldArgs);
                            break;

                        case MetadataField.BackgroundImage:
                            metadata.BackgroundImage = provider.GetBackgroundImage(getFieldArgs);
                            break;

                        case MetadataField.Features:
                            metadata.Features = provider.GetFeatures(getFieldArgs)?.Where(a => a != null).ToHashSet();
                            break;

                        case MetadataField.AgeRating:
                            metadata.AgeRatings = provider.GetAgeRatings(getFieldArgs)?.Where(a => a != null).ToHashSet();
                            break;

                        case MetadataField.Region:
                            metadata.Regions = provider.GetRegions(getFieldArgs)?.Where(a => a != null).ToHashSet();
                            break;

                        case MetadataField.Series:
                            metadata.Series = provider.GetSeries(getFieldArgs)?.Where(a => a != null).ToHashSet();
                            break;

                        case MetadataField.Platform:
                            metadata.Platforms = provider.GetPlatforms(getFieldArgs)?.Where(a => a != null).ToHashSet();
                            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);
        }
        public Task DownloadMetadataAsync(
            List <Game> games,
            MetadataDownloaderSettings settings,
            PlayniteSettings playniteSettings,
            Action <Game, int, int> progressCallback,
            CancellationToken cancelToken)
        {
            return(Task.Run(() =>
            {
                if (games == null || games.Count == 0)
                {
                    return;
                }

                for (int i = 0; i < games.Count; i++)
                {
                    Game game = null;
                    var existingStoreData = new Dictionary <Guid, GameMetadata>();
                    var existingPluginData = new Dictionary <Guid, OnDemandMetadataProvider>();

                    try
                    {
                        if (cancelToken.IsCancellationRequested == true)
                        {
                            return;
                        }

                        GameMetadata gameData = null;

                        // We need to get new instance from DB in case game got edited or deleted.
                        // We don't want to block game editing while metadata is downloading for other games.
                        game = database.Games[games[i].Id]?.GetClone();
                        if (game == null)
                        {
                            logger.Warn($"Game {game.Id} no longer in DB, skipping metadata download.");
                            progressCallback?.Invoke(null, i, games.Count);
                            continue;
                        }

                        var dataModified = false;
                        game.PropertyChanged += (_, __) => dataModified = true;

                        if (game != null)
                        {
                            progressCallback?.Invoke(game, i, games.Count);
                        }

                        logger.Debug($"Downloading metadata for {game.Name}, {game.GameId}, {game.PluginId}");

                        // Name
                        if (!game.IsCustomGame && settings.Name.Import)
                        {
                            gameData = ProcessField(game, settings.Name, MetadataField.Name, (a) => a.Name, existingStoreData, existingPluginData, cancelToken);
                            if (!string.IsNullOrEmpty(gameData?.Name))
                            {
                                game.Name = StringExtensions.RemoveTrademarks(gameData.Name);
                                var sortingName = StringExtensions.ConvertToSortableName(game.Name);
                                if (sortingName != game.Name)
                                {
                                    game.SortingName = sortingName;
                                }
                            }
                        }

                        // Genre
                        if (settings.Genre.Import)
                        {
                            if (!settings.SkipExistingValues || (settings.SkipExistingValues && !game.GenreIds.HasItems()))
                            {
                                gameData = ProcessField(game, settings.Genre, MetadataField.Genres, (a) => a.Genres, existingStoreData, existingPluginData, cancelToken);
                                if (gameData?.Genres.HasItems() == true)
                                {
                                    game.GenreIds = database.Genres.Add(gameData.Genres).Select(a => a.Id).ToList();
                                }
                            }
                        }

                        // Release Date
                        if (settings.ReleaseDate.Import)
                        {
                            if (!settings.SkipExistingValues || (settings.SkipExistingValues && game.ReleaseDate == null))
                            {
                                gameData = ProcessField(game, settings.ReleaseDate, MetadataField.ReleaseDate, (a) => a.ReleaseDate, existingStoreData, existingPluginData, cancelToken);
                                game.ReleaseDate = gameData?.ReleaseDate ?? game.ReleaseDate;
                            }
                        }

                        // Developer
                        if (settings.Developer.Import)
                        {
                            if (!settings.SkipExistingValues || (settings.SkipExistingValues && !game.DeveloperIds.HasItems()))
                            {
                                gameData = ProcessField(game, settings.Developer, MetadataField.Developers, (a) => a.Developers, existingStoreData, existingPluginData, cancelToken);
                                if (gameData?.Developers.HasItems() == true)
                                {
                                    game.DeveloperIds = database.Companies.Add(gameData.Developers).Select(a => a.Id).ToList();
                                }
                            }
                        }

                        // Publisher
                        if (settings.Publisher.Import)
                        {
                            if (!settings.SkipExistingValues || (settings.SkipExistingValues && !game.PublisherIds.HasItems()))
                            {
                                gameData = ProcessField(game, settings.Publisher, MetadataField.Publishers, (a) => a.Publishers, existingStoreData, existingPluginData, cancelToken);
                                if (gameData?.Publishers.HasItems() == true)
                                {
                                    game.PublisherIds = database.Companies.Add(gameData.Publishers).Select(a => a.Id).ToList();
                                }
                            }
                        }

                        // Tags
                        if (settings.Tag.Import)
                        {
                            if (!settings.SkipExistingValues || (settings.SkipExistingValues && !game.TagIds.HasItems()))
                            {
                                gameData = ProcessField(game, settings.Tag, MetadataField.Tags, (a) => a.Tags, existingStoreData, existingPluginData, cancelToken);
                                if (gameData?.Tags.HasItems() == true)
                                {
                                    game.TagIds = database.Tags.Add(gameData.Tags).Select(a => a.Id).ToList();
                                }
                            }
                        }

                        // Features
                        if (settings.Feature.Import)
                        {
                            if (!settings.SkipExistingValues || (settings.SkipExistingValues && !game.FeatureIds.HasItems()))
                            {
                                gameData = ProcessField(game, settings.Feature, MetadataField.Features, (a) => a.Features, existingStoreData, existingPluginData, cancelToken);
                                if (gameData?.Features.HasItems() == true)
                                {
                                    game.FeatureIds = database.Features.Add(gameData.Features).Select(a => a.Id).ToList();
                                }
                            }
                        }

                        // Description
                        if (settings.Description.Import)
                        {
                            if (!settings.SkipExistingValues || (settings.SkipExistingValues && string.IsNullOrEmpty(game.Description)))
                            {
                                gameData = ProcessField(game, settings.Description, MetadataField.Description, (a) => a.Description, existingStoreData, existingPluginData, cancelToken);
                                game.Description = string.IsNullOrEmpty(gameData?.Description) == true ? game.Description : gameData.Description;
                            }
                        }

                        // Links
                        if (settings.Links.Import)
                        {
                            if (!settings.SkipExistingValues || (settings.SkipExistingValues && !game.Links.HasItems()))
                            {
                                gameData = ProcessField(game, settings.Links, MetadataField.Links, (a) => a.Links, existingStoreData, existingPluginData, cancelToken);
                                if (gameData?.Links.HasItems() == true)
                                {
                                    game.Links = gameData.Links.ToObservable();
                                }
                            }
                        }

                        // Age rating
                        if (settings.AgeRating.Import)
                        {
                            if (!settings.SkipExistingValues || (settings.SkipExistingValues && !game.AgeRatingIds.HasItems()))
                            {
                                gameData = ProcessField(game, settings.AgeRating, MetadataField.AgeRating, (a) => a.AgeRatings, existingStoreData, existingPluginData, cancelToken);
                                if (gameData?.AgeRatings.HasItems() == true)
                                {
                                    game.AgeRatingIds = database.AgeRatings.Add(gameData.AgeRatings).Select(a => a.Id).ToList();
                                }
                            }
                        }

                        // Region
                        if (settings.Region.Import)
                        {
                            if (!settings.SkipExistingValues || (settings.SkipExistingValues && !game.RegionIds.HasItems()))
                            {
                                gameData = ProcessField(game, settings.Region, MetadataField.Region, (a) => a.Regions, existingStoreData, existingPluginData, cancelToken);
                                if (gameData?.Regions.HasItems() == true)
                                {
                                    game.RegionIds = database.Regions.Add(gameData.Regions).Select(a => a.Id).ToList();
                                }
                            }
                        }

                        // Series
                        if (settings.Series.Import)
                        {
                            if (!settings.SkipExistingValues || (settings.SkipExistingValues && !game.SeriesIds.HasItems()))
                            {
                                gameData = ProcessField(game, settings.Series, MetadataField.Series, (a) => a.Series, existingStoreData, existingPluginData, cancelToken);
                                if (gameData?.Series.HasItems() == true)
                                {
                                    game.SeriesIds = database.Series.Add(gameData.Series).Select(a => a.Id).ToList();
                                }
                            }
                        }

                        // Platform
                        if (settings.Platform.Import)
                        {
                            if (!settings.SkipExistingValues || (settings.SkipExistingValues && !game.PlatformIds.HasItems()))
                            {
                                gameData = ProcessField(game, settings.Platform, MetadataField.Platform, (a) => a.Platforms, existingStoreData, existingPluginData, cancelToken);
                                if (gameData?.Platforms.HasItems() == true)
                                {
                                    game.PlatformIds = database.Platforms.Add(gameData.Platforms).Select(a => a.Id).ToList();
                                }
                            }
                        }

                        // Critic Score
                        if (settings.CriticScore.Import)
                        {
                            if (!settings.SkipExistingValues || (settings.SkipExistingValues && game.CriticScore == null))
                            {
                                gameData = ProcessField(game, settings.CriticScore, MetadataField.CriticScore, (a) => a.CriticScore, existingStoreData, existingPluginData, cancelToken);
                                game.CriticScore = gameData?.CriticScore == null ? game.CriticScore : gameData.CriticScore;
                            }
                        }

                        // Community Score
                        if (settings.CommunityScore.Import)
                        {
                            if (!settings.SkipExistingValues || (settings.SkipExistingValues && game.CommunityScore == null))
                            {
                                gameData = ProcessField(game, settings.CommunityScore, MetadataField.CommunityScore, (a) => a.CommunityScore, existingStoreData, existingPluginData, cancelToken);
                                game.CommunityScore = gameData?.CommunityScore == null ? game.CommunityScore : gameData.CommunityScore;
                            }
                        }

                        // BackgroundImage
                        if (settings.BackgroundImage.Import)
                        {
                            if (!settings.SkipExistingValues || (settings.SkipExistingValues && string.IsNullOrEmpty(game.BackgroundImage)))
                            {
                                gameData = ProcessField(game, settings.BackgroundImage, MetadataField.BackgroundImage, (a) => a.BackgroundImage, existingStoreData, existingPluginData, cancelToken);
                                if (gameData?.BackgroundImage != null)
                                {
                                    if (playniteSettings.DownloadBackgroundsImmediately && gameData.BackgroundImage.HasImageData)
                                    {
                                        game.BackgroundImage = database.AddFile(gameData.BackgroundImage, game.Id, true);
                                    }
                                    else if (!playniteSettings.DownloadBackgroundsImmediately &&
                                             !gameData.BackgroundImage.Path.IsNullOrEmpty())
                                    {
                                        game.BackgroundImage = gameData.BackgroundImage.Path;
                                    }
                                    else if (gameData.BackgroundImage.HasImageData)
                                    {
                                        game.BackgroundImage = database.AddFile(gameData.BackgroundImage, game.Id, true);
                                    }
                                }
                            }
                        }

                        // Cover
                        if (settings.CoverImage.Import)
                        {
                            if (!settings.SkipExistingValues || (settings.SkipExistingValues && string.IsNullOrEmpty(game.CoverImage)))
                            {
                                gameData = ProcessField(game, settings.CoverImage, MetadataField.CoverImage, (a) => a.CoverImage, existingStoreData, existingPluginData, cancelToken);
                                if (gameData?.CoverImage != null)
                                {
                                    game.CoverImage = database.AddFile(gameData.CoverImage, game.Id, true);
                                }
                            }
                        }

                        // Icon
                        if (settings.Icon.Import)
                        {
                            if (!settings.SkipExistingValues || (settings.SkipExistingValues && string.IsNullOrEmpty(game.Icon)))
                            {
                                gameData = ProcessField(game, settings.Icon, MetadataField.Icon, (a) => a.Icon, existingStoreData, existingPluginData, cancelToken);
                                if (gameData?.Icon != null)
                                {
                                    game.Icon = database.AddFile(gameData.Icon, game.Id, true);
                                }
                            }
                        }

                        // Just to be sure check if somebody didn't remove game while downloading data
                        if (database.Games.FirstOrDefault(a => a.Id == games[i].Id) != null && dataModified)
                        {
                            game.Modified = DateTime.Now;
                            database.Games.Update(game);
                        }
                        else
                        {
                            logger.Warn($"Game {game.Id} no longer in DB, skipping metadata update in DB.");
                        }
                    }
                    catch (Exception e) when(!PlayniteEnvironment.ThrowAllErrors)
                    {
                        logger.Error(e, $"Failed to download metadata for game {game?.Name}, {game?.Id}");
                    }
                    finally
                    {
                        foreach (var plugin in existingPluginData.Values)
                        {
                            plugin.Dispose();
                        }
                    }
                }
            }));
        }
示例#7
0
        public Task DownloadMetadataAsync(
            List <Game> games,
            MetadataDownloaderSettings settings,
            Action <Game, int, int> processCallback,
            CancellationTokenSource cancelToken)
        {
            return(Task.Run(() =>
            {
                if (games == null || games.Count == 0)
                {
                    return;
                }

                for (int i = 0; i < games.Count; i++)
                {
                    Game game = null;

                    try
                    {
                        if (cancelToken?.IsCancellationRequested == true)
                        {
                            return;
                        }

                        GameMetadata storeData = null;
                        GameMetadata igdbData = null;
                        GameMetadata gameData = null;

                        // We need to get new instance from DB in case game got edited or deleted.
                        // We don't want to block game editing while metadata is downloading for other games.
                        game = database.Games[games[i].Id]?.GetClone();
                        if (game == null)
                        {
                            logger.Warn($"Game {game.GameId} no longer in DB, skipping metadata download.");
                            processCallback?.Invoke(null, i, games.Count);
                            continue;
                        }

                        logger.Debug($"Downloading metadata for {game.Name}, {game.GameId}, {game.PluginId}");

                        // Name
                        if (!game.IsCustomGame && settings.Name.Import)
                        {
                            gameData = ProcessField(game, settings.Name, ref storeData, ref igdbData, (a) => a.GameInfo?.Name);
                            if (!string.IsNullOrEmpty(gameData?.GameInfo?.Name))
                            {
                                game.Name = StringExtensions.RemoveTrademarks(gameData.GameInfo.Name);
                                var sortingName = StringExtensions.ConvertToSortableName(game.Name);
                                if (sortingName != game.Name)
                                {
                                    game.SortingName = sortingName;
                                }
                            }
                        }

                        // Genre
                        if (settings.Genre.Import)
                        {
                            if (!settings.SkipExistingValues || (settings.SkipExistingValues && !game.GenreIds.HasItems()))
                            {
                                gameData = ProcessField(game, settings.Genre, ref storeData, ref igdbData, (a) => a.GameInfo?.Genres);
                                if (gameData?.GameInfo?.Genres.HasNonEmptyItems() == true)
                                {
                                    game.GenreIds = database.Genres.Add(gameData.GameInfo.Genres).Select(a => a.Id).ToList();
                                }
                            }
                        }

                        // Release Date
                        if (settings.ReleaseDate.Import)
                        {
                            if (!settings.SkipExistingValues || (settings.SkipExistingValues && game.ReleaseDate == null))
                            {
                                gameData = ProcessField(game, settings.ReleaseDate, ref storeData, ref igdbData, (a) => a.GameInfo?.ReleaseDate);
                                game.ReleaseDate = gameData?.GameInfo?.ReleaseDate ?? game.ReleaseDate;
                            }
                        }

                        // Developer
                        if (settings.Developer.Import)
                        {
                            if (!settings.SkipExistingValues || (settings.SkipExistingValues && !game.DeveloperIds.HasItems()))
                            {
                                gameData = ProcessField(game, settings.Developer, ref storeData, ref igdbData, (a) => a.GameInfo?.Developers);
                                if (gameData?.GameInfo?.Developers.HasNonEmptyItems() == true)
                                {
                                    game.DeveloperIds = database.Companies.Add(gameData.GameInfo.Developers).Select(a => a.Id).ToList();
                                }
                            }
                        }

                        // Publisher
                        if (settings.Publisher.Import)
                        {
                            if (!settings.SkipExistingValues || (settings.SkipExistingValues && !game.PublisherIds.HasItems()))
                            {
                                gameData = ProcessField(game, settings.Publisher, ref storeData, ref igdbData, (a) => a.GameInfo?.Publishers);
                                if (gameData?.GameInfo?.Publishers.HasNonEmptyItems() == true)
                                {
                                    game.PublisherIds = database.Companies.Add(gameData.GameInfo.Publishers).Select(a => a.Id).ToList();
                                }
                            }
                        }

                        // Tags / Features
                        if (settings.Tag.Import)
                        {
                            if (!settings.SkipExistingValues || (settings.SkipExistingValues && !game.TagIds.HasItems()))
                            {
                                gameData = ProcessField(game, settings.Tag, ref storeData, ref igdbData, (a) => a.GameInfo?.Tags);
                                if (gameData?.GameInfo?.Tags.HasNonEmptyItems() == true)
                                {
                                    game.TagIds = database.Tags.Add(gameData.GameInfo.Tags).Select(a => a.Id).ToList();
                                }
                            }
                        }

                        // Description
                        if (settings.Description.Import)
                        {
                            if (!settings.SkipExistingValues || (settings.SkipExistingValues && string.IsNullOrEmpty(game.Description)))
                            {
                                gameData = ProcessField(game, settings.Description, ref storeData, ref igdbData, (a) => a.GameInfo?.Description);
                                game.Description = string.IsNullOrEmpty(gameData?.GameInfo?.Description) == true ? game.Description : gameData.GameInfo.Description;
                            }
                        }

                        // Links
                        if (settings.Links.Import)
                        {
                            if (!settings.SkipExistingValues || (settings.SkipExistingValues && !game.Links.HasItems()))
                            {
                                gameData = ProcessField(game, settings.Links, ref storeData, ref igdbData, (a) => a.GameInfo?.Links);
                                if (gameData?.GameInfo?.Links.HasItems() == true)
                                {
                                    game.Links = gameData.GameInfo.Links.ToObservable();
                                }
                            }
                        }

                        // Critic Score
                        if (settings.CriticScore.Import)
                        {
                            if (!settings.SkipExistingValues || (settings.SkipExistingValues && game.CriticScore == null))
                            {
                                gameData = ProcessField(game, settings.CriticScore, ref storeData, ref igdbData, (a) => a.GameInfo?.CriticScore);
                                game.CriticScore = gameData?.GameInfo?.CriticScore == null ? game.CriticScore : gameData.GameInfo.CriticScore;
                            }
                        }

                        // Community Score
                        if (settings.CommunityScore.Import)
                        {
                            if (!settings.SkipExistingValues || (settings.SkipExistingValues && game.CommunityScore == null))
                            {
                                gameData = ProcessField(game, settings.CommunityScore, ref storeData, ref igdbData, (a) => a.GameInfo?.CommunityScore);
                                game.CommunityScore = gameData?.GameInfo?.CommunityScore == null ? game.CommunityScore : gameData.GameInfo.CommunityScore;
                            }
                        }

                        // BackgroundImage
                        if (settings.BackgroundImage.Import)
                        {
                            if (!settings.SkipExistingValues || (settings.SkipExistingValues && string.IsNullOrEmpty(game.BackgroundImage)))
                            {
                                gameData = ProcessField(game, settings.BackgroundImage, ref storeData, ref igdbData, (a) => a.BackgroundImage);
                                if (gameData?.BackgroundImage != null)
                                {
                                    if (gameData.BackgroundImage.HasContent)
                                    {
                                        game.BackgroundImage = database.AddFile(gameData.BackgroundImage, game.Id);
                                    }
                                    else
                                    {
                                        game.BackgroundImage = gameData.BackgroundImage.OriginalUrl;
                                    }
                                }
                            }
                        }

                        // Cover
                        if (settings.CoverImage.Import)
                        {
                            if (!settings.SkipExistingValues || (settings.SkipExistingValues && string.IsNullOrEmpty(game.CoverImage)))
                            {
                                gameData = ProcessField(game, settings.CoverImage, ref storeData, ref igdbData, (a) => a.CoverImage);
                                if (gameData?.CoverImage != null)
                                {
                                    game.CoverImage = database.AddFile(gameData.CoverImage, game.Id);
                                }
                            }
                        }

                        // Icon
                        if (settings.Icon.Import)
                        {
                            if (!settings.SkipExistingValues || (settings.SkipExistingValues && string.IsNullOrEmpty(game.Icon)))
                            {
                                gameData = ProcessField(game, settings.Icon, ref storeData, ref igdbData, (a) => a.Icon);
                                if (gameData?.Icon != null)
                                {
                                    game.Icon = database.AddFile(gameData.Icon, game.Id);
                                }
                            }
                        }

                        // Only update them if they don't exist yet
                        if (game.OtherActions?.Any() != true && storeData != null)
                        {
                            if (storeData?.GameInfo?.OtherActions?.Any() == true)
                            {
                                game.OtherActions = new System.Collections.ObjectModel.ObservableCollection <GameAction>();
                                foreach (var task in storeData.GameInfo.OtherActions)
                                {
                                    game.OtherActions.Add(task);
                                }
                            }
                        }

                        // Just to be sure check if somebody didn't remove game while downloading data
                        if (database.Games.FirstOrDefault(a => a.GameId == games[i].GameId) != null)
                        {
                            database.Games.Update(game);
                        }
                        else
                        {
                            logger.Warn($"Game {game.GameId} no longer in DB, skipping metadata update in DB.");
                        }
                    }
                    catch (Exception e) when(!PlayniteEnvironment.ThrowAllErrors)
                    {
                        logger.Error(e, $"Failed to download metadata for game {game?.Name}, {game?.GameId}");
                    }
                    finally
                    {
                        if (game != null)
                        {
                            processCallback?.Invoke(game, i, games.Count);
                        }
                    }
                }
            }));
        }
示例#8
0
        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)
            {
                // 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;

                    default:
                        throw new NotImplementedException();
                    }
                }

                if (metadata != null && propertySelector(metadata) != null)
                {
                    return(metadata);
                }
                else
                {
                    continue;
                }
            }

            return(null);
        }