mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-12-16 04:09:39 +00:00
CodeWidgets: Show code approval in Hardcore mode
When Hardcore mode is enabled, show an icon for each code in ARCodeWidget and GeckoCodeWidget indicating whether it's an approved code or not.
This commit is contained in:
parent
2b7faeb920
commit
44f6743a5b
@ -460,15 +460,18 @@ void AchievementManager::FilterApprovedIni(std::vector<T>& codes, const std::str
|
||||
|
||||
for (auto& code : codes)
|
||||
{
|
||||
if (code.enabled && !CheckApprovedCode(code, game_id, revision))
|
||||
if (code.enabled && !IsApprovedCode(code, game_id, revision))
|
||||
code.enabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool AchievementManager::CheckApprovedCode(const T& code, const std::string& game_id,
|
||||
u16 revision) const
|
||||
bool AchievementManager::ShouldCodeBeActivated(const T& code, const std::string& game_id,
|
||||
u16 revision) const
|
||||
{
|
||||
if (!code.enabled)
|
||||
return false;
|
||||
|
||||
if (!IsHardcoreModeActive())
|
||||
return true;
|
||||
|
||||
@ -478,33 +481,42 @@ bool AchievementManager::CheckApprovedCode(const T& code, const std::string& gam
|
||||
|
||||
INFO_LOG_FMT(ACHIEVEMENTS, "Verifying code {}", code.name);
|
||||
|
||||
bool verified = false;
|
||||
if (IsApprovedCode(code, game_id, revision))
|
||||
return true;
|
||||
|
||||
auto hash = Common::SHA1::DigestToString(GetCodeHash(code));
|
||||
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);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool AchievementManager::IsApprovedCode(const T& code, const std::string& game_id,
|
||||
u16 revision) const
|
||||
{
|
||||
// Approved codes list failed to hash
|
||||
if (!m_ini_root->is<picojson::value::object>())
|
||||
return false;
|
||||
|
||||
const auto hash = Common::SHA1::DigestToString(GetCodeHash(code));
|
||||
|
||||
for (const std::string& filename : ConfigLoaders::GetGameIniFilenames(game_id, revision))
|
||||
{
|
||||
auto config = filename.substr(0, filename.length() - 4);
|
||||
const auto config = filename.substr(0, filename.length() - 4);
|
||||
if (m_ini_root->contains(config))
|
||||
{
|
||||
auto ini_config = m_ini_root->get(config);
|
||||
const auto ini_config = m_ini_root->get(config);
|
||||
if (ini_config.is<picojson::object>() && ini_config.contains(code.name))
|
||||
{
|
||||
auto ini_code = ini_config.get(code.name);
|
||||
if (ini_code.template is<std::string>())
|
||||
verified = (ini_code.template get<std::string>() == hash);
|
||||
const auto ini_code = ini_config.get(code.name);
|
||||
if (ini_code.template is<std::string>() && ini_code.template get<std::string>() == hash)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!verified)
|
||||
{
|
||||
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);
|
||||
}
|
||||
return verified;
|
||||
return false;
|
||||
}
|
||||
|
||||
Common::SHA1::Digest AchievementManager::GetCodeHash(const PatchEngine::Patch& patch) const
|
||||
@ -564,16 +576,27 @@ void AchievementManager::FilterApprovedARCodes(std::vector<ActionReplay::ARCode>
|
||||
FilterApprovedIni(codes, game_id, revision);
|
||||
}
|
||||
|
||||
bool AchievementManager::CheckApprovedGeckoCode(const Gecko::GeckoCode& code,
|
||||
const std::string& game_id, u16 revision) const
|
||||
bool AchievementManager::ShouldGeckoCodeBeActivated(const Gecko::GeckoCode& code,
|
||||
const std::string& game_id, u16 revision) const
|
||||
{
|
||||
return CheckApprovedCode(code, game_id, revision);
|
||||
return ShouldCodeBeActivated(code, game_id, revision);
|
||||
}
|
||||
|
||||
bool AchievementManager::CheckApprovedARCode(const ActionReplay::ARCode& code,
|
||||
bool AchievementManager::ShouldARCodeBeActivated(const ActionReplay::ARCode& code,
|
||||
const std::string& game_id, u16 revision) const
|
||||
{
|
||||
return ShouldCodeBeActivated(code, game_id, revision);
|
||||
}
|
||||
|
||||
bool AchievementManager::IsApprovedGeckoCode(const Gecko::GeckoCode& code,
|
||||
const std::string& game_id, u16 revision) const
|
||||
{
|
||||
return CheckApprovedCode(code, game_id, revision);
|
||||
return IsApprovedCode(code, game_id, revision);
|
||||
}
|
||||
bool AchievementManager::IsApprovedARCode(const ActionReplay::ARCode& code,
|
||||
const std::string& game_id, u16 revision) const
|
||||
{
|
||||
return IsApprovedCode(code, game_id, revision);
|
||||
}
|
||||
|
||||
void AchievementManager::SetSpectatorMode()
|
||||
|
||||
@ -149,10 +149,14 @@ public:
|
||||
u16 revision) const;
|
||||
void FilterApprovedARCodes(std::vector<ActionReplay::ARCode>& 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,
|
||||
bool ShouldGeckoCodeBeActivated(const Gecko::GeckoCode& code, const std::string& game_id,
|
||||
u16 revision) const;
|
||||
bool ShouldARCodeBeActivated(const ActionReplay::ARCode& code, const std::string& game_id,
|
||||
u16 revision) const;
|
||||
bool IsApprovedGeckoCode(const Gecko::GeckoCode& code, const std::string& game_id,
|
||||
u16 revision) const;
|
||||
bool IsApprovedARCode(const ActionReplay::ARCode& code, const std::string& game_id,
|
||||
u16 revision) const;
|
||||
|
||||
void SetSpectatorMode();
|
||||
std::string_view GetPlayerDisplayName() const;
|
||||
@ -223,7 +227,9 @@ private:
|
||||
template <typename T>
|
||||
void FilterApprovedIni(std::vector<T>& codes, const std::string& game_id, u16 revision) const;
|
||||
template <typename T>
|
||||
bool CheckApprovedCode(const T& code, const std::string& game_id, u16 revision) const;
|
||||
bool ShouldCodeBeActivated(const T& code, const std::string& game_id, u16 revision) const;
|
||||
template <typename T>
|
||||
bool IsApprovedCode(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;
|
||||
@ -338,14 +344,14 @@ public:
|
||||
|
||||
constexpr bool IsHardcoreModeActive() { return false; }
|
||||
|
||||
constexpr bool CheckApprovedGeckoCode(const Gecko::GeckoCode& code, const std::string& game_id,
|
||||
u16 revision)
|
||||
constexpr bool ShouldGeckoCodeBeActivated(const Gecko::GeckoCode& code,
|
||||
const std::string& game_id, u16 revision)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
constexpr bool CheckApprovedARCode(const ActionReplay::ARCode& code, const std::string& game_id,
|
||||
u16 revision)
|
||||
constexpr bool ShouldARCodeBeActivated(const ActionReplay::ARCode& code,
|
||||
const std::string& game_id, u16 revision)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -122,11 +122,11 @@ void ApplyCodes(std::span<const ARCode> codes, const std::string& game_id, u16 r
|
||||
std::lock_guard guard(s_lock);
|
||||
s_disable_logging = false;
|
||||
s_active_codes.clear();
|
||||
std::copy_if(codes.begin(), codes.end(), std::back_inserter(s_active_codes),
|
||||
[&game_id, &revision](const ARCode& code) {
|
||||
return code.enabled && AchievementManager::GetInstance().CheckApprovedARCode(
|
||||
code, game_id, revision);
|
||||
});
|
||||
|
||||
const auto should_be_activated = [&game_id, &revision](const ARCode& code) {
|
||||
return AchievementManager::GetInstance().ShouldARCodeBeActivated(code, game_id, revision);
|
||||
};
|
||||
std::copy_if(codes.begin(), codes.end(), std::back_inserter(s_active_codes), should_be_activated);
|
||||
s_active_codes.shrink_to_fit();
|
||||
}
|
||||
|
||||
|
||||
@ -59,11 +59,11 @@ void SetActiveCodes(std::span<const GeckoCode> gcodes, const std::string& game_i
|
||||
{
|
||||
s_active_codes.reserve(gcodes.size());
|
||||
|
||||
const auto should_be_activated = [&game_id, &revision](const GeckoCode& code) {
|
||||
return AchievementManager::GetInstance().ShouldGeckoCodeBeActivated(code, game_id, revision);
|
||||
};
|
||||
std::copy_if(gcodes.begin(), gcodes.end(), std::back_inserter(s_active_codes),
|
||||
[&game_id, &revision](const GeckoCode& code) {
|
||||
return code.enabled && AchievementManager::GetInstance().CheckApprovedGeckoCode(
|
||||
code, game_id, revision);
|
||||
});
|
||||
should_be_activated);
|
||||
}
|
||||
s_active_codes.shrink_to_fit();
|
||||
|
||||
|
||||
@ -8,14 +8,21 @@
|
||||
|
||||
#include <QCursor>
|
||||
#include <QHBoxLayout>
|
||||
#ifdef USE_RETRO_ACHIEVEMENTS
|
||||
#include <QIcon>
|
||||
#endif // USE_RETRO_ACHIEVEMENTS
|
||||
#include <QListWidget>
|
||||
#include <QMenu>
|
||||
#include <QPushButton>
|
||||
#ifdef USE_RETRO_ACHIEVEMENTS
|
||||
#include <QStyle>
|
||||
#endif // USE_RETRO_ACHIEVEMENTS
|
||||
#include <QVBoxLayout>
|
||||
|
||||
#include "Common/FileUtil.h"
|
||||
#include "Common/IniFile.h"
|
||||
|
||||
#include "Core/AchievementManager.h"
|
||||
#include "Core/ActionReplay.h"
|
||||
#include "Core/ConfigManager.h"
|
||||
|
||||
@ -23,6 +30,9 @@
|
||||
#include "DolphinQt/Config/CheatWarningWidget.h"
|
||||
#include "DolphinQt/Config/HardcoreWarningWidget.h"
|
||||
#include "DolphinQt/QtUtils/NonDefaultQPushButton.h"
|
||||
#ifdef USE_RETRO_ACHIEVEMENTS
|
||||
#include "DolphinQt/Settings.h"
|
||||
#endif // USE_RETRO_ACHIEVEMENTS
|
||||
|
||||
ARCodeWidget::ARCodeWidget(std::string game_id, u16 game_revision, bool restart_required)
|
||||
: m_game_id(std::move(game_id)), m_game_revision(game_revision),
|
||||
@ -90,6 +100,7 @@ void ARCodeWidget::ConnectWidgets()
|
||||
#ifdef USE_RETRO_ACHIEVEMENTS
|
||||
connect(m_hc_warning, &HardcoreWarningWidget::OpenAchievementSettings, this,
|
||||
&ARCodeWidget::OpenAchievementSettings);
|
||||
connect(&Settings::Instance(), &Settings::EmulationStateChanged, this, &ARCodeWidget::UpdateList);
|
||||
#endif // USE_RETRO_ACHIEVEMENTS
|
||||
|
||||
connect(m_code_list, &QListWidget::itemChanged, this, &ARCodeWidget::OnItemChanged);
|
||||
@ -199,6 +210,21 @@ void ARCodeWidget::UpdateList()
|
||||
item->setCheckState(ar.enabled ? Qt::Checked : Qt::Unchecked);
|
||||
item->setData(Qt::UserRole, static_cast<int>(i));
|
||||
|
||||
#ifdef USE_RETRO_ACHIEVEMENTS
|
||||
const AchievementManager& achievement_manager = AchievementManager::GetInstance();
|
||||
|
||||
if (achievement_manager.IsHardcoreModeActive())
|
||||
{
|
||||
const QIcon approved_icon = style()->standardIcon(QStyle::SP_DialogYesButton);
|
||||
const QIcon warning_icon = style()->standardIcon(QStyle::SP_MessageBoxWarning);
|
||||
|
||||
if (achievement_manager.IsApprovedARCode(ar, m_game_id, m_game_revision))
|
||||
item->setIcon(approved_icon);
|
||||
else
|
||||
item->setIcon(warning_icon);
|
||||
}
|
||||
#endif // USE_RETRO_ACHIEVEMENTS
|
||||
|
||||
m_code_list->addItem(item);
|
||||
}
|
||||
|
||||
|
||||
@ -10,16 +10,23 @@
|
||||
#include <QFontDatabase>
|
||||
#include <QFormLayout>
|
||||
#include <QHBoxLayout>
|
||||
#ifdef USE_RETRO_ACHIEVEMENTS
|
||||
#include <QIcon>
|
||||
#endif // USE_RETRO_ACHIEVEMENTS
|
||||
#include <QLabel>
|
||||
#include <QListWidget>
|
||||
#include <QMenu>
|
||||
#include <QPushButton>
|
||||
#ifdef USE_RETRO_ACHIEVEMENTS
|
||||
#include <QStyle>
|
||||
#endif // USE_RETRO_ACHIEVEMENTS
|
||||
#include <QTextEdit>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
#include "Common/FileUtil.h"
|
||||
#include "Common/IniFile.h"
|
||||
|
||||
#include "Core/AchievementManager.h"
|
||||
#include "Core/ConfigManager.h"
|
||||
#include "Core/GeckoCode.h"
|
||||
#include "Core/GeckoCodeConfig.h"
|
||||
@ -31,6 +38,9 @@
|
||||
#include "DolphinQt/QtUtils/NonDefaultQPushButton.h"
|
||||
#include "DolphinQt/QtUtils/QtUtils.h"
|
||||
#include "DolphinQt/QtUtils/WrapInScrollArea.h"
|
||||
#ifdef USE_RETRO_ACHIEVEMENTS
|
||||
#include "DolphinQt/Settings.h"
|
||||
#endif // USE_RETRO_ACHIEVEMENTS
|
||||
|
||||
GeckoCodeWidget::GeckoCodeWidget(std::string game_id, std::string gametdb_id, u16 game_revision,
|
||||
bool restart_required)
|
||||
@ -158,6 +168,8 @@ void GeckoCodeWidget::ConnectWidgets()
|
||||
#ifdef USE_RETRO_ACHIEVEMENTS
|
||||
connect(m_hc_warning, &HardcoreWarningWidget::OpenAchievementSettings, this,
|
||||
&GeckoCodeWidget::OpenAchievementSettings);
|
||||
connect(&Settings::Instance(), &Settings::EmulationStateChanged, this,
|
||||
&GeckoCodeWidget::UpdateList);
|
||||
#endif // USE_RETRO_ACHIEVEMENTS
|
||||
}
|
||||
|
||||
@ -356,6 +368,21 @@ void GeckoCodeWidget::UpdateList()
|
||||
item->setCheckState(code.enabled ? Qt::Checked : Qt::Unchecked);
|
||||
item->setData(Qt::UserRole, static_cast<int>(i));
|
||||
|
||||
#ifdef USE_RETRO_ACHIEVEMENTS
|
||||
const AchievementManager& achievement_manager = AchievementManager::GetInstance();
|
||||
|
||||
if (achievement_manager.IsHardcoreModeActive())
|
||||
{
|
||||
const QIcon approved_icon = style()->standardIcon(QStyle::SP_DialogYesButton);
|
||||
const QIcon warning_icon = style()->standardIcon(QStyle::SP_MessageBoxWarning);
|
||||
|
||||
if (achievement_manager.IsApprovedGeckoCode(code, m_game_id, m_game_revision))
|
||||
item->setIcon(approved_icon);
|
||||
else
|
||||
item->setIcon(warning_icon);
|
||||
}
|
||||
#endif // USE_RETRO_ACHIEVEMENTS
|
||||
|
||||
m_code_list->addItem(item);
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user