From daf66c4b60277473b81f34dd33b3368085e34fc3 Mon Sep 17 00:00:00 2001 From: Leon Styhre Date: Fri, 17 Dec 2021 20:18:47 +0100 Subject: [PATCH] Added proper support for interpreting directories as files. --- es-app/src/SystemData.cpp | 15 +++++++++++---- es-app/src/guis/GuiGamelistOptions.cpp | 10 ++++++++++ es-app/src/guis/GuiMetaDataEd.cpp | 18 ++++++++++++++---- es-app/src/guis/GuiScraperSearch.cpp | 16 +++++++++++++--- es-app/src/scrapers/GamesDBJSONScraper.cpp | 17 ++++++++++++++--- es-app/src/scrapers/ScreenScraper.cpp | 19 ++++++++++++++++--- 6 files changed, 78 insertions(+), 17 deletions(-) diff --git a/es-app/src/SystemData.cpp b/es-app/src/SystemData.cpp index 68a84afbc..c67dc79b8 100644 --- a/es-app/src/SystemData.cpp +++ b/es-app/src/SystemData.cpp @@ -298,15 +298,22 @@ bool SystemData::populateFolder(FileData* folder) // We first get the extension of the file itself: extension = Utils::FileSystem::getExtension(filePath); - // FYI, folders *can* also match the extension and be added as games. - // This is mostly just to support higan. - // See issue #75: https://github.com/Aloshi/EmulationStation/issues/75 - isGame = false; if (std::find(mEnvData->mSearchExtensions.cbegin(), mEnvData->mSearchExtensions.cend(), extension) != mEnvData->mSearchExtensions.cend()) { FileData* newGame = new FileData(GAME, filePath, mEnvData, this); + // If adding a configured file extension to a directory it will get interpreted as + // a regular file. This is useful for some emulators that can get directories passed + // to them as command line parameters instead of regular files. In these instances + // we remove the extension from the metadata name so it does not show up in the + // gamelists and similar. + if (Utils::FileSystem::isDirectory(filePath)) { + const std::string folderName = newGame->metadata.get("name"); + newGame->metadata.set( + "name", folderName.substr(0, folderName.length() - extension.length())); + } + // Prevent new arcade assets from being added. if (!newGame->isArcadeAsset()) { folder->addChild(newGame); diff --git a/es-app/src/guis/GuiGamelistOptions.cpp b/es-app/src/guis/GuiGamelistOptions.cpp index 8026eaf8e..a4ed3289c 100644 --- a/es-app/src/guis/GuiGamelistOptions.cpp +++ b/es-app/src/guis/GuiGamelistOptions.cpp @@ -385,6 +385,11 @@ void GuiGamelistOptions::openMetaDataEd() LOG(LogInfo) << "Deleting the media files and gamelist.xml entry for the folder \"" << file->getFullPath() << "\""; } + else if (file->getType() == GAME && Utils::FileSystem::isDirectory(file->getFullPath())) { + LOG(LogInfo) << "Deleting the media files and gamelist.xml entry for the " + "file-interpreted folder \"" + << file->getFullPath() << "\""; + } else { LOG(LogInfo) << "Deleting the media files and gamelist.xml entry for the file \"" << file->getFullPath() << "\""; @@ -408,6 +413,11 @@ void GuiGamelistOptions::openMetaDataEd() file->metadata.set(it->key, it->defaultValue); } + // For the special case where a directory has a supported file extension and is therefore + // interpreted as a file, don't include the extension in the metadata name. + if (file->getType() == GAME && Utils::FileSystem::isDirectory(file->getFullPath())) + file->metadata.set("name", Utils::FileSystem::getStem(file->metadata.get("name"))); + // Update all collections where the game is present. if (file->getType() == GAME) CollectionSystemsManager::get()->refreshCollectionSystems(file, true); diff --git a/es-app/src/guis/GuiMetaDataEd.cpp b/es-app/src/guis/GuiMetaDataEd.cpp index 99855a17e..4a4107499 100644 --- a/es-app/src/guis/GuiMetaDataEd.cpp +++ b/es-app/src/guis/GuiMetaDataEd.cpp @@ -429,11 +429,19 @@ GuiMetaDataEd::GuiMetaDataEd(Window* window, // If the user has entered a blank game name, then set the name to the ROM // filename (minus the extension). if (currentKey == "name" && newVal == "") { - if (scraperParams.game->isArcadeGame()) + if (scraperParams.game->isArcadeGame()) { ed->setValue(MameNames::getInstance().getCleanName( scraperParams.game->getCleanName())); - else - ed->setValue(gamePath); + } + else { + // For the special case where a directory has a supported file extension + // and is therefore interpreted as a file, exclude the extension. + if (scraperParams.game->getType() == GAME && + Utils::FileSystem::isDirectory(scraperParams.game->getFullPath())) + ed->setValue(Utils::FileSystem::getStem(gamePath)); + else + ed->setValue(gamePath); + } if (gamePath == originalValue) ed->setColor(DEFAULT_TEXTCOLOR); else @@ -546,7 +554,9 @@ GuiMetaDataEd::GuiMetaDataEd(Window* window, clearSelfBtnFunc)); } - if (mDeleteGameFunc) { + // For the special case where a directory has a supported file extension and is therefore + // interpreted as a file, don't add the delete button. + if (mDeleteGameFunc && !Utils::FileSystem::isDirectory(scraperParams.game->getPath())) { auto deleteFilesAndSelf = [&] { mDeleteGameFunc(); delete this; diff --git a/es-app/src/guis/GuiScraperSearch.cpp b/es-app/src/guis/GuiScraperSearch.cpp index 11dc8a009..831570556 100644 --- a/es-app/src/guis/GuiScraperSearch.cpp +++ b/es-app/src/guis/GuiScraperSearch.cpp @@ -823,10 +823,20 @@ void GuiScraperSearch::openInputScreen(ScraperSearchParams& params) // in case the scraper is set to TheGamesDB and it's an arcade game. This is // required as TheGamesDB does not support searches using the short MAME names. if (params.game->isArcadeGame() && - Settings::getInstance()->getString("Scraper") == "thegamesdb") + Settings::getInstance()->getString("Scraper") == "thegamesdb") { searchString = MameNames::getInstance().getCleanName(params.game->getCleanName()); - else - searchString = params.game->getCleanName(); + } + else { + if (params.game->getType() == GAME && + Utils::FileSystem::isDirectory(params.game->getFullPath())) { + // For the special case where a directory has a supported file extension and is + // therefore interpreted as a file, exclude the extension from the search. + searchString = Utils::FileSystem::getStem(params.game->getCleanName()); + } + else { + searchString = params.game->getCleanName(); + } + } } } else { diff --git a/es-app/src/scrapers/GamesDBJSONScraper.cpp b/es-app/src/scrapers/GamesDBJSONScraper.cpp index 1646464f3..bcd8f3772 100644 --- a/es-app/src/scrapers/GamesDBJSONScraper.cpp +++ b/es-app/src/scrapers/GamesDBJSONScraper.cpp @@ -156,10 +156,21 @@ void thegamesdb_generate_json_scraper_requests( // If not searching based on the metadata name, then check whether it's an // arcade game and if so expand to the full game name. This is required as // TheGamesDB has issues with searching using the short MAME names. - if (params.game->isArcadeGame()) + if (params.game->isArcadeGame()) { cleanName = MameNames::getInstance().getCleanName(params.game->getCleanName()); - else - cleanName = params.game->getCleanName(); + } + else { + if (params.game->getType() == GAME && + Utils::FileSystem::isDirectory(params.game->getFullPath())) { + // For the special case where a directory has a supported file extension + // and is therefore interpreted as a file, exclude the extension from the + // search. + cleanName = Utils::FileSystem::getStem(params.game->getCleanName()); + } + else { + cleanName = params.game->getCleanName(); + } + } } } diff --git a/es-app/src/scrapers/ScreenScraper.cpp b/es-app/src/scrapers/ScreenScraper.cpp index 0893470f6..231c26bd4 100644 --- a/es-app/src/scrapers/ScreenScraper.cpp +++ b/es-app/src/scrapers/ScreenScraper.cpp @@ -181,11 +181,24 @@ void screenscraper_generate_scraper_requests(const ScraperSearchParams& params, ssConfig.isArcadeSystem = false; if (params.nameOverride == "") { - if (Settings::getInstance()->getBool("ScraperSearchMetadataName")) + if (Settings::getInstance()->getBool("ScraperSearchMetadataName")) { path = ssConfig.getGameSearchUrl( Utils::String::removeParenthesis(params.game->metadata.get("name"))); - else - path = ssConfig.getGameSearchUrl(params.game->getCleanName()); + } + else { + std::string cleanName; + if (params.game->getType() == GAME && + Utils::FileSystem::isDirectory(params.game->getFullPath())) { + // For the special case where a directory has a supported file extension and is + // therefore interpreted as a file, exclude the extension from the search. + cleanName = Utils::FileSystem::getStem(params.game->getCleanName()); + } + else { + cleanName = params.game->getCleanName(); + } + + path = ssConfig.getGameSearchUrl(cleanName); + } } else { path = ssConfig.getGameSearchUrl(params.nameOverride);