#pragma once #include "packet.pb.h" // IWYU pragma: keep #include #include #include namespace Cubed { constexpr int HEADER_LEN = 8; using Packet = std::shared_ptr>; 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 struct always_false : std::false_type {}; // NOLINT template constexpr uint16_t get_packet_id() { using enum PacketEnum; using std::is_same_v; using U = std::decay_t; constexpr auto& to_num = std::to_underlying; if constexpr (is_same_v) { return to_num(LOGIN_REQ); } else if constexpr (is_same_v) { return to_num(LOGIN_RSP); } else if constexpr (is_same_v) { return to_num(LOGOUT_REQ); } else if constexpr (is_same_v) { return to_num(LOGOUT_RSP); } else if constexpr (is_same_v) { return to_num(PLAYER_INFO); } else if constexpr (is_same_v) { return to_num(PLAYER_POS); } else if constexpr (is_same_v) { return to_num(PLAYER_INFO_RSP); } else if constexpr (is_same_v) { return to_num(CHUNK_DATA_REQ); } else if constexpr (is_same_v) { return to_num(CHUNK_DATA_RSP); } else if constexpr (is_same_v) { return to_num(BLOCK_CHANGE_REQ); } else if constexpr (is_same_v) { return to_num(BLOCK_CHANGE_RSP); } else if constexpr (is_same_v) { return to_num(UPDATE_TIME); } else if constexpr (is_same_v) { return to_num(PING); } else if (is_same_v) { return to_num(PONG); } else { static_assert(always_false::value, "Unkonw Type"); } } template Packet make_packet(const T& msg) { uint16_t cmd = get_packet_id(); uint32_t body_len = static_cast(msg.ByteSizeLong()); uint32_t total_len = HEADER_LEN + body_len; 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)); if (!msg.SerializeToArray(packet->data() + HEADER_LEN, static_cast(body_len))) { return {}; } return packet; } } // namespace Cubed