System: Hash executable for game code when system.cnf missing
This commit is contained in:
parent
ac4dd11fa0
commit
6bbb1128b6
|
@ -32,6 +32,7 @@
|
|||
#include "spu.h"
|
||||
#include "texture_replacements.h"
|
||||
#include "timers.h"
|
||||
#include "xxhash.h"
|
||||
#include <cctype>
|
||||
#include <cinttypes>
|
||||
#include <cmath>
|
||||
|
@ -385,39 +386,57 @@ std::string_view GetTitleForPath(const char* path)
|
|||
return path_view.substr(0, path_view.find_last_of('.'));
|
||||
}
|
||||
|
||||
std::string GetGameCodeForPath(const char* image_path)
|
||||
std::string GetGameCodeForPath(const char* image_path, bool fallback_to_hash)
|
||||
{
|
||||
std::unique_ptr<CDImage> cdi = CDImage::Open(image_path);
|
||||
if (!cdi)
|
||||
return {};
|
||||
|
||||
return GetGameCodeForImage(cdi.get());
|
||||
return GetGameCodeForImage(cdi.get(), fallback_to_hash);
|
||||
}
|
||||
|
||||
std::string GetGameCodeForImage(CDImage* cdi)
|
||||
std::string GetGameCodeForImage(CDImage* cdi, bool fallback_to_hash)
|
||||
{
|
||||
std::string code(GetExecutableNameForImage(cdi));
|
||||
if (code.empty())
|
||||
return {};
|
||||
|
||||
// SCES_123.45 -> SCES-12345
|
||||
for (std::string::size_type pos = 0; pos < code.size();)
|
||||
if (!code.empty())
|
||||
{
|
||||
if (code[pos] == '.')
|
||||
// SCES_123.45 -> SCES-12345
|
||||
for (std::string::size_type pos = 0; pos < code.size();)
|
||||
{
|
||||
code.erase(pos, 1);
|
||||
continue;
|
||||
if (code[pos] == '.')
|
||||
{
|
||||
code.erase(pos, 1);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (code[pos] == '_')
|
||||
code[pos] = '-';
|
||||
else
|
||||
code[pos] = static_cast<char>(std::toupper(code[pos]));
|
||||
|
||||
pos++;
|
||||
}
|
||||
|
||||
if (code[pos] == '_')
|
||||
code[pos] = '-';
|
||||
else
|
||||
code[pos] = static_cast<char>(std::toupper(code[pos]));
|
||||
|
||||
pos++;
|
||||
return code;
|
||||
}
|
||||
|
||||
return code;
|
||||
if (!fallback_to_hash)
|
||||
return {};
|
||||
|
||||
std::string exe_name;
|
||||
std::vector<u8> exe_buffer;
|
||||
if (!ReadExecutableFromImage(cdi, &exe_name, &exe_buffer))
|
||||
return {};
|
||||
|
||||
XXH64_state_t* state = XXH64_createState();
|
||||
XXH64_reset(state, 0x4242D00C);
|
||||
XXH64_update(state, exe_name.c_str(), exe_name.size());
|
||||
XXH64_update(state, exe_buffer.data(), exe_buffer.size());
|
||||
const u64 hash = XXH64_digest(state);
|
||||
XXH64_freeState(state);
|
||||
|
||||
Log_InfoPrintf("Hash for '%s' - %" PRIX64, exe_name.c_str(), hash);
|
||||
return StringUtil::StdStringFromFormat("HASH-%" PRIX64, hash);
|
||||
}
|
||||
|
||||
static std::string GetExecutableNameForImage(CDImage* cdi, ISOReader& iso, bool strip_subdirectories)
|
||||
|
@ -601,7 +620,7 @@ DiscRegion GetRegionForImage(CDImage* cdi)
|
|||
if (system_area_region != DiscRegion::Other)
|
||||
return system_area_region;
|
||||
|
||||
std::string code = GetGameCodeForImage(cdi);
|
||||
std::string code = GetGameCodeForImage(cdi, false);
|
||||
if (code.empty())
|
||||
return DiscRegion::Other;
|
||||
|
||||
|
|
|
@ -78,8 +78,8 @@ ConsoleRegion GetConsoleRegionForDiscRegion(DiscRegion region);
|
|||
std::string GetExecutableNameForImage(CDImage* cdi);
|
||||
bool ReadExecutableFromImage(CDImage* cdi, std::string* out_executable_name, std::vector<u8>* out_executable_data);
|
||||
|
||||
std::string GetGameCodeForImage(CDImage* cdi);
|
||||
std::string GetGameCodeForPath(const char* image_path);
|
||||
std::string GetGameCodeForImage(CDImage* cdi, bool fallback_to_hash);
|
||||
std::string GetGameCodeForPath(const char* image_path, bool fallback_to_hash);
|
||||
DiscRegion GetRegionForCode(std::string_view code);
|
||||
DiscRegion GetRegionFromSystemArea(CDImage* cdi);
|
||||
DiscRegion GetRegionForImage(CDImage* cdi);
|
||||
|
|
|
@ -415,7 +415,7 @@ bool CommonHostInterface::ParseCommandLineParameters(int argc, char* argv[],
|
|||
else
|
||||
{
|
||||
// find the game id, and get its save state path
|
||||
std::string game_code = System::GetGameCodeForPath(boot_filename.c_str());
|
||||
std::string game_code = System::GetGameCodeForPath(boot_filename.c_str(), true);
|
||||
if (game_code.empty())
|
||||
{
|
||||
Log_WarningPrintf("Could not identify game code for '%s', cannot load save state %d.", boot_filename.c_str(),
|
||||
|
@ -2867,7 +2867,7 @@ void CommonHostInterface::GetGameInfo(const char* path, CDImage* image, std::str
|
|||
else
|
||||
{
|
||||
if (image)
|
||||
*code = System::GetGameCodeForImage(image);
|
||||
*code = System::GetGameCodeForImage(image, true);
|
||||
|
||||
const GameListDatabaseEntry* db_entry = (!code->empty()) ? m_game_list->GetDatabaseEntryForCode(*code) : nullptr;
|
||||
if (db_entry)
|
||||
|
|
|
@ -181,7 +181,7 @@ bool GameList::GetM3UListEntry(const char* path, GameListEntry* entry)
|
|||
|
||||
if (entry->compatibility_rating == GameListCompatibilityRating::Unknown)
|
||||
{
|
||||
std::string code = System::GetGameCodeForImage(entry_image.get());
|
||||
std::string code = System::GetGameCodeForImage(entry_image.get(), true);
|
||||
const GameListCompatibilityEntry* compatibility_entry = GetCompatibilityEntryForCode(entry->code);
|
||||
if (compatibility_entry)
|
||||
entry->compatibility_rating = compatibility_entry->compatibility_rating;
|
||||
|
@ -206,7 +206,7 @@ bool GameList::GetGameListEntry(const std::string& path, GameListEntry* entry)
|
|||
if (!cdi)
|
||||
return false;
|
||||
|
||||
std::string code = System::GetGameCodeForImage(cdi.get());
|
||||
std::string code = System::GetGameCodeForImage(cdi.get(), true);
|
||||
DiscRegion region = System::GetRegionFromSystemArea(cdi.get());
|
||||
if (region == DiscRegion::Other)
|
||||
region = System::GetRegionForCode(code);
|
||||
|
|
Loading…
Reference in New Issue