mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2026-04-24 23:32:39 -05:00
AchievementManager: APPROVED_LIST_HASH quality of life improvements
APPROVED_LIST_HASH is moved to a separate file, making tests compilation faster after changing it. The error message prints the hash in a way that it can be directly copy-pasted (though it still needs clang-format).
This commit is contained in:
parent
981b7df420
commit
a108fb849f
|
|
@ -7,6 +7,7 @@
|
|||
#include <array>
|
||||
#include <memory>
|
||||
|
||||
#include <fmt/ranges.h>
|
||||
#include <mbedtls/sha1.h>
|
||||
|
||||
#include "Common/Assert.h"
|
||||
|
|
@ -390,17 +391,11 @@ Digest CalculateDigest(const u8* msg, size_t len)
|
|||
|
||||
std::string DigestToString(const Digest& digest)
|
||||
{
|
||||
static constexpr std::array<char, 16> lookup = {'0', '1', '2', '3', '4', '5', '6', '7',
|
||||
'8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
|
||||
std::string hash;
|
||||
hash.reserve(digest.size() * 2);
|
||||
for (size_t i = 0; i < digest.size(); ++i)
|
||||
{
|
||||
const u8 upper = static_cast<u8>((digest[i] >> 4) & 0xf);
|
||||
const u8 lower = static_cast<u8>(digest[i] & 0xf);
|
||||
hash.push_back(lookup[upper]);
|
||||
hash.push_back(lookup[lower]);
|
||||
}
|
||||
return hash;
|
||||
return fmt::format("{:02X}", fmt::join(digest, ""));
|
||||
}
|
||||
|
||||
std::string DigestToSource(const Digest& digest)
|
||||
{
|
||||
return fmt::format("{{0x{:02X}}}", fmt::join(digest, ", 0x"));
|
||||
}
|
||||
} // namespace Common::SHA1
|
||||
|
|
|
|||
|
|
@ -58,4 +58,5 @@ inline Digest CalculateDigest(const std::array<T, Size>& msg)
|
|||
}
|
||||
|
||||
std::string DigestToString(const Digest& digest);
|
||||
std::string DigestToSource(const Digest& digest);
|
||||
} // namespace Common::SHA1
|
||||
|
|
|
|||
13
Source/Core/Core/AchievementApprovedHash.h
Normal file
13
Source/Core/Core/AchievementApprovedHash.h
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
// Copyright 2026 Dolphin Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Common/Crypto/SHA1.h"
|
||||
|
||||
static constexpr std::string_view ACHIEVEMENT_APPROVED_LIST_FILENAME = "ApprovedInis.json";
|
||||
// After building tests, find the new hash with:
|
||||
// ./Binaries/Tests/tests --gtest_filter=PatchAllowlist.VerifyHashes
|
||||
static const inline Common::SHA1::Digest ACHIEVEMENT_APPROVED_LIST_HASH = {
|
||||
0xEA, 0x2F, 0x74, 0xA1, 0x6C, 0xF3, 0xB5, 0xD4, 0x8A, 0xAF,
|
||||
0x03, 0x30, 0x58, 0x2A, 0xE0, 0xF7, 0x0A, 0x88, 0x86, 0xB3};
|
||||
|
|
@ -21,6 +21,7 @@
|
|||
#include "Common/StringUtil.h"
|
||||
#include "Common/Version.h"
|
||||
#include "Common/WorkQueueThread.h"
|
||||
#include "Core/AchievementApprovedHash.h"
|
||||
#include "Core/ActionReplay.h"
|
||||
#include "Core/Config/AchievementSettings.h"
|
||||
#include "Core/Config/FreeLookSettings.h"
|
||||
|
|
@ -100,23 +101,24 @@ picojson::value AchievementManager::LoadApprovedList()
|
|||
{
|
||||
picojson::value temp;
|
||||
std::string error;
|
||||
if (!JsonFromFile(fmt::format("{}{}{}", File::GetSysDirectory(), DIR_SEP, APPROVED_LIST_FILENAME),
|
||||
if (!JsonFromFile(fmt::format("{}{}{}", File::GetSysDirectory(), DIR_SEP,
|
||||
ACHIEVEMENT_APPROVED_LIST_FILENAME),
|
||||
&temp, &error))
|
||||
{
|
||||
WARN_LOG_FMT(ACHIEVEMENTS, "Failed to load approved game settings list {}",
|
||||
APPROVED_LIST_FILENAME);
|
||||
ACHIEVEMENT_APPROVED_LIST_FILENAME);
|
||||
WARN_LOG_FMT(ACHIEVEMENTS, "Error: {}", error);
|
||||
return {};
|
||||
}
|
||||
auto context = Common::SHA1::CreateContext();
|
||||
context->Update(temp.serialize());
|
||||
auto digest = context->Finish();
|
||||
if (digest != APPROVED_LIST_HASH)
|
||||
if (digest != ACHIEVEMENT_APPROVED_LIST_HASH)
|
||||
{
|
||||
WARN_LOG_FMT(ACHIEVEMENTS, "Failed to verify approved game settings list {}",
|
||||
APPROVED_LIST_FILENAME);
|
||||
ACHIEVEMENT_APPROVED_LIST_FILENAME);
|
||||
WARN_LOG_FMT(ACHIEVEMENTS, "Expected hash {}, found hash {}",
|
||||
Common::SHA1::DigestToString(APPROVED_LIST_HASH),
|
||||
Common::SHA1::DigestToString(ACHIEVEMENT_APPROVED_LIST_HASH),
|
||||
Common::SHA1::DigestToString(digest));
|
||||
return {};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -81,10 +81,6 @@ public:
|
|||
static constexpr std::string_view GRAY = "transparent";
|
||||
static constexpr std::string_view GOLD = "#FFD700";
|
||||
static constexpr std::string_view BLUE = "#0B71C1";
|
||||
static constexpr std::string_view APPROVED_LIST_FILENAME = "ApprovedInis.json";
|
||||
static const inline Common::SHA1::Digest APPROVED_LIST_HASH = {
|
||||
0xEA, 0x2F, 0x74, 0xA1, 0x6C, 0xF3, 0xB5, 0xD4, 0x8A, 0xAF,
|
||||
0x03, 0x30, 0x58, 0x2A, 0xE0, 0xF7, 0x0A, 0x88, 0x86, 0xB3};
|
||||
|
||||
struct LeaderboardEntry
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
add_library(core
|
||||
AchievementApprovedHash.h
|
||||
AchievementManager.cpp
|
||||
AchievementManager.h
|
||||
ActionReplay.cpp
|
||||
|
|
|
|||
|
|
@ -183,6 +183,7 @@
|
|||
<ClInclude Include="Common\WindowsRegistry.h" />
|
||||
<ClInclude Include="Common\WindowSystemInfo.h" />
|
||||
<ClInclude Include="Common\WorkQueueThread.h" />
|
||||
<ClInclude Include="Core\AchievementApprovedHash.h" />
|
||||
<ClInclude Include="Core\AchievementManager.h" />
|
||||
<ClInclude Include="Core\ActionReplay.h" />
|
||||
<ClInclude Include="Core\ARDecrypt.h" />
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
#include "Common/FileUtil.h"
|
||||
#include "Common/IniFile.h"
|
||||
#include "Common/JsonUtil.h"
|
||||
#include "Core/AchievementManager.h"
|
||||
#include "Core/AchievementApprovedHash.h"
|
||||
#include "Core/ActionReplay.h"
|
||||
#include "Core/GeckoCode.h"
|
||||
#include "Core/GeckoCodeConfig.h"
|
||||
|
|
@ -128,23 +128,24 @@ TEST(PatchAllowlist, VerifyHashes)
|
|||
auto context = Common::SHA1::CreateContext();
|
||||
context->Update(new_allowlist_str);
|
||||
auto digest = context->Finish();
|
||||
if (digest != AchievementManager::APPROVED_LIST_HASH)
|
||||
if (digest != ACHIEVEMENT_APPROVED_LIST_HASH)
|
||||
{
|
||||
ADD_FAILURE() << "Approved list hash does not match the one in AchievementMananger."
|
||||
ADD_FAILURE() << "Approved list hash does not match the one in AchievementApprovedHash.h."
|
||||
<< std::endl
|
||||
<< "Please update APPROVED_LIST_HASH to the following:" << std::endl
|
||||
<< Common::SHA1::DigestToString(digest);
|
||||
<< Common::SHA1::DigestToSource(digest);
|
||||
}
|
||||
// Compare with old allowlist
|
||||
static constexpr std::string_view APPROVED_LIST_FILENAME = "ApprovedInis.json";
|
||||
std::string old_allowlist;
|
||||
std::string error;
|
||||
const auto& list_filepath = fmt::format("{}{}{}", sys_directory, DIR_SEP, APPROVED_LIST_FILENAME);
|
||||
const auto& list_filepath =
|
||||
fmt::format("{}{}{}", sys_directory, DIR_SEP, ACHIEVEMENT_APPROVED_LIST_FILENAME);
|
||||
if (!File::ReadFileToString(list_filepath, old_allowlist) || old_allowlist != new_allowlist_str)
|
||||
{
|
||||
static constexpr std::string_view NEW_APPROVED_LIST_FILENAME = "New-ApprovedInis.json";
|
||||
static constexpr std::string_view NEW_ACHIEVEMENT_APPROVED_LIST_FILENAME =
|
||||
"New-ApprovedInis.json";
|
||||
const auto& new_list_filepath =
|
||||
fmt::format("{}{}{}", sys_directory, DIR_SEP, NEW_APPROVED_LIST_FILENAME);
|
||||
fmt::format("{}{}{}", sys_directory, DIR_SEP, NEW_ACHIEVEMENT_APPROVED_LIST_FILENAME);
|
||||
if (!JsonToFile(new_list_filepath, picojson::value(new_allowlist), false))
|
||||
{
|
||||
ADD_FAILURE() << "Failed to write new approved list to " << list_filepath;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user