diff --git a/Source/Core/Core/AchievementManager.cpp b/Source/Core/Core/AchievementManager.cpp index a40f4aaeb5..fca4cdd5c7 100644 --- a/Source/Core/Core/AchievementManager.cpp +++ b/Source/Core/Core/AchievementManager.cpp @@ -28,6 +28,7 @@ #include "Core/Config/AchievementSettings.h" #include "Core/Config/FreeLookSettings.h" #include "Core/Config/MainSettings.h" +#include "Core/ConfigLoaders/GameConfigLoader.h" #include "Core/Core.h" #include "Core/GeckoCode.h" #include "Core/HW/Memmap.h" @@ -386,8 +387,8 @@ bool AchievementManager::IsHardcoreModeActive() const } template -void AchievementManager::FilterApprovedIni(std::vector& codes, - const std::string& game_ini_id) const +void AchievementManager::FilterApprovedIni(std::vector& codes, const std::string& game_id, + u16 revision) const { if (codes.empty()) { @@ -409,13 +410,14 @@ void AchievementManager::FilterApprovedIni(std::vector& codes, for (auto& code : codes) { - if (code.enabled && !CheckApprovedCode(code, game_ini_id)) + if (code.enabled && !CheckApprovedCode(code, game_id, revision)) code.enabled = false; } } template -bool AchievementManager::CheckApprovedCode(const T& code, const std::string& game_ini_id) const +bool AchievementManager::CheckApprovedCode(const T& code, const std::string& game_id, + u16 revision) const { if (!IsHardcoreModeActive()) return true; @@ -424,22 +426,22 @@ bool AchievementManager::CheckApprovedCode(const T& code, const std::string& gam if (!m_ini_root->is()) return false; - const bool known_id = m_ini_root->contains(game_ini_id); - INFO_LOG_FMT(ACHIEVEMENTS, "Verifying code {}", code.name); bool verified = false; - if (known_id) - { - auto digest = GetCodeHash(code); + auto hash = Common::SHA1::DigestToString(GetCodeHash(code)); - verified = m_ini_root->get(game_ini_id).contains(Common::SHA1::DigestToString(digest)); + for (const std::string& filename : ConfigLoaders::GetGameIniFilenames(game_id, revision)) + { + auto config = filename.substr(0, filename.length() - 4); + if (m_ini_root->contains(config) && m_ini_root->get(config).contains(hash)) + verified = true; } if (!verified) { - OSD::AddMessage(fmt::format("Failed to verify code {} from file {}.", code.name, game_ini_id), + OSD::AddMessage(fmt::format("Failed to verify code {} for game ID {}.", code.name, game_id), OSD::Duration::VERY_LONG, OSD::Color::RED); OSD::AddMessage("Disable hardcore mode to enable this code.", OSD::Duration::VERY_LONG, OSD::Color::RED); @@ -487,33 +489,33 @@ Common::SHA1::Digest AchievementManager::GetCodeHash(const ActionReplay::ARCode& } void AchievementManager::FilterApprovedPatches(std::vector& patches, - const std::string& game_ini_id) const + const std::string& game_id, u16 revision) const { - FilterApprovedIni(patches, game_ini_id); + FilterApprovedIni(patches, game_id, revision); } void AchievementManager::FilterApprovedGeckoCodes(std::vector& codes, - const std::string& game_ini_id) const + const std::string& game_id, u16 revision) const { - FilterApprovedIni(codes, game_ini_id); + FilterApprovedIni(codes, game_id, revision); } void AchievementManager::FilterApprovedARCodes(std::vector& codes, - const std::string& game_ini_id) const + const std::string& game_id, u16 revision) const { - FilterApprovedIni(codes, game_ini_id); + FilterApprovedIni(codes, game_id, revision); } bool AchievementManager::CheckApprovedGeckoCode(const Gecko::GeckoCode& code, - const std::string& game_ini_id) const + const std::string& game_id, u16 revision) const { - return CheckApprovedCode(code, game_ini_id); + return CheckApprovedCode(code, game_id, revision); } bool AchievementManager::CheckApprovedARCode(const ActionReplay::ARCode& code, - const std::string& game_ini_id) const + const std::string& game_id, u16 revision) const { - return CheckApprovedCode(code, game_ini_id); + return CheckApprovedCode(code, game_id, revision); } void AchievementManager::SetSpectatorMode() diff --git a/Source/Core/Core/AchievementManager.h b/Source/Core/Core/AchievementManager.h index aad6ba9561..f46b7e9da3 100644 --- a/Source/Core/Core/AchievementManager.h +++ b/Source/Core/Core/AchievementManager.h @@ -133,16 +133,17 @@ public: std::recursive_mutex& GetLock(); bool IsHardcoreModeActive() const; - void SetGameIniId(const std::string& game_ini_id) { m_game_ini_id = game_ini_id; } - void FilterApprovedPatches(std::vector& patches, - const std::string& game_ini_id) const; - void FilterApprovedGeckoCodes(std::vector& codes, - const std::string& game_ini_id) const; - void FilterApprovedARCodes(std::vector& codes, - const std::string& game_ini_id) const; - bool CheckApprovedGeckoCode(const Gecko::GeckoCode& code, const std::string& game_ini_id) const; - bool CheckApprovedARCode(const ActionReplay::ARCode& code, const std::string& game_ini_id) const; + void FilterApprovedPatches(std::vector& patches, const std::string& game_id, + u16 revision) const; + void FilterApprovedGeckoCodes(std::vector& codes, const std::string& game_id, + u16 revision) const; + void FilterApprovedARCodes(std::vector& codes, const std::string& game_id, + u16 revision) const; + bool CheckApprovedGeckoCode(const Gecko::GeckoCode& code, const std::string& game_id, + u16 revision) const; + bool CheckApprovedARCode(const ActionReplay::ARCode& code, const std::string& game_id, + u16 revision) const; void SetSpectatorMode(); std::string_view GetPlayerDisplayName() const; @@ -201,9 +202,9 @@ private: void SetHardcoreMode(); template - void FilterApprovedIni(std::vector& codes, const std::string& game_ini_id) const; + void FilterApprovedIni(std::vector& codes, const std::string& game_id, u16 revision) const; template - bool CheckApprovedCode(const T& code, const std::string& game_ini_id) const; + bool CheckApprovedCode(const T& code, const std::string& game_id, u16 revision) const; Common::SHA1::Digest GetCodeHash(const PatchEngine::Patch& patch) const; Common::SHA1::Digest GetCodeHash(const Gecko::GeckoCode& code) const; Common::SHA1::Digest GetCodeHash(const ActionReplay::ARCode& code) const; @@ -259,7 +260,6 @@ private: std::chrono::steady_clock::time_point m_last_progress_message = std::chrono::steady_clock::now(); Common::Lazy m_ini_root{LoadApprovedList}; - std::string m_game_ini_id; std::unordered_map m_leaderboard_map; bool m_challenges_updated = false; @@ -302,14 +302,12 @@ public: constexpr bool IsHardcoreModeActive() { return false; } - constexpr bool CheckApprovedGeckoCode(const Gecko::GeckoCode& code, - const std::string& game_ini_id) + constexpr bool CheckApprovedGeckoCode(const Gecko::GeckoCode& code, const std::string& game_id) { return true; }; - constexpr bool CheckApprovedARCode(const ActionReplay::ARCode& code, - const std::string& game_ini_id) + constexpr bool CheckApprovedARCode(const ActionReplay::ARCode& code, const std::string& game_id) { return true; }; diff --git a/Source/Core/Core/ActionReplay.cpp b/Source/Core/Core/ActionReplay.cpp index d3171cdd25..4b309fd5a6 100644 --- a/Source/Core/Core/ActionReplay.cpp +++ b/Source/Core/Core/ActionReplay.cpp @@ -113,7 +113,7 @@ struct ARAddr // ---------------------- // AR Remote Functions -void ApplyCodes(std::span codes, const std::string& game_id) +void ApplyCodes(std::span codes, const std::string& game_id, u16 revision) { if (!Config::AreCheatsEnabled()) return; @@ -122,9 +122,9 @@ void ApplyCodes(std::span codes, const std::string& game_id) s_disable_logging = false; s_active_codes.clear(); std::copy_if(codes.begin(), codes.end(), std::back_inserter(s_active_codes), - [&game_id](const ARCode& code) { - return code.enabled && - AchievementManager::GetInstance().CheckApprovedARCode(code, game_id); + [&game_id, &revision](const ARCode& code) { + return code.enabled && AchievementManager::GetInstance().CheckApprovedARCode( + code, game_id, revision); }); s_active_codes.shrink_to_fit(); } @@ -174,9 +174,9 @@ void AddCode(ARCode code) } void LoadAndApplyCodes(const Common::IniFile& global_ini, const Common::IniFile& local_ini, - const std::string& game_id) + const std::string& game_id, u16 revision) { - ApplyCodes(LoadCodes(global_ini, local_ini), game_id); + ApplyCodes(LoadCodes(global_ini, local_ini), game_id, revision); } // Parses the Action Replay section of a game ini file. diff --git a/Source/Core/Core/ActionReplay.h b/Source/Core/Core/ActionReplay.h index 1cfbb0a1fe..104b3a6c6e 100644 --- a/Source/Core/Core/ActionReplay.h +++ b/Source/Core/Core/ActionReplay.h @@ -45,13 +45,13 @@ struct ARCode void RunAllActive(const Core::CPUThreadGuard& cpu_guard); -void ApplyCodes(std::span codes, const std::string& game_id); +void ApplyCodes(std::span codes, const std::string& game_id, u16 revision); void SetSyncedCodesAsActive(); void UpdateSyncedCodes(std::span codes); std::vector ApplyAndReturnCodes(std::span codes); void AddCode(ARCode new_code); void LoadAndApplyCodes(const Common::IniFile& global_ini, const Common::IniFile& local_ini, - const std::string& game_id); + const std::string& game_id, u16 revision); std::vector LoadCodes(const Common::IniFile& global_ini, const Common::IniFile& local_ini); void SaveCodes(Common::IniFile* local_ini, std::span codes); diff --git a/Source/Core/Core/GeckoCode.cpp b/Source/Core/Core/GeckoCode.cpp index 0d43c5a507..62d2dc5481 100644 --- a/Source/Core/Core/GeckoCode.cpp +++ b/Source/Core/Core/GeckoCode.cpp @@ -50,7 +50,7 @@ static std::vector s_active_codes; static std::vector s_synced_codes; static std::mutex s_active_codes_lock; -void SetActiveCodes(std::span gcodes, const std::string& game_id) +void SetActiveCodes(std::span gcodes, const std::string& game_id, u16 revision) { std::lock_guard lk(s_active_codes_lock); @@ -60,9 +60,9 @@ void SetActiveCodes(std::span gcodes, const std::string& game_i s_active_codes.reserve(gcodes.size()); std::copy_if(gcodes.begin(), gcodes.end(), std::back_inserter(s_active_codes), - [&game_id](const GeckoCode& code) { - return code.enabled && - AchievementManager::GetInstance().CheckApprovedGeckoCode(code, game_id); + [&game_id, &revision](const GeckoCode& code) { + return code.enabled && AchievementManager::GetInstance().CheckApprovedGeckoCode( + code, game_id, revision); }); } s_active_codes.shrink_to_fit(); diff --git a/Source/Core/Core/GeckoCode.h b/Source/Core/Core/GeckoCode.h index 2931ed3641..0746db0d21 100644 --- a/Source/Core/Core/GeckoCode.h +++ b/Source/Core/Core/GeckoCode.h @@ -60,7 +60,7 @@ constexpr u32 HLE_TRAMPOLINE_ADDRESS = INSTALLER_END_ADDRESS - 4; // preserve the emulation performance. constexpr u32 MAGIC_GAMEID = 0xD01F1BAD; -void SetActiveCodes(std::span gcodes, const std::string& game_id); +void SetActiveCodes(std::span gcodes, const std::string& game_id, u16 revision); void SetSyncedCodesAsActive(); void UpdateSyncedCodes(std::span gcodes); std::vector SetAndReturnActiveCodes(std::span gcodes); diff --git a/Source/Core/Core/NetPlayServer.cpp b/Source/Core/Core/NetPlayServer.cpp index cf21adfdc4..7d910d54c8 100644 --- a/Source/Core/Core/NetPlayServer.cpp +++ b/Source/Core/Core/NetPlayServer.cpp @@ -2075,7 +2075,7 @@ bool NetPlayServer::SyncCodes() std::vector codes = Gecko::LoadCodes(globalIni, localIni); #ifdef USE_RETRO_ACHIEVEMENTS - AchievementManager::GetInstance().FilterApprovedGeckoCodes(codes, game_id); + AchievementManager::GetInstance().FilterApprovedGeckoCodes(codes, game_id, revision); #endif // USE_RETRO_ACHIEVEMENTS // Create a Gecko Code Vector with just the active codes @@ -2129,7 +2129,7 @@ bool NetPlayServer::SyncCodes() { std::vector codes = ActionReplay::LoadCodes(globalIni, localIni); #ifdef USE_RETRO_ACHIEVEMENTS - AchievementManager::GetInstance().FilterApprovedARCodes(codes, game_id); + AchievementManager::GetInstance().FilterApprovedARCodes(codes, game_id, revision); #endif // USE_RETRO_ACHIEVEMENTS // Create an AR Code Vector with just the active codes std::vector active_codes = ActionReplay::ApplyAndReturnCodes(codes); diff --git a/Source/Core/Core/PatchEngine.cpp b/Source/Core/Core/PatchEngine.cpp index b69368336b..65765c44e0 100644 --- a/Source/Core/Core/PatchEngine.cpp +++ b/Source/Core/Core/PatchEngine.cpp @@ -183,7 +183,8 @@ void LoadPatches() LoadPatchSection("OnFrame", &s_on_frame, globalIni, localIni); #ifdef USE_RETRO_ACHIEVEMENTS - AchievementManager::GetInstance().FilterApprovedPatches(s_on_frame, sconfig.GetGameID()); + AchievementManager::GetInstance().FilterApprovedPatches(s_on_frame, sconfig.GetGameID(), + sconfig.GetRevision()); #endif // USE_RETRO_ACHIEVEMENTS // Check if I'm syncing Codes @@ -194,8 +195,10 @@ void LoadPatches() } else { - Gecko::SetActiveCodes(Gecko::LoadCodes(globalIni, localIni), sconfig.GetGameID()); - ActionReplay::LoadAndApplyCodes(globalIni, localIni, sconfig.GetGameID()); + Gecko::SetActiveCodes(Gecko::LoadCodes(globalIni, localIni), sconfig.GetGameID(), + sconfig.GetRevision()); + ActionReplay::LoadAndApplyCodes(globalIni, localIni, sconfig.GetGameID(), + sconfig.GetRevision()); } } @@ -340,7 +343,7 @@ bool ApplyFramePatches(Core::System& system) void Shutdown() { s_on_frame.clear(); - ActionReplay::ApplyCodes({}, ""); + ActionReplay::ApplyCodes({}, "", 0); Gecko::Shutdown(); } diff --git a/Source/Core/DolphinQt/Config/ARCodeWidget.cpp b/Source/Core/DolphinQt/Config/ARCodeWidget.cpp index 5089e98806..f73017d723 100644 --- a/Source/Core/DolphinQt/Config/ARCodeWidget.cpp +++ b/Source/Core/DolphinQt/Config/ARCodeWidget.cpp @@ -115,7 +115,7 @@ void ARCodeWidget::OnItemChanged(QListWidgetItem* item) m_ar_codes[m_code_list->row(item)].enabled = (item->checkState() == Qt::Checked); if (!m_restart_required) - ActionReplay::ApplyCodes(m_ar_codes, m_game_id); + ActionReplay::ApplyCodes(m_ar_codes, m_game_id, m_game_revision); UpdateList(); SaveCodes(); diff --git a/Source/Core/DolphinQt/Config/GeckoCodeWidget.cpp b/Source/Core/DolphinQt/Config/GeckoCodeWidget.cpp index 97a93051f5..bce1e89b68 100644 --- a/Source/Core/DolphinQt/Config/GeckoCodeWidget.cpp +++ b/Source/Core/DolphinQt/Config/GeckoCodeWidget.cpp @@ -202,7 +202,7 @@ void GeckoCodeWidget::OnItemChanged(QListWidgetItem* item) m_gecko_codes[index].enabled = (item->checkState() == Qt::Checked); if (!m_restart_required) - Gecko::SetActiveCodes(m_gecko_codes, m_game_id); + Gecko::SetActiveCodes(m_gecko_codes, m_game_id, m_game_revision); SaveCodes(); }