Achievements: Simplify hash-to-string routine

pull/3566/head
Stenzek 1 month ago
parent fe09b5d16f
commit 56665d64af
No known key found for this signature in database

@ -153,7 +153,7 @@ struct PauseMenuTimedMeasuredAchievementInfo : PauseMenuMeasuredAchievementInfo
} // namespace
static TinyString GameHashToString(const GameHash& hash);
static TinyString GameHashToString(const std::optional<GameHash>& hash);
static void ReportError(std::string_view sv);
template<typename... T>
@ -334,12 +334,24 @@ ALIGN_TO_CACHE_LINE static State s_state;
} // namespace Achievements
TinyString Achievements::GameHashToString(const GameHash& hash)
TinyString Achievements::GameHashToString(const std::optional<GameHash>& hash)
{
return TinyString::from_format(
"{:02x}{:02x}{:02x}{:02x}{:02x}{:02x}{:02x}{:02x}{:02x}{:02x}{:02x}{:02x}{:02x}{:02x}{:02x}{:02x}", hash[0],
hash[1], hash[2], hash[3], hash[4], hash[5], hash[6], hash[7], hash[8], hash[9], hash[10], hash[11], hash[12],
hash[13], hash[14], hash[15]);
TinyString ret;
// Use a hash that will never match if we removed the disc. See rc_client_begin_change_media().
if (!hash.has_value())
{
ret = "[NO HASH]";
}
else
{
ret.format("{:02x}{:02x}{:02x}{:02x}{:02x}{:02x}{:02x}{:02x}{:02x}{:02x}{:02x}{:02x}{:02x}{:02x}{:02x}{:02x}",
hash.value()[0], hash.value()[1], hash.value()[2], hash.value()[3], hash.value()[4], hash.value()[5],
hash.value()[6], hash.value()[7], hash.value()[8], hash.value()[9], hash.value()[10], hash.value()[11],
hash.value()[12], hash.value()[13], hash.value()[14], hash.value()[15]);
}
return ret;
}
std::unique_lock<std::recursive_mutex> Achievements::GetLock()
@ -380,7 +392,7 @@ void Achievements::ReportRCError(int err, fmt::format_string<T...> fmt, T&&... a
ReportError(str);
}
std::optional<Achievements::GameHash> Achievements::GetGameHash(CDImage* image, u32* bytes_hashed)
std::optional<Achievements::GameHash> Achievements::GetGameHash(CDImage* image)
{
std::optional<GameHash> ret;
@ -389,12 +401,11 @@ std::optional<Achievements::GameHash> Achievements::GetGameHash(CDImage* image,
if (!System::ReadExecutableFromImage(image, &executable_name, &executable_data))
return ret;
return GetGameHash(executable_name, executable_data, bytes_hashed);
return GetGameHash(executable_name, executable_data);
}
std::optional<Achievements::GameHash> Achievements::GetGameHash(const std::string_view executable_name,
std::span<const u8> executable_data,
u32* bytes_hashed /* = nullptr */)
std::span<const u8> executable_data)
{
std::optional<GameHash> ret;
@ -413,11 +424,11 @@ std::optional<Achievements::GameHash> Achievements::GetGameHash(const std::strin
if (hash_size > 0)
digest.Update(executable_data.data(), hash_size);
ret = GameHash();
ret.emplace();
digest.Final(ret.value());
if (bytes_hashed)
*bytes_hashed = hash_size;
INFO_COLOR_LOG(StrongOrange, "RA Hash for '{}': {} ({} bytes hashed)", executable_name, GameHashToString(ret),
hash_size);
return ret;
}
@ -1169,36 +1180,24 @@ void Achievements::GameChanged(CDImage* image)
s_state.load_game_request = nullptr;
}
// Use a hash that will never match if we removed the disc. See rc_client_begin_change_media().
TinyString game_hash_str;
if (s_state.game_hash.has_value())
game_hash_str = GameHashToString(s_state.game_hash.value());
else
game_hash_str = "[NO HASH]";
s_state.load_game_request = rc_client_begin_change_media_from_hash(
s_state.client, game_hash_str.c_str(), ClientLoadGameCallback, reinterpret_cast<void*>(static_cast<uintptr_t>(1)));
s_state.load_game_request =
rc_client_begin_change_media_from_hash(s_state.client, GameHashToString(s_state.game_hash).c_str(),
ClientLoadGameCallback, reinterpret_cast<void*>(static_cast<uintptr_t>(1)));
}
bool Achievements::IdentifyGame(CDImage* image)
{
std::optional<GameHash> game_hash;
if (image)
game_hash = GetGameHash(image);
if (!game_hash.has_value() && !rc_client_is_game_loaded(s_state.client))
{
u32 bytes_hashed;
game_hash = GetGameHash(image, &bytes_hashed);
if (game_hash.has_value())
{
INFO_COLOR_LOG(StrongOrange, "RA Hash: {} ({} bytes hashed)", GameHashToString(game_hash.value()), bytes_hashed);
}
else
{
// If we are starting with this game and it's bad, notify the user that this is why.
Host::AddIconOSDWarning(
"AchievementsHashFailed", ICON_EMOJI_WARNING,
TRANSLATE_STR("Achievements", "Failed to read executable from disc. Achievements disabled."),
Host::OSD_ERROR_DURATION);
}
// If we are starting with this game and it's bad, notify the user that this is why.
Host::AddIconOSDWarning(
"AchievementsHashFailed", ICON_EMOJI_WARNING,
TRANSLATE_STR("Achievements", "Failed to read executable from disc. Achievements disabled."),
Host::OSD_ERROR_DURATION);
}
s_state.game_path = image ? image->GetPath() : std::string();
@ -1240,7 +1239,7 @@ void Achievements::BeginLoadGame()
return;
}
s_state.load_game_request = rc_client_begin_load_game(s_state.client, GameHashToString(s_state.game_hash.value()),
s_state.load_game_request = rc_client_begin_load_game(s_state.client, GameHashToString(s_state.game_hash).c_str(),
ClientLoadGameCallback, nullptr);
}
@ -1253,7 +1252,7 @@ void Achievements::ClientLoadGameCallback(int result, const char* error_message,
if (result == RC_NO_GAME_LOADED)
{
// Unknown game.
INFO_LOG("Unknown game '{}', disabling achievements.", GameHashToString(s_state.game_hash.value_or(GameHash{})));
INFO_LOG("Unknown game '{}', disabling achievements.", GameHashToString(s_state.game_hash));
if (was_disc_change)
ClearGameInfo();
@ -2592,7 +2591,8 @@ void Achievements::DrawPauseMenuOverlays(float start_pos_y)
const float box_content_width = box_width - box_padding - box_padding;
const float box_rounding = LayoutScale(20.0f);
const u32 box_background_color = ImGui::GetColorU32(ModAlpha(UIStyle.BackgroundColor, 0.8f));
const ImU32 box_title_text_color = ImGui::GetColorU32(DarkerColor(UIStyle.BackgroundTextColor, 0.9f)) | IM_COL32_A_MASK;
const ImU32 box_title_text_color =
ImGui::GetColorU32(DarkerColor(UIStyle.BackgroundTextColor, 0.9f)) | IM_COL32_A_MASK;
const ImU32 title_text_color = ImGui::GetColorU32(UIStyle.BackgroundTextColor) | IM_COL32_A_MASK;
const ImU32 text_color =
ImGui::GetColorU32(DarkerColor(DarkerColor(UIStyle.BackgroundTextColor, 0.9f))) | IM_COL32_A_MASK;

@ -64,9 +64,8 @@ private:
std::unique_lock<std::recursive_mutex> GetLock();
/// Returns the achievements game hash for a given disc.
std::optional<GameHash> GetGameHash(CDImage* image, u32* bytes_hashed = nullptr);
std::optional<GameHash> GetGameHash(const std::string_view executable_name, std::span<const u8> executable_data,
u32* bytes_hashed = nullptr);
std::optional<GameHash> GetGameHash(CDImage* image);
std::optional<GameHash> GetGameHash(const std::string_view executable_name, std::span<const u8> executable_data);
/// Returns the number of achievements for a given hash.
const HashDatabaseEntry* LookupGameHash(const GameHash& hash);

Loading…
Cancel
Save