From db7b67f2655295fcf2a6e7af753c65a5bff90393 Mon Sep 17 00:00:00 2001 From: zhenyan121 <3367366583@qq.com> Date: Fri, 26 Jun 2026 19:12:39 +0800 Subject: [PATCH] refactor(packet): replace zlib with zstd compression and restructure header Increase header length to 12 bytes, add CompressType and PacketHeader struct, and implement decode_packet_header. Update CMake to find zstd and link against it, adding Findzstd module. --- CMakeLists.txt | 6 +-- cmake/modules/Findzstd.cmake | 22 ++++++++ include/Cubed/gameplay/packet.hpp | 84 +++++++++++++++++++++++++------ src/dev_panel.cpp | 2 +- 4 files changed, 96 insertions(+), 18 deletions(-) create mode 100644 cmake/modules/Findzstd.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 2710e62..207273c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -17,11 +17,11 @@ set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) if(MSVC) add_compile_options(/utf-8) endif() - +list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules") find_package(OpenGL REQUIRED) find_package(Protobuf REQUIRED) find_package(absl REQUIRED) -find_package(ZLIB REQUIRED) +find_package(zstd REQUIRED) if (UNIX AND NOT APPLE) find_package(Freetype REQUIRED) @@ -208,7 +208,7 @@ target_link_libraries(${PROJECT_NAME} protobuf::libprotobuf absl::log absl::check - ZLIB::ZLIB + zstd::zstd ) if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang") diff --git a/cmake/modules/Findzstd.cmake b/cmake/modules/Findzstd.cmake new file mode 100644 index 0000000..4d8a415 --- /dev/null +++ b/cmake/modules/Findzstd.cmake @@ -0,0 +1,22 @@ +find_path(ZSTD_INCLUDE_DIRS + NAMES zstd.h + HINTS ${zstd_ROOT_DIR}/include) + +find_library(ZSTD_LIBRARIES + NAMES zstd + HINTS ${zstd_ROOT_DIR}/lib) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(zstd DEFAULT_MSG ZSTD_LIBRARIES ZSTD_INCLUDE_DIRS) + +mark_as_advanced( + ZSTD_LIBRARIES + ZSTD_INCLUDE_DIRS) + +if(ZSTD_FOUND AND NOT (TARGET zstd::zstd)) + add_library (zstd::zstd UNKNOWN IMPORTED) + set_target_properties(zstd::zstd + PROPERTIES + IMPORTED_LOCATION ${ZSTD_LIBRARIES} + INTERFACE_INCLUDE_DIRECTORIES ${ZSTD_INCLUDE_DIRS}) +endif() \ No newline at end of file diff --git a/include/Cubed/gameplay/packet.hpp b/include/Cubed/gameplay/packet.hpp index c57f827..5e7b764 100644 --- a/include/Cubed/gameplay/packet.hpp +++ b/include/Cubed/gameplay/packet.hpp @@ -1,12 +1,41 @@ #pragma once #include "packet.pb.h" // IWYU pragma: keep +#include +#include +#include +#include #include +#include #include #include + namespace Cubed { -constexpr int HEADER_LEN = 8; +constexpr int HEADER_LEN = 12; using Packet = std::shared_ptr>; +enum class CompressType : uint16_t { + NONE = 0, + ZSTD = 1, +}; + +inline CompressType get_compress_type(uint16_t id) { + using enum CompressType; + constexpr auto& to = std::to_underlying; + switch (id) { + case to(NONE): + return NONE; + case to(ZSTD): + return ZSTD; + } + throw std::runtime_error(std::format("Unkown CompressType {}", id)); +} + +struct PacketHeader { + uint16_t cmd; + CompressType compress_type; // 0=none 1=zlib + uint32_t uncompressed_size; + uint32_t compressed_size; +}; enum class PacketEnum { LOGIN_REQ = 1001, @@ -59,7 +88,7 @@ template constexpr uint16_t get_packet_id() { return to_num(UPDATE_TIME); } else if constexpr (is_same_v) { return to_num(PING); - } else if (is_same_v) { + } else if constexpr (is_same_v) { return to_num(PONG); } else { static_assert(always_false::value, "Unkonw Type"); @@ -67,27 +96,54 @@ template constexpr uint16_t get_packet_id() { } template Packet make_packet(const T& msg) { - uint16_t cmd = get_packet_id(); + PacketHeader header{}; + header.cmd = get_packet_id(); + uint32_t size = static_cast(msg.ByteSizeLong()); + header.uncompressed_size = size; + header.compressed_size = size; + header.compress_type = CompressType::NONE; - uint32_t body_len = static_cast(msg.ByteSizeLong()); + auto packet = std::make_shared>( + HEADER_LEN + header.compressed_size); - uint32_t total_len = HEADER_LEN + body_len; + uint16_t cmd_net = htons(header.cmd); + uint16_t compress_type_net = + htons(std::to_underlying(header.compress_type)); + uint32_t uncompressed_size_net = htonl(header.uncompressed_size); + uint32_t compressed_size_net = htonl(header.compressed_size); - auto packet = std::make_shared>(total_len); - - uint32_t total_len_net = htonl(total_len); - uint16_t cmd_net = htons(cmd); - - std::memcpy(packet->data(), &total_len_net, sizeof(total_len_net)); - - std::memcpy(packet->data() + 4, &cmd_net, sizeof(cmd_net)); + std::memcpy(packet->data(), &cmd_net, sizeof(cmd_net)); + std::memcpy(packet->data() + 2, &compress_type_net, + sizeof(compress_type_net)); + std::memcpy(packet->data() + 4, &uncompressed_size_net, + sizeof(uncompressed_size_net)); + std::memcpy(packet->data() + 8, &compressed_size_net, + sizeof(compressed_size_net)); if (!msg.SerializeToArray(packet->data() + HEADER_LEN, - static_cast(body_len))) { + static_cast(size))) { return {}; } return packet; } +inline PacketHeader +decode_packet_header(const std::array& header) { + uint16_t cmd_net; + uint16_t compress_type_net; + uint32_t uncompressed_size_net; + uint32_t compressed_size_net; + std::memcpy(&cmd_net, header.data(), sizeof(cmd_net)); + std::memcpy(&compress_type_net, header.data() + 2, + sizeof(compress_type_net)); + std::memcpy(&uncompressed_size_net, header.data() + 4, + sizeof(uncompressed_size_net)); + std::memcpy(&compressed_size_net, header.data() + 8, + sizeof(compressed_size_net)); + + return {ntohs(cmd_net), get_compress_type(ntohs(compress_type_net)), + ntohl(uncompressed_size_net), ntohl(compressed_size_net)}; +} + } // namespace Cubed diff --git a/src/dev_panel.cpp b/src/dev_panel.cpp index acf3ea2..46dfdf3 100644 --- a/src/dev_panel.cpp +++ b/src/dev_panel.cpp @@ -113,7 +113,7 @@ void DevPanel::show_about_table_bar() { ImGui::Text("Tbb"); ImGui::Text("Asio"); ImGui::Text("protobuf"); - ImGui::Text("zlib"); + ImGui::Text("zstd"); ImGui::Separator(); ImGui::Text("Special Thanks"); ImGui::Text("TANGERIME");