mirror of
https://github.com/zhenyan121/Cubed.git
synced 2026-08-08 17:57:02 +08:00
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.
This commit is contained in:
@@ -17,11 +17,11 @@ set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
|
|||||||
if(MSVC)
|
if(MSVC)
|
||||||
add_compile_options(/utf-8)
|
add_compile_options(/utf-8)
|
||||||
endif()
|
endif()
|
||||||
|
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules")
|
||||||
find_package(OpenGL REQUIRED)
|
find_package(OpenGL REQUIRED)
|
||||||
find_package(Protobuf REQUIRED)
|
find_package(Protobuf REQUIRED)
|
||||||
find_package(absl REQUIRED)
|
find_package(absl REQUIRED)
|
||||||
find_package(ZLIB REQUIRED)
|
find_package(zstd REQUIRED)
|
||||||
|
|
||||||
if (UNIX AND NOT APPLE)
|
if (UNIX AND NOT APPLE)
|
||||||
find_package(Freetype REQUIRED)
|
find_package(Freetype REQUIRED)
|
||||||
@@ -208,7 +208,7 @@ target_link_libraries(${PROJECT_NAME}
|
|||||||
protobuf::libprotobuf
|
protobuf::libprotobuf
|
||||||
absl::log
|
absl::log
|
||||||
absl::check
|
absl::check
|
||||||
ZLIB::ZLIB
|
zstd::zstd
|
||||||
)
|
)
|
||||||
|
|
||||||
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
||||||
|
|||||||
22
cmake/modules/Findzstd.cmake
Normal file
22
cmake/modules/Findzstd.cmake
Normal file
@@ -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()
|
||||||
@@ -1,12 +1,41 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "packet.pb.h" // IWYU pragma: keep
|
#include "packet.pb.h" // IWYU pragma: keep
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <cstring>
|
||||||
|
#include <memory>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
|
#include <stdexcept>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
namespace Cubed {
|
namespace Cubed {
|
||||||
constexpr int HEADER_LEN = 8;
|
constexpr int HEADER_LEN = 12;
|
||||||
using Packet = std::shared_ptr<std::vector<uint8_t>>;
|
using Packet = std::shared_ptr<std::vector<uint8_t>>;
|
||||||
|
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<CompressType>;
|
||||||
|
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 {
|
enum class PacketEnum {
|
||||||
LOGIN_REQ = 1001,
|
LOGIN_REQ = 1001,
|
||||||
@@ -59,7 +88,7 @@ template <typename T> constexpr uint16_t get_packet_id() {
|
|||||||
return to_num(UPDATE_TIME);
|
return to_num(UPDATE_TIME);
|
||||||
} else if constexpr (is_same_v<U, Ping>) {
|
} else if constexpr (is_same_v<U, Ping>) {
|
||||||
return to_num(PING);
|
return to_num(PING);
|
||||||
} else if (is_same_v<U, Pong>) {
|
} else if constexpr (is_same_v<U, Pong>) {
|
||||||
return to_num(PONG);
|
return to_num(PONG);
|
||||||
} else {
|
} else {
|
||||||
static_assert(always_false<U>::value, "Unkonw Type");
|
static_assert(always_false<U>::value, "Unkonw Type");
|
||||||
@@ -67,27 +96,54 @@ template <typename T> constexpr uint16_t get_packet_id() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename T> Packet make_packet(const T& msg) {
|
template <typename T> Packet make_packet(const T& msg) {
|
||||||
uint16_t cmd = get_packet_id<T>();
|
PacketHeader header{};
|
||||||
|
header.cmd = get_packet_id<T>();
|
||||||
|
uint32_t size = static_cast<uint32_t>(msg.ByteSizeLong());
|
||||||
|
header.uncompressed_size = size;
|
||||||
|
header.compressed_size = size;
|
||||||
|
header.compress_type = CompressType::NONE;
|
||||||
|
|
||||||
uint32_t body_len = static_cast<uint32_t>(msg.ByteSizeLong());
|
auto packet = std::make_shared<std::vector<uint8_t>>(
|
||||||
|
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<std::vector<uint8_t>>(total_len);
|
std::memcpy(packet->data(), &cmd_net, sizeof(cmd_net));
|
||||||
|
|
||||||
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() + 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,
|
if (!msg.SerializeToArray(packet->data() + HEADER_LEN,
|
||||||
static_cast<int>(body_len))) {
|
static_cast<int>(size))) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
return packet;
|
return packet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline PacketHeader
|
||||||
|
decode_packet_header(const std::array<char, HEADER_LEN>& 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
|
} // namespace Cubed
|
||||||
|
|||||||
@@ -113,7 +113,7 @@ void DevPanel::show_about_table_bar() {
|
|||||||
ImGui::Text("Tbb");
|
ImGui::Text("Tbb");
|
||||||
ImGui::Text("Asio");
|
ImGui::Text("Asio");
|
||||||
ImGui::Text("protobuf");
|
ImGui::Text("protobuf");
|
||||||
ImGui::Text("zlib");
|
ImGui::Text("zstd");
|
||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
ImGui::Text("Special Thanks");
|
ImGui::Text("Special Thanks");
|
||||||
ImGui::Text("TANGERIME");
|
ImGui::Text("TANGERIME");
|
||||||
|
|||||||
Reference in New Issue
Block a user