Hash system fixes
This commit is contained in:
parent
ce12f0d9f5
commit
2db853c4c1
@ -8,6 +8,8 @@
|
||||
|
||||
#include "game/ui_scripting/execution.hpp"
|
||||
|
||||
#include "utils/hash.hpp"
|
||||
|
||||
#include <utils/concurrency.hpp>
|
||||
#include <utils/http.hpp>
|
||||
#include <utils/io.hpp>
|
||||
@ -165,7 +167,7 @@ namespace download
|
||||
|
||||
const auto url = utils::string::va("%s/%s", base.data(), file.name.data());
|
||||
console::debug("Downloading %s from %s: %s\n", file.name.data(), base.data(), url);
|
||||
const auto data = utils::http::get_data(url, {}, {}, &progress_callback);
|
||||
auto data = utils::http::get_data(url, {}, {}, &progress_callback);
|
||||
if (!data.has_value())
|
||||
{
|
||||
menu_error("Download failed: An unknown error occurred, please try again.");
|
||||
@ -177,7 +179,7 @@ namespace download
|
||||
return;
|
||||
}
|
||||
|
||||
const auto& result = data.value();
|
||||
auto& result = data.value();
|
||||
if (result.code != CURLE_OK)
|
||||
{
|
||||
menu_error(utils::string::va("Download failed: %s (%i)\n",
|
||||
@ -192,7 +194,7 @@ namespace download
|
||||
return;
|
||||
}
|
||||
|
||||
const auto hash = utils::cryptography::sha1::compute(result.buffer, true);
|
||||
const auto hash = utils::hash::get_buffer_hash(result.buffer, file.name);
|
||||
if (hash != file.hash)
|
||||
{
|
||||
menu_error(utils::string::va("Download failed: file hash doesn't match the server's (%s: %s != %s)\n",
|
||||
|
@ -211,7 +211,11 @@ namespace party
|
||||
}
|
||||
|
||||
const auto hash = utils::hash::get_file_hash(file);
|
||||
hash_cache.insert(std::make_pair(file, hash));
|
||||
if (!hash.empty())
|
||||
{
|
||||
hash_cache.insert(std::make_pair(file, hash));
|
||||
}
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
@ -271,6 +275,7 @@ namespace party
|
||||
}
|
||||
|
||||
const auto hash = get_file_hash(filename);
|
||||
console::debug("hash != source_hash => %s != %s\n", source_hash.data(), hash.data());
|
||||
if (hash != source_hash)
|
||||
{
|
||||
files.emplace_back(filename, source_hash);
|
||||
@ -327,6 +332,7 @@ namespace party
|
||||
if (!has_to_download)
|
||||
{
|
||||
const auto hash = get_file_hash(file_path);
|
||||
console::debug("has_to_download = %s != %s\n", source_hash.data(), hash.data());
|
||||
has_to_download = source_hash != hash;
|
||||
}
|
||||
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include "game/game.hpp"
|
||||
|
||||
#include "hash.hpp"
|
||||
#include "component/console.hpp"
|
||||
|
||||
#include <zlib.h>
|
||||
#include <utils/cryptography.hpp>
|
||||
@ -30,6 +31,8 @@ namespace utils::hash
|
||||
game::DB_AuthHash empty_hash{};
|
||||
if (!std::memcmp(header.hash.bytes, empty_hash.bytes, hash_size))
|
||||
{
|
||||
console::warn("Computing pakfile hash because its missing, this may take some time...\n");
|
||||
|
||||
hash_state state;
|
||||
sha256_init(&state);
|
||||
|
||||
@ -82,6 +85,40 @@ namespace utils::hash
|
||||
hash.append(reinterpret_cast<char*>(&crc_value), sizeof(crc_value));
|
||||
return utils::string::dump_hex(hash, "");
|
||||
}
|
||||
|
||||
std::string get_pakfile_buffer_hash(std::string& buffer)
|
||||
{
|
||||
if (buffer.size() < sizeof(game::XPakHeader))
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
constexpr auto hash_size = sizeof(game::DB_AuthHash);
|
||||
const auto header = reinterpret_cast<game::XPakHeader*>(buffer.data());
|
||||
|
||||
game::DB_AuthHash empty_hash{};
|
||||
if (!std::memcmp(header->hash.bytes, empty_hash.bytes, hash_size))
|
||||
{
|
||||
console::warn("Computing pakfile hash because its missing, this may take some time...\n");
|
||||
const auto hash_start = reinterpret_cast<std::uint8_t*>(buffer.data() + sizeof(game::XPakHeader));
|
||||
const auto len = buffer.size() - sizeof(game::XPakHeader);
|
||||
const auto hash = utils::cryptography::sha256::compute(hash_start, len, false);
|
||||
std::memcpy(header->hash.bytes, hash.data(), sizeof(header->hash));
|
||||
}
|
||||
|
||||
std::string hash = {header->hash.bytes, header->hash.bytes + hash_size};
|
||||
return utils::string::dump_hex(hash, "");
|
||||
}
|
||||
|
||||
std::string get_generic_buffer_hash(const std::string& buffer)
|
||||
{
|
||||
auto crc_value = crc32(0L, Z_NULL, 0);
|
||||
crc_value = crc32(crc_value, reinterpret_cast<const std::uint8_t*>(buffer.data()),
|
||||
static_cast<std::uint32_t>(buffer.size()));
|
||||
std::string hash;
|
||||
hash.append(reinterpret_cast<char*>(&crc_value), sizeof(crc_value));
|
||||
return utils::string::dump_hex(hash, "");
|
||||
}
|
||||
}
|
||||
|
||||
std::string get_file_hash(const std::string& file)
|
||||
@ -105,4 +142,16 @@ namespace utils::hash
|
||||
return get_file_hash_generic(file_stream, file_size);
|
||||
}
|
||||
}
|
||||
|
||||
std::string get_buffer_hash(std::string& buffer, const std::string& filename)
|
||||
{
|
||||
if (filename.ends_with(".pak"))
|
||||
{
|
||||
return get_pakfile_buffer_hash(buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
return get_generic_buffer_hash(buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,4 +3,5 @@
|
||||
namespace utils::hash
|
||||
{
|
||||
std::string get_file_hash(const std::string& file);
|
||||
std::string get_buffer_hash(std::string& buffer, const std::string& filename);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user