diff --git a/external/gamekit b/external/gamekit index a38978145..feb628bd9 160000 --- a/external/gamekit +++ b/external/gamekit @@ -1 +1 @@ -Subproject commit a389781453383c9760354647b2af9a30b4cee7f2 +Subproject commit feb628bd90c8e29d4cad8a1dfd086f163ffd4434 diff --git a/source/common/network/CompressedPacket.cpp b/source/common/network/CompressedPacket.cpp index fa561368b..c7b0a9e14 100644 --- a/source/common/network/CompressedPacket.cpp +++ b/source/common/network/CompressedPacket.cpp @@ -26,11 +26,63 @@ */ #include +#include + #include "CompressedPacket.hpp" // Note: This class was implemented thanks to this SFML forum topic: // https://en.sfml-dev.org/forums/index.php?topic=14344.0 +#include +#include +#include +#include + +template>> +container_type arrange_bytes(const byte_type* buffer, const std::size_t size, const std::size_t w = 16) { + return std::accumulate(buffer, buffer + size, container_type{{}}, [w](auto& acc, const byte_type byte) { + if(acc.back().size() >= w) { + acc.push_back({}); + } + acc.back().push_back(byte); + return acc; + }); +} + +std::string init_text_row(const int offset) { + std::ostringstream ost{}; + ost << std::hex << std::setfill('0') << std::setw(8) << offset; + return ost.str(); +} + +template +std::string format_row(const std::vector& bytes, const int offset) { + auto init = init_text_row(offset); + return std::accumulate(bytes.begin(), bytes.end(), init, [](auto& acc, const auto& byte) { + std::ostringstream ost{}; + ost << ' ' << std::hex << std::setfill('0') << static_cast(byte); + return acc + ost.str(); + }); +} + +template>> +std::string format_bytes(const container_type& bytes) { + struct memory { + std::string data = {}; + int offset = 0; + }; + return std::accumulate(bytes.begin(), bytes.end(), memory{}, [](auto& acc, const auto& row) { + acc.data += format_row(row, acc.offset) + '\n'; + acc.offset += row.size(); + return acc; + }).data; +} + +template +std::string hexdump(const byte_type* buffer, std::size_t size) { + return format_bytes(arrange_bytes(buffer, size)); +} + const void* CompressedPacket::onSend(std::size_t& size) { // We only support data with a maximum size of // an unsigned short (so the size can be sent @@ -57,7 +109,11 @@ const void* CompressedPacket::onSend(std::size_t& size) { m_compressionBuffer[1] = (srcSize >> 8) & 0xFF; // Compress the data into the rest of the buffer - compress(m_compressionBuffer.data() + 2, &dstSize, srcData, srcSize); + int result = compress(m_compressionBuffer.data() + 2, &dstSize, srcData, srcSize); + if (result != Z_OK) + gkError() << "Failed to compress packet"; + + // hexdump(srcData, srcSize); // Set the size to the compressed size plus // two bytes for the size marker @@ -79,10 +135,14 @@ void CompressedPacket::onReceive(const void* data, std::size_t size) { m_compressionBuffer.resize(uncompressedSize); // Declare a variable for the destination size - uLong dstSize; + uLong dstSize = uncompressedSize; // Uncompress the data (remove the first two bytes) - uncompress(m_compressionBuffer.data(), &dstSize, (srcData + 2), size - 2); + int result = uncompress(m_compressionBuffer.data(), &dstSize, (srcData + 2), size - 2); + if (result != Z_OK) + gkError() << "Failed to uncompress packet"; + + // hexdump(m_compressionBuffer.data(), dstSize); // Assert that the uncompressed size is the same as the // size we were sent for the buffer