mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-01-09 23:59:27 +01:00
Don't show "extra" files from DirectoryBlobs in game list
For instance, we don't want to show TGC files that might be inside the /files/ directory of a GameCube DirectoryBlob, and we don't want to show the /sys/main.dol files for extra partitions of Wii DirectoryBlobs.
This commit is contained in:
parent
1ea44f425d
commit
5fe3745750
@ -150,15 +150,20 @@ static std::optional<PartitionType> ParsePartitionDirectoryName(const std::strin
|
||||
return {};
|
||||
}
|
||||
|
||||
static bool PathCharactersEqual(char a, char b)
|
||||
static bool IsDirectorySeparator(char c)
|
||||
{
|
||||
return a == b
|
||||
return c == '/'
|
||||
#ifdef _WIN32
|
||||
|| (a == '/' && b == '\\') || (a == '\\' && b == '/')
|
||||
|| c == '\\'
|
||||
#endif
|
||||
;
|
||||
}
|
||||
|
||||
static bool PathCharactersEqual(char a, char b)
|
||||
{
|
||||
return a == b || (IsDirectorySeparator(a) && IsDirectorySeparator(b));
|
||||
}
|
||||
|
||||
static bool PathEndsWith(const std::string& path, const std::string& suffix)
|
||||
{
|
||||
if (suffix.size() > path.size())
|
||||
@ -178,7 +183,7 @@ static bool PathEndsWith(const std::string& path, const std::string& suffix)
|
||||
}
|
||||
|
||||
static bool IsValidDirectoryBlob(const std::string& dol_path, std::string* partition_root,
|
||||
std::string* true_root)
|
||||
std::string* true_root = nullptr)
|
||||
{
|
||||
if (!PathEndsWith(dol_path, "/sys/main.dol"))
|
||||
return false;
|
||||
@ -194,12 +199,75 @@ static bool IsValidDirectoryBlob(const std::string& dol_path, std::string* parti
|
||||
#else
|
||||
constexpr char dir_separator = '/';
|
||||
#endif
|
||||
const size_t true_root_end = dol_path.find_last_of(dir_separator, partition_root->size() - 2) + 1;
|
||||
*true_root = dol_path.substr(0, true_root_end);
|
||||
if (true_root)
|
||||
{
|
||||
*true_root =
|
||||
dol_path.substr(0, dol_path.find_last_of(dir_separator, partition_root->size() - 2) + 1);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool ExistsAndIsValidDirectoryBlob(const std::string& dol_path)
|
||||
{
|
||||
std::string partition_root;
|
||||
return File::Exists(dol_path) && IsValidDirectoryBlob(dol_path, &partition_root);
|
||||
}
|
||||
|
||||
static bool IsInFilesDirectory(const std::string& path)
|
||||
{
|
||||
size_t files_pos = std::string::npos;
|
||||
while (true)
|
||||
{
|
||||
files_pos = path.rfind("files", files_pos);
|
||||
if (files_pos == std::string::npos)
|
||||
return false;
|
||||
|
||||
const size_t slash_before_pos = files_pos - 1;
|
||||
const size_t slash_after_pos = files_pos + 5;
|
||||
if ((files_pos == 0 || IsDirectorySeparator(path[slash_before_pos])) &&
|
||||
(slash_after_pos == path.size() || (IsDirectorySeparator(path[slash_after_pos]))) &&
|
||||
ExistsAndIsValidDirectoryBlob(path.substr(0, files_pos) + "sys/main.dol"))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
--files_pos;
|
||||
}
|
||||
}
|
||||
|
||||
static bool IsMainDolForNonGamePartition(const std::string& path)
|
||||
{
|
||||
std::string partition_root, true_root;
|
||||
if (!IsValidDirectoryBlob(path, &partition_root, &true_root))
|
||||
return false; // This is not a /sys/main.dol
|
||||
|
||||
std::string partition_directory_name = partition_root.substr(true_root.size());
|
||||
partition_directory_name.pop_back(); // Remove trailing slash
|
||||
const std::optional<PartitionType> partition_type =
|
||||
ParsePartitionDirectoryName(partition_directory_name);
|
||||
if (!partition_type || *partition_type == PartitionType::Game)
|
||||
return false; // volume_path is the game partition's /sys/main.dol
|
||||
|
||||
const File::FSTEntry true_root_entry = File::ScanDirectoryTree(true_root, false);
|
||||
for (const File::FSTEntry& entry : true_root_entry.children)
|
||||
{
|
||||
if (entry.isDirectory &&
|
||||
ParsePartitionDirectoryName(entry.virtualName) == PartitionType::Game &&
|
||||
ExistsAndIsValidDirectoryBlob(entry.physicalName + "/sys/main.dol"))
|
||||
{
|
||||
return true; // volume_path is the /sys/main.dol for a non-game partition
|
||||
}
|
||||
}
|
||||
|
||||
return false; // volume_path is the game partition's /sys/main.dol
|
||||
}
|
||||
|
||||
bool ShouldHideFromGameList(const std::string& volume_path)
|
||||
{
|
||||
return IsInFilesDirectory(volume_path) || IsMainDolForNonGamePartition(volume_path);
|
||||
}
|
||||
|
||||
std::unique_ptr<DirectoryBlobReader> DirectoryBlobReader::Create(const std::string& dol_path)
|
||||
{
|
||||
std::string partition_root, true_root;
|
||||
|
@ -27,6 +27,9 @@ namespace DiscIO
|
||||
{
|
||||
enum class PartitionType : u32;
|
||||
|
||||
// Returns true if the path is inside a DirectoryBlob and doesn't represent the DirectoryBlob itself
|
||||
bool ShouldHideFromGameList(const std::string& volume_path);
|
||||
|
||||
class DiscContent
|
||||
{
|
||||
public:
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include <QDirIterator>
|
||||
#include <QFile>
|
||||
|
||||
#include "DiscIO/DirectoryBlob.h"
|
||||
#include "DolphinQt2/GameList/GameTracker.h"
|
||||
#include "DolphinQt2/Settings.h"
|
||||
|
||||
@ -137,3 +138,13 @@ void GameTracker::UpdateFile(const QString& file)
|
||||
emit GameRemoved(file);
|
||||
}
|
||||
}
|
||||
|
||||
void GameLoader::LoadGame(const QString& path)
|
||||
{
|
||||
if (!DiscIO::ShouldHideFromGameList(path.toStdString()))
|
||||
{
|
||||
GameFile* game = new GameFile(path);
|
||||
if (game->IsValid())
|
||||
emit GameLoaded(QSharedPointer<GameFile>(game));
|
||||
}
|
||||
}
|
||||
|
@ -54,12 +54,7 @@ class GameLoader final : public QObject
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
void LoadGame(const QString& path)
|
||||
{
|
||||
GameFile* game = new GameFile(path);
|
||||
if (game->IsValid())
|
||||
emit GameLoaded(QSharedPointer<GameFile>(game));
|
||||
}
|
||||
void LoadGame(const QString& path);
|
||||
|
||||
signals:
|
||||
void GameLoaded(QSharedPointer<GameFile> game);
|
||||
|
@ -53,6 +53,7 @@
|
||||
#include "Core/Movie.h"
|
||||
#include "Core/TitleDatabase.h"
|
||||
#include "DiscIO/Blob.h"
|
||||
#include "DiscIO/DirectoryBlob.h"
|
||||
#include "DiscIO/Enums.h"
|
||||
#include "DiscIO/Volume.h"
|
||||
#include "DolphinWX/Frame.h"
|
||||
@ -761,6 +762,12 @@ void GameListCtrl::RescanList()
|
||||
auto search_results = Common::DoFileSearch(SConfig::GetInstance().m_ISOFolder, search_extensions,
|
||||
SConfig::GetInstance().m_RecursiveISOFolder);
|
||||
|
||||
// TODO Prevent DoFileSearch from looking inside /files/ directories of DirectoryBlobs at all?
|
||||
// TODO Make DoFileSearch support filter predicates so we don't have remove things afterwards?
|
||||
search_results.erase(
|
||||
std::remove_if(search_results.begin(), search_results.end(), DiscIO::ShouldHideFromGameList),
|
||||
search_results.end());
|
||||
|
||||
std::vector<std::string> cached_paths;
|
||||
for (const auto& file : m_cached_files)
|
||||
cached_paths.emplace_back(file->GetFileName());
|
||||
|
Loading…
x
Reference in New Issue
Block a user