From 5bb009e604223922583289a4b8f2964fe50440b8 Mon Sep 17 00:00:00 2001 From: Leon Styhre Date: Mon, 3 Jan 2022 18:37:43 +0100 Subject: [PATCH] Added scraper support for displaying the returned platform if it does not match the game platform. --- es-app/src/PlatformId.cpp | 3 ++ es-app/src/guis/GuiScraperSearch.cpp | 56 ++++++++++++++++++++-- es-app/src/guis/GuiScraperSearch.h | 2 +- es-app/src/scrapers/GamesDBJSONScraper.cpp | 11 +++++ es-app/src/scrapers/Scraper.h | 2 + es-app/src/scrapers/ScreenScraper.cpp | 16 +++++-- 6 files changed, 81 insertions(+), 9 deletions(-) diff --git a/es-app/src/PlatformId.cpp b/es-app/src/PlatformId.cpp index c91cba266..1a0b18a4f 100644 --- a/es-app/src/PlatformId.cpp +++ b/es-app/src/PlatformId.cpp @@ -153,6 +153,9 @@ namespace PlatformIds const std::string getPlatformName(PlatformId id) { + if (id > platformNames.size() - 1) + return "unknown"; + // Return the platform name. return platformNames[id]; } diff --git a/es-app/src/guis/GuiScraperSearch.cpp b/es-app/src/guis/GuiScraperSearch.cpp index 831570556..4e158c426 100644 --- a/es-app/src/guis/GuiScraperSearch.cpp +++ b/es-app/src/guis/GuiScraperSearch.cpp @@ -351,7 +351,7 @@ void GuiScraperSearch::stop() mScrapeResult = {}; } -void GuiScraperSearch::onSearchDone(const std::vector& results) +void GuiScraperSearch::onSearchDone(std::vector& results) { mResultList->clear(); @@ -386,11 +386,57 @@ void GuiScraperSearch::onSearchDone(const std::vector& resu ComponentListRow row; for (size_t i = 0; i < results.size(); ++i) { + // If the platform IDs returned by the scraper do not match the platform IDs of the + // scraped game, then add the additional platform information to the end of the game + // name (within square brackets). + std::string gameName = results.at(i).mdl.get("name"); + std::string otherPlatforms; + + // As the platform names are found via reverse lookup there could be multiple entries. + // So if any of the entries match the platforms of the last search, then just keep + // this platform ID and remove the other ones. + for (auto& platformID : mLastSearch.system->getSystemEnvData()->mPlatformIds) { + if (!results.at(i).platformIDs.empty() && + std::find(results.at(i).platformIDs.begin(), results.at(i).platformIDs.end(), + platformID) != results.at(i).platformIDs.end()) { + results.at(i).platformIDs.clear(); + results.at(i).platformIDs.push_back(platformID); + } + } + + bool hasOtherPlatforms = false; + + for (auto& platformID : mLastSearch.system->getSystemEnvData()->mPlatformIds) { + if (!results.at(i).platformIDs.empty() && + std::find(results.at(i).platformIDs.cbegin(), results.at(i).platformIDs.cend(), + platformID) == results.at(i).platformIDs.cend()) + hasOtherPlatforms = true; + } + + if (hasOtherPlatforms) { + if (std::find(results.at(i).platformIDs.cbegin(), results.at(i).platformIDs.cend(), + PlatformIds::PlatformId::PC) != results.at(i).platformIDs.cend()) { + // The PC platform is a bit special as it's widely used by a number of + // different systems. As such remove these other IDs and only display the + // main PC ID as the list of platforms would otherwise be quite long. + otherPlatforms = PlatformIds::getPlatformName(PlatformIds::PlatformId::PC); + } + else { + for (auto& platform : results.at(i).platformIDs) + otherPlatforms += PlatformIds::getPlatformName(platform) + "/"; + } + } + + if (otherPlatforms != "" && otherPlatforms.back() == '/') + otherPlatforms.pop_back(); + + if (otherPlatforms != "") + gameName.append(" [").append(otherPlatforms).append("]"); + row.elements.clear(); - row.addElement( - std::make_shared( - mWindow, Utils::String::toUpper(results.at(i).mdl.get("name")), font, color), - false); + row.addElement(std::make_shared( + mWindow, Utils::String::toUpper(gameName), font, color), + false); row.makeAcceptInputHandler([this, i] { returnResult(mScraperResults.at(i)); }); mResultList->addRow(row); } diff --git a/es-app/src/guis/GuiScraperSearch.h b/es-app/src/guis/GuiScraperSearch.h index 7ef4beb0f..2df3ce320 100644 --- a/es-app/src/guis/GuiScraperSearch.h +++ b/es-app/src/guis/GuiScraperSearch.h @@ -108,7 +108,7 @@ private: void onSearchError(const std::string& error, HttpReq::Status status = HttpReq::REQ_UNDEFINED_ERROR); - void onSearchDone(const std::vector& results); + void onSearchDone(std::vector& results); int getSelectedIndex(); diff --git a/es-app/src/scrapers/GamesDBJSONScraper.cpp b/es-app/src/scrapers/GamesDBJSONScraper.cpp index 10fdc57be..b9c2d0e23 100644 --- a/es-app/src/scrapers/GamesDBJSONScraper.cpp +++ b/es-app/src/scrapers/GamesDBJSONScraper.cpp @@ -333,6 +333,17 @@ namespace { ScraperSearchResult result; + // Platform IDs. + if (game.HasMember("platform") && game["platform"].IsInt()) { + for (auto& platform : gamesdb_new_platformid_map) { + if (platform.second == std::to_string(game["platform"].GetInt())) + result.platformIDs.push_back(platform.first); + } + } + + if (result.platformIDs.empty()) + result.platformIDs.push_back(PlatformId::PLATFORM_UNKNOWN); + if (game.HasMember("id") && game["id"].IsInt()) result.gameID = std::to_string(getIntOrThrow(game, "id")); diff --git a/es-app/src/scrapers/Scraper.h b/es-app/src/scrapers/Scraper.h index 61c405cff..5877084e4 100644 --- a/es-app/src/scrapers/Scraper.h +++ b/es-app/src/scrapers/Scraper.h @@ -14,6 +14,7 @@ #include "AsyncHandle.h" #include "HttpReq.h" #include "MetaData.h" +#include "PlatformId.h" #include #include @@ -52,6 +53,7 @@ struct ScraperSearchResult { MetaDataList mdl; std::string gameID; + std::vector platformIDs; // How many more objects the scraper service allows to be downloaded // within a given time period. diff --git a/es-app/src/scrapers/ScreenScraper.cpp b/es-app/src/scrapers/ScreenScraper.cpp index 231c26bd4..4224ba3e0 100644 --- a/es-app/src/scrapers/ScreenScraper.cpp +++ b/es-app/src/scrapers/ScreenScraper.cpp @@ -445,11 +445,21 @@ void ScreenScraperRequest::processGame(const pugi::xml_document& xmldoc, << result.mdl.get("players"); } - // Controller (only for the Arcade and SNK Neo Geo systems). pugi::xml_node system = game.child("systeme"); - int platformID = system.attribute("parentid").as_int(); + int platformID = system.attribute("id").as_int(); + int parentPlatformID = system.attribute("parentid").as_int(); - if (platformID == 75 || platformID == 142) { + // Platform IDs. + for (auto& platform : screenscraper_platformid_map) { + if (platform.second == platformID || platform.second == parentPlatformID) + result.platformIDs.push_back(platform.first); + } + + if (result.platformIDs.empty()) + result.platformIDs.push_back(PlatformId::PLATFORM_UNKNOWN); + + // Controller (only for the Arcade and SNK Neo Geo systems). + if (parentPlatformID == 75 || parentPlatformID == 142) { std::string controller = Utils::String::toLower(game.child("controles").text().get()); if (!controller.empty()) { std::string controllerDescription = "Other";