Skip to content

Commit

Permalink
Hash system fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
alicealys committed Dec 13, 2023
1 parent ce12f0d commit 2db853c
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 4 deletions.
8 changes: 5 additions & 3 deletions src/client/component/download.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down Expand Up @@ -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.");
Expand All @@ -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",
Expand All @@ -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",
Expand Down
8 changes: 7 additions & 1 deletion src/client/component/party.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
}

Expand Down
49 changes: 49 additions & 0 deletions src/client/utils/hash.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include "game/game.hpp"

#include "hash.hpp"
#include "component/console.hpp"

#include <zlib.h>
#include <utils/cryptography.hpp>
Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -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)
Expand All @@ -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);
}
}
}
1 change: 1 addition & 0 deletions src/client/utils/hash.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

0 comments on commit 2db853c

Please sign in to comment.