mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-23 14:19:46 -06:00
Merge pull request #13427 from LillyJadeKatrin/retroachievements-code-approval-fix
Fixed Multi Config Code Approvals
This commit is contained in:
@ -28,6 +28,7 @@
|
|||||||
#include "Core/Config/AchievementSettings.h"
|
#include "Core/Config/AchievementSettings.h"
|
||||||
#include "Core/Config/FreeLookSettings.h"
|
#include "Core/Config/FreeLookSettings.h"
|
||||||
#include "Core/Config/MainSettings.h"
|
#include "Core/Config/MainSettings.h"
|
||||||
|
#include "Core/ConfigLoaders/GameConfigLoader.h"
|
||||||
#include "Core/Core.h"
|
#include "Core/Core.h"
|
||||||
#include "Core/GeckoCode.h"
|
#include "Core/GeckoCode.h"
|
||||||
#include "Core/HW/Memmap.h"
|
#include "Core/HW/Memmap.h"
|
||||||
@ -386,8 +387,8 @@ bool AchievementManager::IsHardcoreModeActive() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void AchievementManager::FilterApprovedIni(std::vector<T>& codes,
|
void AchievementManager::FilterApprovedIni(std::vector<T>& codes, const std::string& game_id,
|
||||||
const std::string& game_ini_id) const
|
u16 revision) const
|
||||||
{
|
{
|
||||||
if (codes.empty())
|
if (codes.empty())
|
||||||
{
|
{
|
||||||
@ -409,13 +410,14 @@ void AchievementManager::FilterApprovedIni(std::vector<T>& codes,
|
|||||||
|
|
||||||
for (auto& code : codes)
|
for (auto& code : codes)
|
||||||
{
|
{
|
||||||
if (code.enabled && !CheckApprovedCode(code, game_ini_id))
|
if (code.enabled && !CheckApprovedCode(code, game_id, revision))
|
||||||
code.enabled = false;
|
code.enabled = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
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())
|
if (!IsHardcoreModeActive())
|
||||||
return true;
|
return true;
|
||||||
@ -424,22 +426,22 @@ bool AchievementManager::CheckApprovedCode(const T& code, const std::string& gam
|
|||||||
if (!m_ini_root->is<picojson::value::object>())
|
if (!m_ini_root->is<picojson::value::object>())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
const bool known_id = m_ini_root->contains(game_ini_id);
|
|
||||||
|
|
||||||
INFO_LOG_FMT(ACHIEVEMENTS, "Verifying code {}", code.name);
|
INFO_LOG_FMT(ACHIEVEMENTS, "Verifying code {}", code.name);
|
||||||
|
|
||||||
bool verified = false;
|
bool verified = false;
|
||||||
|
|
||||||
if (known_id)
|
auto hash = Common::SHA1::DigestToString(GetCodeHash(code));
|
||||||
{
|
|
||||||
auto digest = 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)
|
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::Duration::VERY_LONG, OSD::Color::RED);
|
||||||
OSD::AddMessage("Disable hardcore mode to enable this code.", OSD::Duration::VERY_LONG,
|
OSD::AddMessage("Disable hardcore mode to enable this code.", OSD::Duration::VERY_LONG,
|
||||||
OSD::Color::RED);
|
OSD::Color::RED);
|
||||||
@ -487,33 +489,33 @@ Common::SHA1::Digest AchievementManager::GetCodeHash(const ActionReplay::ARCode&
|
|||||||
}
|
}
|
||||||
|
|
||||||
void AchievementManager::FilterApprovedPatches(std::vector<PatchEngine::Patch>& patches,
|
void AchievementManager::FilterApprovedPatches(std::vector<PatchEngine::Patch>& 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<Gecko::GeckoCode>& codes,
|
void AchievementManager::FilterApprovedGeckoCodes(std::vector<Gecko::GeckoCode>& 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<ActionReplay::ARCode>& codes,
|
void AchievementManager::FilterApprovedARCodes(std::vector<ActionReplay::ARCode>& 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,
|
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,
|
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()
|
void AchievementManager::SetSpectatorMode()
|
||||||
|
@ -133,16 +133,17 @@ public:
|
|||||||
|
|
||||||
std::recursive_mutex& GetLock();
|
std::recursive_mutex& GetLock();
|
||||||
bool IsHardcoreModeActive() const;
|
bool IsHardcoreModeActive() const;
|
||||||
void SetGameIniId(const std::string& game_ini_id) { m_game_ini_id = game_ini_id; }
|
|
||||||
|
|
||||||
void FilterApprovedPatches(std::vector<PatchEngine::Patch>& patches,
|
void FilterApprovedPatches(std::vector<PatchEngine::Patch>& patches, const std::string& game_id,
|
||||||
const std::string& game_ini_id) const;
|
u16 revision) const;
|
||||||
void FilterApprovedGeckoCodes(std::vector<Gecko::GeckoCode>& codes,
|
void FilterApprovedGeckoCodes(std::vector<Gecko::GeckoCode>& codes, const std::string& game_id,
|
||||||
const std::string& game_ini_id) const;
|
u16 revision) const;
|
||||||
void FilterApprovedARCodes(std::vector<ActionReplay::ARCode>& codes,
|
void FilterApprovedARCodes(std::vector<ActionReplay::ARCode>& codes, const std::string& game_id,
|
||||||
const std::string& game_ini_id) const;
|
u16 revision) const;
|
||||||
bool CheckApprovedGeckoCode(const Gecko::GeckoCode& code, const std::string& game_ini_id) const;
|
bool CheckApprovedGeckoCode(const Gecko::GeckoCode& code, const std::string& game_id,
|
||||||
bool CheckApprovedARCode(const ActionReplay::ARCode& code, const std::string& game_ini_id) const;
|
u16 revision) const;
|
||||||
|
bool CheckApprovedARCode(const ActionReplay::ARCode& code, const std::string& game_id,
|
||||||
|
u16 revision) const;
|
||||||
|
|
||||||
void SetSpectatorMode();
|
void SetSpectatorMode();
|
||||||
std::string_view GetPlayerDisplayName() const;
|
std::string_view GetPlayerDisplayName() const;
|
||||||
@ -201,9 +202,9 @@ private:
|
|||||||
void SetHardcoreMode();
|
void SetHardcoreMode();
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void FilterApprovedIni(std::vector<T>& codes, const std::string& game_ini_id) const;
|
void FilterApprovedIni(std::vector<T>& codes, const std::string& game_id, u16 revision) const;
|
||||||
template <typename T>
|
template <typename T>
|
||||||
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 PatchEngine::Patch& patch) const;
|
||||||
Common::SHA1::Digest GetCodeHash(const Gecko::GeckoCode& code) const;
|
Common::SHA1::Digest GetCodeHash(const Gecko::GeckoCode& code) const;
|
||||||
Common::SHA1::Digest GetCodeHash(const ActionReplay::ARCode& 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();
|
std::chrono::steady_clock::time_point m_last_progress_message = std::chrono::steady_clock::now();
|
||||||
|
|
||||||
Common::Lazy<picojson::value> m_ini_root{LoadApprovedList};
|
Common::Lazy<picojson::value> m_ini_root{LoadApprovedList};
|
||||||
std::string m_game_ini_id;
|
|
||||||
|
|
||||||
std::unordered_map<AchievementId, LeaderboardStatus> m_leaderboard_map;
|
std::unordered_map<AchievementId, LeaderboardStatus> m_leaderboard_map;
|
||||||
bool m_challenges_updated = false;
|
bool m_challenges_updated = false;
|
||||||
@ -302,14 +302,12 @@ public:
|
|||||||
|
|
||||||
constexpr bool IsHardcoreModeActive() { return false; }
|
constexpr bool IsHardcoreModeActive() { return false; }
|
||||||
|
|
||||||
constexpr bool CheckApprovedGeckoCode(const Gecko::GeckoCode& code,
|
constexpr bool CheckApprovedGeckoCode(const Gecko::GeckoCode& code, const std::string& game_id)
|
||||||
const std::string& game_ini_id)
|
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
constexpr bool CheckApprovedARCode(const ActionReplay::ARCode& code,
|
constexpr bool CheckApprovedARCode(const ActionReplay::ARCode& code, const std::string& game_id)
|
||||||
const std::string& game_ini_id)
|
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
@ -113,7 +113,7 @@ struct ARAddr
|
|||||||
|
|
||||||
// ----------------------
|
// ----------------------
|
||||||
// AR Remote Functions
|
// AR Remote Functions
|
||||||
void ApplyCodes(std::span<const ARCode> codes, const std::string& game_id)
|
void ApplyCodes(std::span<const ARCode> codes, const std::string& game_id, u16 revision)
|
||||||
{
|
{
|
||||||
if (!Config::AreCheatsEnabled())
|
if (!Config::AreCheatsEnabled())
|
||||||
return;
|
return;
|
||||||
@ -122,9 +122,9 @@ void ApplyCodes(std::span<const ARCode> codes, const std::string& game_id)
|
|||||||
s_disable_logging = false;
|
s_disable_logging = false;
|
||||||
s_active_codes.clear();
|
s_active_codes.clear();
|
||||||
std::copy_if(codes.begin(), codes.end(), std::back_inserter(s_active_codes),
|
std::copy_if(codes.begin(), codes.end(), std::back_inserter(s_active_codes),
|
||||||
[&game_id](const ARCode& code) {
|
[&game_id, &revision](const ARCode& code) {
|
||||||
return code.enabled &&
|
return code.enabled && AchievementManager::GetInstance().CheckApprovedARCode(
|
||||||
AchievementManager::GetInstance().CheckApprovedARCode(code, game_id);
|
code, game_id, revision);
|
||||||
});
|
});
|
||||||
s_active_codes.shrink_to_fit();
|
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,
|
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.
|
// Parses the Action Replay section of a game ini file.
|
||||||
|
@ -45,13 +45,13 @@ struct ARCode
|
|||||||
|
|
||||||
void RunAllActive(const Core::CPUThreadGuard& cpu_guard);
|
void RunAllActive(const Core::CPUThreadGuard& cpu_guard);
|
||||||
|
|
||||||
void ApplyCodes(std::span<const ARCode> codes, const std::string& game_id);
|
void ApplyCodes(std::span<const ARCode> codes, const std::string& game_id, u16 revision);
|
||||||
void SetSyncedCodesAsActive();
|
void SetSyncedCodesAsActive();
|
||||||
void UpdateSyncedCodes(std::span<const ARCode> codes);
|
void UpdateSyncedCodes(std::span<const ARCode> codes);
|
||||||
std::vector<ARCode> ApplyAndReturnCodes(std::span<const ARCode> codes);
|
std::vector<ARCode> ApplyAndReturnCodes(std::span<const ARCode> codes);
|
||||||
void AddCode(ARCode new_code);
|
void AddCode(ARCode new_code);
|
||||||
void LoadAndApplyCodes(const Common::IniFile& global_ini, const Common::IniFile& local_ini,
|
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<ARCode> LoadCodes(const Common::IniFile& global_ini, const Common::IniFile& local_ini);
|
std::vector<ARCode> LoadCodes(const Common::IniFile& global_ini, const Common::IniFile& local_ini);
|
||||||
void SaveCodes(Common::IniFile* local_ini, std::span<const ARCode> codes);
|
void SaveCodes(Common::IniFile* local_ini, std::span<const ARCode> codes);
|
||||||
|
@ -50,7 +50,7 @@ static std::vector<GeckoCode> s_active_codes;
|
|||||||
static std::vector<GeckoCode> s_synced_codes;
|
static std::vector<GeckoCode> s_synced_codes;
|
||||||
static std::mutex s_active_codes_lock;
|
static std::mutex s_active_codes_lock;
|
||||||
|
|
||||||
void SetActiveCodes(std::span<const GeckoCode> gcodes, const std::string& game_id)
|
void SetActiveCodes(std::span<const GeckoCode> gcodes, const std::string& game_id, u16 revision)
|
||||||
{
|
{
|
||||||
std::lock_guard lk(s_active_codes_lock);
|
std::lock_guard lk(s_active_codes_lock);
|
||||||
|
|
||||||
@ -60,9 +60,9 @@ void SetActiveCodes(std::span<const GeckoCode> gcodes, const std::string& game_i
|
|||||||
s_active_codes.reserve(gcodes.size());
|
s_active_codes.reserve(gcodes.size());
|
||||||
|
|
||||||
std::copy_if(gcodes.begin(), gcodes.end(), std::back_inserter(s_active_codes),
|
std::copy_if(gcodes.begin(), gcodes.end(), std::back_inserter(s_active_codes),
|
||||||
[&game_id](const GeckoCode& code) {
|
[&game_id, &revision](const GeckoCode& code) {
|
||||||
return code.enabled &&
|
return code.enabled && AchievementManager::GetInstance().CheckApprovedGeckoCode(
|
||||||
AchievementManager::GetInstance().CheckApprovedGeckoCode(code, game_id);
|
code, game_id, revision);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
s_active_codes.shrink_to_fit();
|
s_active_codes.shrink_to_fit();
|
||||||
|
@ -60,7 +60,7 @@ constexpr u32 HLE_TRAMPOLINE_ADDRESS = INSTALLER_END_ADDRESS - 4;
|
|||||||
// preserve the emulation performance.
|
// preserve the emulation performance.
|
||||||
constexpr u32 MAGIC_GAMEID = 0xD01F1BAD;
|
constexpr u32 MAGIC_GAMEID = 0xD01F1BAD;
|
||||||
|
|
||||||
void SetActiveCodes(std::span<const GeckoCode> gcodes, const std::string& game_id);
|
void SetActiveCodes(std::span<const GeckoCode> gcodes, const std::string& game_id, u16 revision);
|
||||||
void SetSyncedCodesAsActive();
|
void SetSyncedCodesAsActive();
|
||||||
void UpdateSyncedCodes(std::span<const GeckoCode> gcodes);
|
void UpdateSyncedCodes(std::span<const GeckoCode> gcodes);
|
||||||
std::vector<GeckoCode> SetAndReturnActiveCodes(std::span<const GeckoCode> gcodes);
|
std::vector<GeckoCode> SetAndReturnActiveCodes(std::span<const GeckoCode> gcodes);
|
||||||
|
@ -2075,7 +2075,7 @@ bool NetPlayServer::SyncCodes()
|
|||||||
std::vector<Gecko::GeckoCode> codes = Gecko::LoadCodes(globalIni, localIni);
|
std::vector<Gecko::GeckoCode> codes = Gecko::LoadCodes(globalIni, localIni);
|
||||||
|
|
||||||
#ifdef USE_RETRO_ACHIEVEMENTS
|
#ifdef USE_RETRO_ACHIEVEMENTS
|
||||||
AchievementManager::GetInstance().FilterApprovedGeckoCodes(codes, game_id);
|
AchievementManager::GetInstance().FilterApprovedGeckoCodes(codes, game_id, revision);
|
||||||
#endif // USE_RETRO_ACHIEVEMENTS
|
#endif // USE_RETRO_ACHIEVEMENTS
|
||||||
|
|
||||||
// Create a Gecko Code Vector with just the active codes
|
// Create a Gecko Code Vector with just the active codes
|
||||||
@ -2129,7 +2129,7 @@ bool NetPlayServer::SyncCodes()
|
|||||||
{
|
{
|
||||||
std::vector<ActionReplay::ARCode> codes = ActionReplay::LoadCodes(globalIni, localIni);
|
std::vector<ActionReplay::ARCode> codes = ActionReplay::LoadCodes(globalIni, localIni);
|
||||||
#ifdef USE_RETRO_ACHIEVEMENTS
|
#ifdef USE_RETRO_ACHIEVEMENTS
|
||||||
AchievementManager::GetInstance().FilterApprovedARCodes(codes, game_id);
|
AchievementManager::GetInstance().FilterApprovedARCodes(codes, game_id, revision);
|
||||||
#endif // USE_RETRO_ACHIEVEMENTS
|
#endif // USE_RETRO_ACHIEVEMENTS
|
||||||
// Create an AR Code Vector with just the active codes
|
// Create an AR Code Vector with just the active codes
|
||||||
std::vector<ActionReplay::ARCode> active_codes = ActionReplay::ApplyAndReturnCodes(codes);
|
std::vector<ActionReplay::ARCode> active_codes = ActionReplay::ApplyAndReturnCodes(codes);
|
||||||
|
@ -183,7 +183,8 @@ void LoadPatches()
|
|||||||
LoadPatchSection("OnFrame", &s_on_frame, globalIni, localIni);
|
LoadPatchSection("OnFrame", &s_on_frame, globalIni, localIni);
|
||||||
|
|
||||||
#ifdef USE_RETRO_ACHIEVEMENTS
|
#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
|
#endif // USE_RETRO_ACHIEVEMENTS
|
||||||
|
|
||||||
// Check if I'm syncing Codes
|
// Check if I'm syncing Codes
|
||||||
@ -194,8 +195,10 @@ void LoadPatches()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Gecko::SetActiveCodes(Gecko::LoadCodes(globalIni, localIni), sconfig.GetGameID());
|
Gecko::SetActiveCodes(Gecko::LoadCodes(globalIni, localIni), sconfig.GetGameID(),
|
||||||
ActionReplay::LoadAndApplyCodes(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()
|
void Shutdown()
|
||||||
{
|
{
|
||||||
s_on_frame.clear();
|
s_on_frame.clear();
|
||||||
ActionReplay::ApplyCodes({}, "");
|
ActionReplay::ApplyCodes({}, "", 0);
|
||||||
Gecko::Shutdown();
|
Gecko::Shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,7 +115,7 @@ void ARCodeWidget::OnItemChanged(QListWidgetItem* item)
|
|||||||
m_ar_codes[m_code_list->row(item)].enabled = (item->checkState() == Qt::Checked);
|
m_ar_codes[m_code_list->row(item)].enabled = (item->checkState() == Qt::Checked);
|
||||||
|
|
||||||
if (!m_restart_required)
|
if (!m_restart_required)
|
||||||
ActionReplay::ApplyCodes(m_ar_codes, m_game_id);
|
ActionReplay::ApplyCodes(m_ar_codes, m_game_id, m_game_revision);
|
||||||
|
|
||||||
UpdateList();
|
UpdateList();
|
||||||
SaveCodes();
|
SaveCodes();
|
||||||
|
@ -202,7 +202,7 @@ void GeckoCodeWidget::OnItemChanged(QListWidgetItem* item)
|
|||||||
m_gecko_codes[index].enabled = (item->checkState() == Qt::Checked);
|
m_gecko_codes[index].enabled = (item->checkState() == Qt::Checked);
|
||||||
|
|
||||||
if (!m_restart_required)
|
if (!m_restart_required)
|
||||||
Gecko::SetActiveCodes(m_gecko_codes, m_game_id);
|
Gecko::SetActiveCodes(m_gecko_codes, m_game_id, m_game_revision);
|
||||||
|
|
||||||
SaveCodes();
|
SaveCodes();
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user