GameFile: Calculate a sensible sync hash for mod descriptors.
This commit is contained in:
parent
005e850ad6
commit
418bb0b087
|
@ -22,6 +22,7 @@
|
||||||
#include <mbedtls/sha1.h>
|
#include <mbedtls/sha1.h>
|
||||||
#include <pugixml.hpp>
|
#include <pugixml.hpp>
|
||||||
|
|
||||||
|
#include "Common/BitUtils.h"
|
||||||
#include "Common/ChunkFile.h"
|
#include "Common/ChunkFile.h"
|
||||||
#include "Common/CommonPaths.h"
|
#include "Common/CommonPaths.h"
|
||||||
#include "Common/CommonTypes.h"
|
#include "Common/CommonTypes.h"
|
||||||
|
@ -624,15 +625,75 @@ std::string GameFile::GetNetPlayName(const Core::TitleDatabase& title_database)
|
||||||
return name + " (" + ss.str() + ")";
|
return name + " (" + ss.str() + ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static std::array<u8, 20> GetHash(u32 value)
|
||||||
|
{
|
||||||
|
auto data = Common::BitCastToArray<u8>(value);
|
||||||
|
std::array<u8, 20> hash;
|
||||||
|
mbedtls_sha1_ret(reinterpret_cast<const unsigned char*>(data.data()), data.size(), hash.data());
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::array<u8, 20> GetHash(std::string_view str)
|
||||||
|
{
|
||||||
|
std::array<u8, 20> hash;
|
||||||
|
mbedtls_sha1_ret(reinterpret_cast<const unsigned char*>(str.data()), str.size(), hash.data());
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::optional<std::array<u8, 20>> GetFileHash(const std::string& path)
|
||||||
|
{
|
||||||
|
std::string buffer;
|
||||||
|
if (!File::ReadFileToString(path, buffer))
|
||||||
|
return std::nullopt;
|
||||||
|
return GetHash(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::optional<std::array<u8, 20>> MixHash(const std::optional<std::array<u8, 20>>& lhs,
|
||||||
|
const std::optional<std::array<u8, 20>>& rhs)
|
||||||
|
{
|
||||||
|
if (!lhs && !rhs)
|
||||||
|
return std::nullopt;
|
||||||
|
if (!lhs || !rhs)
|
||||||
|
return !rhs ? lhs : rhs;
|
||||||
|
std::array<u8, 20> result;
|
||||||
|
for (size_t i = 0; i < result.size(); ++i)
|
||||||
|
result[i] = (*lhs)[i] ^ (*rhs)[(i + 1) % result.size()];
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
std::array<u8, 20> GameFile::GetSyncHash() const
|
std::array<u8, 20> GameFile::GetSyncHash() const
|
||||||
{
|
{
|
||||||
std::array<u8, 20> hash{};
|
std::optional<std::array<u8, 20>> hash;
|
||||||
|
|
||||||
if (m_platform == DiscIO::Platform::ELFOrDOL)
|
if (m_platform == DiscIO::Platform::ELFOrDOL)
|
||||||
{
|
{
|
||||||
std::string buffer;
|
hash = GetFileHash(m_file_path);
|
||||||
if (File::ReadFileToString(m_file_path, buffer))
|
}
|
||||||
mbedtls_sha1_ret(reinterpret_cast<unsigned char*>(buffer.data()), buffer.size(), hash.data());
|
else if (m_blob_type == DiscIO::BlobType::MOD_DESCRIPTOR)
|
||||||
|
{
|
||||||
|
auto descriptor = DiscIO::ParseGameModDescriptorFile(m_file_path);
|
||||||
|
if (descriptor)
|
||||||
|
{
|
||||||
|
GameFile proxy(descriptor->base_file);
|
||||||
|
if (proxy.IsValid())
|
||||||
|
hash = proxy.GetSyncHash();
|
||||||
|
|
||||||
|
// add patches to hash if they're enabled
|
||||||
|
if (descriptor->riivolution)
|
||||||
|
{
|
||||||
|
for (const auto& patch : descriptor->riivolution->patches)
|
||||||
|
{
|
||||||
|
hash = MixHash(hash, GetFileHash(patch.xml));
|
||||||
|
for (const auto& option : patch.options)
|
||||||
|
{
|
||||||
|
hash = MixHash(hash, GetHash(option.section_name));
|
||||||
|
hash = MixHash(hash, GetHash(option.option_id));
|
||||||
|
hash = MixHash(hash, GetHash(option.option_name));
|
||||||
|
hash = MixHash(hash, GetHash(option.choice));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -640,7 +701,7 @@ std::array<u8, 20> GameFile::GetSyncHash() const
|
||||||
hash = volume->GetSyncHash();
|
hash = volume->GetSyncHash();
|
||||||
}
|
}
|
||||||
|
|
||||||
return hash;
|
return hash.value_or(std::array<u8, 20>{});
|
||||||
}
|
}
|
||||||
|
|
||||||
NetPlay::SyncIdentifier GameFile::GetSyncIdentifier() const
|
NetPlay::SyncIdentifier GameFile::GetSyncIdentifier() const
|
||||||
|
|
Loading…
Reference in New Issue