mirror of
https://github.com/dolphin-emu/dolphin
synced 2025-10-05 16:03:02 +02:00
Merge pull request #13909 from Dentomologist/codewidgets_show_code_approval_in_hardcore_mode
CodeWidgets: Show code approval in Hardcore mode
This commit is contained in:
@@ -450,15 +450,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;
|
||||
|
||||
@@ -468,33 +471,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
|
||||
@@ -554,16 +566,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;
|
||||
@@ -220,7 +224,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;
|
||||
@@ -333,14 +339,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();
|
||||
}
|
||||
|
||||
|
@@ -68,11 +68,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);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user