mirror of
https://github.com/zhenyan121/Cubed.git
synced 2026-08-08 17:57:02 +08:00
94 lines
2.8 KiB
C++
94 lines
2.8 KiB
C++
#pragma once
|
|
#include "packet.pb.h" // IWYU pragma: keep
|
|
|
|
#include <netinet/in.h>
|
|
#include <type_traits>
|
|
#include <utility>
|
|
namespace Cubed {
|
|
constexpr int HEADER_LEN = 8;
|
|
using Packet = std::shared_ptr<std::vector<uint8_t>>;
|
|
|
|
enum class PacketEnum {
|
|
LOGIN_REQ = 1001,
|
|
LOGIN_RSP = 1002,
|
|
LOGOUT_REQ = 1003,
|
|
LOGOUT_RSP = 1004,
|
|
PLAYER_INFO = 2001,
|
|
PLAYER_POS = 2002,
|
|
PLAYER_INFO_RSP = 2003,
|
|
CHUNK_DATA_REQ = 3001,
|
|
CHUNK_DATA_RSP = 3002,
|
|
BLOCK_CHANGE_REQ = 3003,
|
|
BLOCK_CHANGE_RSP = 3004,
|
|
UPDATE_TIME = 3005,
|
|
PING = 9001,
|
|
PONG = 9002
|
|
|
|
};
|
|
|
|
template <typename> struct always_false : std::false_type {}; // NOLINT
|
|
template <typename T> constexpr uint16_t get_packet_id() {
|
|
using enum PacketEnum;
|
|
using std::is_same_v;
|
|
|
|
using U = std::decay_t<T>;
|
|
constexpr auto& to_num = std::to_underlying<PacketEnum>;
|
|
if constexpr (is_same_v<U, LoginReq>) {
|
|
return to_num(LOGIN_REQ);
|
|
} else if constexpr (is_same_v<U, LoginRsp>) {
|
|
return to_num(LOGIN_RSP);
|
|
} else if constexpr (is_same_v<U, LogoutReq>) {
|
|
return to_num(LOGOUT_REQ);
|
|
} else if constexpr (is_same_v<U, LogoutRsp>) {
|
|
return to_num(LOGOUT_RSP);
|
|
} else if constexpr (is_same_v<U, PlayerInfo>) {
|
|
return to_num(PLAYER_INFO);
|
|
} else if constexpr (is_same_v<U, PlayerPos>) {
|
|
return to_num(PLAYER_POS);
|
|
} else if constexpr (is_same_v<U, PlayerInfoRsp>) {
|
|
return to_num(PLAYER_INFO_RSP);
|
|
} else if constexpr (is_same_v<U, ChunkDataReq>) {
|
|
return to_num(CHUNK_DATA_REQ);
|
|
} else if constexpr (is_same_v<U, ChunkDataRsp>) {
|
|
return to_num(CHUNK_DATA_RSP);
|
|
} else if constexpr (is_same_v<U, BlockChangeReq>) {
|
|
return to_num(BLOCK_CHANGE_REQ);
|
|
} else if constexpr (is_same_v<U, BlockChangeRsp>) {
|
|
return to_num(BLOCK_CHANGE_RSP);
|
|
} else if constexpr (is_same_v<U, UpdateTime>) {
|
|
return to_num(UPDATE_TIME);
|
|
} else if constexpr (is_same_v<U, Ping>) {
|
|
return to_num(PING);
|
|
} else if (is_same_v<U, Pong>) {
|
|
return to_num(PONG);
|
|
} else {
|
|
static_assert(always_false<U>::value, "Unkonw Type");
|
|
}
|
|
}
|
|
|
|
template <typename T> Packet make_packet(const T& msg) {
|
|
uint16_t cmd = get_packet_id<T>();
|
|
|
|
uint32_t body_len = static_cast<uint32_t>(msg.ByteSizeLong());
|
|
|
|
uint32_t total_len = HEADER_LEN + body_len;
|
|
|
|
auto packet = std::make_shared<std::vector<uint8_t>>(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));
|
|
|
|
if (!msg.SerializeToArray(packet->data() + HEADER_LEN,
|
|
static_cast<int>(body_len))) {
|
|
return {};
|
|
}
|
|
|
|
return packet;
|
|
}
|
|
|
|
} // namespace Cubed
|