From 9d46c678f45f2b6161a0f9764136fb82f217e348 Mon Sep 17 00:00:00 2001 From: Choi Yusun <43121372+ggstone0523@users.noreply.github.com> Date: Thu, 12 Mar 2026 18:15:26 +0900 Subject: [PATCH 01/14] [Refact] Change recv method non-blocking only to poll --- .../lobby_network/window_lobby_network.hpp | 1 + .../window/include/network/window_network.hpp | 4 +- .../lobby_network/window_lobby_network.cpp | 95 +++++++++++-------- .../window/source/network/window_network.cpp | 40 ++++---- 4 files changed, 75 insertions(+), 65 deletions(-) diff --git a/platform/window/include/lobby_network/window_lobby_network.hpp b/platform/window/include/lobby_network/window_lobby_network.hpp index 7702b5b3..c4680b55 100644 --- a/platform/window/include/lobby_network/window_lobby_network.hpp +++ b/platform/window/include/lobby_network/window_lobby_network.hpp @@ -14,6 +14,7 @@ class WindowLobbyNetwork : public ILobbyNetwork { private: SOCKET sock; + WSAPOLLFD fds[1]; void write_32b(uint8_t*& p, int32_t v); void write_bytes(uint8_t*& p, const void* data, size_t size); diff --git a/platform/window/include/network/window_network.hpp b/platform/window/include/network/window_network.hpp index 3a7be611..18972f22 100644 --- a/platform/window/include/network/window_network.hpp +++ b/platform/window/include/network/window_network.hpp @@ -19,11 +19,11 @@ class WindowNetwork : public INetwork SOCKET client_sock; SOCKET server_sock; - // [window] epoll 관련 변수(epfd, events)는 삭제했습니다. - // 대신 수신 주소 정보를 저장할 구조체를 미리 선언해두면 편합니다. SOCKADDR_IN server_addr; SOCKADDR_IN client_addr; + WSAPOLLFD fds[1]; + void write_32b(uint8_t*& p, int32_t v); void write_bytes(uint8_t*& p, const void* data, size_t size); void serialize(uint8_t* buf, const Packet& pkt); diff --git a/platform/window/source/lobby_network/window_lobby_network.cpp b/platform/window/source/lobby_network/window_lobby_network.cpp index 33183cf0..f444dbb4 100644 --- a/platform/window/source/lobby_network/window_lobby_network.cpp +++ b/platform/window/source/lobby_network/window_lobby_network.cpp @@ -46,6 +46,10 @@ WindowLobbyNetwork::WindowLobbyNetwork() perror("bind failed: "); exit(0); } + + // 8. Poll + fds[0].fd = sock; + fds[0].events = POLLIN; } /** @@ -239,34 +243,39 @@ bool WindowLobbyNetwork::recv_udp(user_data& ud, char* ip) int addr_len; uint8_t buf[USER_DATA_SIZE]; int recv_result; - int recv_err; + bool data_received = false; ZeroMemory(&addr, sizeof(addr)); addr_len = sizeof(addr); memset(buf, 0, sizeof(buf)); - - recv_result = recvfrom(sock, (char*) buf, sizeof(buf), 0, (SOCKADDR*) &addr, &addr_len); - recv_err = (recv_result == SOCKET_ERROR) ? WSAGetLastError() : 0; - if (recv_result == SOCKET_ERROR) { - if (recv_err == WSAEWOULDBLOCK || recv_err == WSAEMSGSIZE) - // ̻ Ͱ ( ) - return false; - else { - // ¥ ߻ - printf("recvfrom failed: %d\n", recv_err); - return false; - } - } - else if (recv_result != USER_DATA_SIZE) - return false; - inet_ntop(AF_INET, &addr.sin_addr, ip, 16); - deserialize(buf, ud); + // [window Poll ó] + int ret = WSAPoll(fds, 1, 0); + + if (ret > 0) { + if (fds[0].revents & POLLIN) { + recv_result = recvfrom(sock, (char*) buf, sizeof(buf), 0, (SOCKADDR*) &addr, + &addr_len); - if (ud.magic != USER_DATA_MAGIC) - return false; + if (recv_result == SOCKET_ERROR) { + int err = WSAGetLastError(); + printf("recvfrom failed: %d\n", err); + return false; + } + else if (recv_result != USER_DATA_SIZE) + return false; - return true; + // + inet_ntop(AF_INET, &addr.sin_addr, ip, 16); + deserialize(buf, ud); + + if (ud.magic != USER_DATA_MAGIC) data_received = false; + + data_received = true; + } + } + + return data_received; } void WindowLobbyNetwork::send_udp(const char* room_master_id, @@ -315,34 +324,38 @@ bool WindowLobbyNetwork::recv_udp(room_data& rd, char* ip) int addr_len; uint8_t buf[ROOM_DATA_SIZE]; int recv_result; - int recv_err; + bool data_received = false; ZeroMemory(&addr, sizeof(addr)); addr_len = sizeof(addr); memset(buf, 0, sizeof(buf)); - recv_result = recvfrom(sock, (char*) buf, sizeof(buf), 0, (SOCKADDR*) &addr, &addr_len); - recv_err = (recv_result == SOCKET_ERROR) ? WSAGetLastError() : 0; - if (recv_result == SOCKET_ERROR) { - if (recv_err == WSAEWOULDBLOCK || recv_err == WSAEMSGSIZE) - // ̻ Ͱ ( ) - return false; - else { - // ¥ ߻ - printf("recvfrom failed: %d\n", recv_err); - return false; - } - } - else if (recv_result != ROOM_DATA_SIZE) - return false; + // [window Poll ó] + int ret = WSAPoll(fds, 1, 0); + + if (ret > 0) { + if (fds[0].revents & POLLIN) { + recv_result = recvfrom(sock, (char*) buf, sizeof(buf), 0, (SOCKADDR*) &addr, &addr_len); - inet_ntop(AF_INET, &addr.sin_addr, ip, 16); - deserialize(buf, rd); + if (recv_result == SOCKET_ERROR) { + int err = WSAGetLastError(); + printf("recvfrom failed: %d\n", err); + return false; + } + else if (recv_result != ROOM_DATA_SIZE) + return false; - if (rd.magic != ROOM_DATA_MAGIC) - return false; + // + inet_ntop(AF_INET, &addr.sin_addr, ip, 16); + deserialize(buf, rd); + + if (rd.magic != ROOM_DATA_MAGIC) data_received = false; + + data_received = true; + } + } - return true; + return data_received; } void WindowLobbyNetwork::send_multi_udp( diff --git a/platform/window/source/network/window_network.cpp b/platform/window/source/network/window_network.cpp index 09c7731c..12bef561 100644 --- a/platform/window/source/network/window_network.cpp +++ b/platform/window/source/network/window_network.cpp @@ -51,8 +51,9 @@ WindowNetwork::WindowNetwork() exit(0); } - // window에는 epoll이 없으므로 epoll 생성 코드는 삭제됩니다. - // 대신 recv_udp에서 논블로킹 소켓의 특성을 이용합니다. + // 6. Poll + fds[0].fd = server_sock; + fds[0].events = POLLIN; } void WindowNetwork::write_32b(uint8_t*& p, int32_t v) @@ -227,32 +228,27 @@ bool WindowNetwork::recv_udp(Packet& recv_pkt) SOCKADDR_IN client_addr; int addr_len = sizeof(client_addr); - // [window Non-blocking 처리] - // epoll 대신 루프를 돌며 쌓인 패킷을 모두 처리하고 가장 최신 것을 가져옵니다. - while (true) { - int r = - recvfrom(server_sock, (char*) buf, PACKET_SIZE, 0, (SOCKADDR*) &client_addr, &addr_len); - - if (r == SOCKET_ERROR) { - int err = WSAGetLastError(); - if (err == WSAEWOULDBLOCK) { - // 더 이상 읽을 데이터가 없음 (버퍼 비워짐) - break; - } - else { - // 진짜 에러 발생 + // [window Poll 처리] + int ret = WSAPoll(fds, 1, 0); + + if (ret > 0) { + if (fds[0].revents & POLLIN) { + int r = recvfrom(server_sock, (char*) buf, PACKET_SIZE, 0, (SOCKADDR*) &client_addr, + &addr_len); + + if (r == SOCKET_ERROR) { + int err = WSAGetLastError(); cerr << "recvfrom failed: " << err << "\n"; return false; } - } - // 데이터 수신 성공 - deserialize(buf, recv_pkt); + // 데이터 수신 성공 + deserialize(buf, recv_pkt); - if (recv_pkt.magic != PACKET_MAGIC) - data_received = false; + if (recv_pkt.magic != PACKET_MAGIC) data_received = false; - data_received = true; + data_received = true; + } } return data_received; From 5bce4efa3b18c6536f95e96318bc1d182741713e Mon Sep 17 00:00:00 2001 From: Choi Yusun <43121372+ggstone0523@users.noreply.github.com> Date: Fri, 13 Mar 2026 12:38:22 +0900 Subject: [PATCH 02/14] [Refact] Change serialization logic --- core/include/util/network_packet.hpp | 47 +++-- .../linux/include/network/linux_network.hpp | 4 +- .../linux/source/network/linux_network.cpp | 182 ++++++++++++++---- .../window/include/network/window_network.hpp | 4 +- .../window/source/network/window_network.cpp | 181 +++++++++++++---- 5 files changed, 320 insertions(+), 98 deletions(-) diff --git a/core/include/util/network_packet.hpp b/core/include/util/network_packet.hpp index 3b86f43a..6af0e3e8 100644 --- a/core/include/util/network_packet.hpp +++ b/core/include/util/network_packet.hpp @@ -2,19 +2,44 @@ #define __PACKET_HPP__ #include -#define PACKET_SIZE (4 + (20 * 10 * 4) + (7 * 4) + 9) -#define PACKET_MAGIC 0x5041434B + +enum PacketInfo +{ + PACKET_SIZE = ((20 * 10 * 4) + (7 * 4) + 9), + PACKET_MAGIC = 0x5041434B, + PACKET_MAGIC_SIZE = 4, + PACKET_ID_SIZE = 9 +}; + +/* +serialilzation packet +magic 4byte +flag bit 4byte : 0 => board / 1 => type / 2 => rotation / 3 => r / 4 => c / 5 => deleted_line / 6 => is_game_over / 7 => is_win / 8 => id +data ? byte +*/ + +enum FlagBitInfo +{ + BOARD_BIT = (1 << 0), + TYPE_BIT = (1 << 1), + ROTATION_BIT = (1 << 2), + R_BIT = (1 << 3), + C_BIT = (1 << 4), + DELETED_LINE_BIT = (1 << 5), + IS_GAME_OVER_BIT = (1 << 6), + IS_WIN_BIT = (1 << 7), + ID_BIT = (1 << 8) +}; typedef struct PacketStruct { - int32_t magic; - int32_t board[20][10]; - int32_t type; - int32_t rotation; - int32_t r; - int32_t c; - int32_t deleted_line; - int32_t is_game_over; // 1 => True, 0 => False - int32_t is_win; + uint32_t board[20][10]; + uint32_t type; + uint32_t rotation; + uint32_t r; + uint32_t c; + uint32_t deleted_line; + uint32_t is_game_over; + uint32_t is_win; char id[9]; } Packet; diff --git a/platform/linux/include/network/linux_network.hpp b/platform/linux/include/network/linux_network.hpp index 25a5975e..ba7c6603 100644 --- a/platform/linux/include/network/linux_network.hpp +++ b/platform/linux/include/network/linux_network.hpp @@ -22,10 +22,10 @@ class LinuxNetwork : public INetwork void write_32b(uint8_t*& p, int32_t v); void write_bytes(uint8_t*& p, const void* data, size_t size); - void serialize(uint8_t* buf, const Packet& pkt); + uint32_t serialize(uint8_t* buf, const Packet& pkt); int32_t read_32b(const uint8_t*& p); void read_bytes(const uint8_t*& p, void* dst, size_t size); - void deserialize(const uint8_t* buf, Packet& pkt); + bool deserialize(const uint8_t* buf, Packet& pkt); public: LinuxNetwork(); diff --git a/platform/linux/source/network/linux_network.cpp b/platform/linux/source/network/linux_network.cpp index cb994673..d60e1bea 100644 --- a/platform/linux/source/network/linux_network.cpp +++ b/platform/linux/source/network/linux_network.cpp @@ -59,25 +59,78 @@ void LinuxNetwork::write_bytes(uint8_t*& p, const void* data, size_t size) p += size; } -void LinuxNetwork::serialize(uint8_t* buf, const Packet& pkt) +uint32_t LinuxNetwork::serialize(uint8_t* buf, const Packet& pkt) { uint8_t* p = buf; + uint8_t* op = buf; + uint32_t size = 0; + uint32_t flag_bit = 0; + uint8_t itc = 0; - write_32b(p, pkt.magic); + write_32b(p, PACKET_MAGIC); + size += 4; + op += 4; - for (int i = 0; i < 20; ++i) - for (int j = 0; j < 10; ++j) - write_32b(p, pkt.board[i][j]); + // flag bit + p += 4; + size += 4; + + flag_bit |= BOARD_BIT; + for (int i = 0; i < 20; ++i) { + for (int j = 0; j < 10; ++j) { + itc = static_cast(pkt.board[i][j]); + write_bytes(p, &itc, 1); + size += 1; + } + } + + flag_bit |= TYPE_BIT; + itc = static_cast(pkt.type); + write_bytes(p, &itc, 1); + size += 1; + + flag_bit |= ROTATION_BIT; + itc = static_cast(pkt.rotation); + write_bytes(p, &itc, 1); + size += 1; + + flag_bit |= R_BIT; + itc = static_cast(pkt.r); + write_bytes(p, &itc, 1); + size += 1; + + flag_bit |= C_BIT; + itc = static_cast(pkt.c); + write_bytes(p, &itc, 1); + size += 1; + + flag_bit |= DELETED_LINE_BIT; + itc = static_cast(pkt.deleted_line); + write_bytes(p, &itc, 1); + size += 1; + + if (pkt.is_game_over == 1) { + flag_bit |= IS_GAME_OVER_BIT; + itc = static_cast(pkt.is_game_over); + write_bytes(p, &itc, 1); + size += 1; + } - write_32b(p, pkt.type); - write_32b(p, pkt.rotation); - write_32b(p, pkt.r); - write_32b(p, pkt.c); - write_32b(p, pkt.deleted_line); - write_32b(p, pkt.is_game_over); - write_32b(p, pkt.is_win); + if (pkt.is_win == 1) { + flag_bit |= IS_WIN_BIT; + itc = static_cast(pkt.is_win); + write_bytes(p, &itc, 1); + size += 1; + } + flag_bit |= ID_BIT; write_bytes(p, pkt.id, 9); + size += 9; + + // flag bit + write_32b(op, flag_bit); + + return size; } int32_t LinuxNetwork::read_32b(const uint8_t*& p) @@ -94,26 +147,71 @@ void LinuxNetwork::read_bytes(const uint8_t*& p, void* dst, size_t size) p += size; } -void LinuxNetwork::deserialize(const uint8_t* buf, Packet& pkt) +bool LinuxNetwork::deserialize(const uint8_t* buf, Packet& pkt) { const uint8_t* p = buf; - pkt.magic = read_32b(p); + uint32_t magic = 0; + uint32_t flag_bit = 0; + uint8_t itc = 0; - for (int i = 0; i < 20; ++i) - for (int j = 0; j < 10; ++j) - pkt.board[i][j] = read_32b(p); + magic = read_32b(p); + if (magic != PACKET_MAGIC) return false; - pkt.type = read_32b(p); - pkt.rotation = read_32b(p); - pkt.r = read_32b(p); - pkt.c = read_32b(p); - pkt.deleted_line = read_32b(p); - pkt.is_game_over = read_32b(p); - pkt.is_win = read_32b(p); + flag_bit = read_32b(p); - read_bytes(p, pkt.id, 9); - pkt.id[8] = '\0'; + memset((void*) &pkt, 0, PACKET_SIZE); + + if (flag_bit & BOARD_BIT) { + for (int i = 0; i < 20; ++i) { + for (int j = 0; j < 10; ++j) { + read_bytes(p, &itc, 1); + pkt.board[i][j] = static_cast(itc); + } + } + } + + if (flag_bit & TYPE_BIT) { + read_bytes(p, &itc, 1); + pkt.type = static_cast(itc); + } + + if (flag_bit & ROTATION_BIT) { + read_bytes(p, &itc, 1); + pkt.rotation = static_cast(itc); + } + + if (flag_bit & R_BIT) { + read_bytes(p, &itc, 1); + pkt.r = static_cast(itc); + } + + if (flag_bit & C_BIT) { + read_bytes(p, &itc, 1); + pkt.c = static_cast(itc); + } + + if (flag_bit & DELETED_LINE_BIT) { + read_bytes(p, &itc, 1); + pkt.deleted_line = static_cast(itc); + } + + if (flag_bit & IS_GAME_OVER_BIT) { + read_bytes(p, &itc, 1); + pkt.is_game_over = static_cast(itc); + } + + if (flag_bit & IS_WIN_BIT) { + read_bytes(p, &itc, 1); + pkt.is_win = static_cast(itc); + } + + if (flag_bit & ID_BIT) { + read_bytes(p, pkt.id, PACKET_ID_SIZE); + pkt.id[PACKET_ID_SIZE - 1] = '\0'; + } + + return true; } void LinuxNetwork::send_udp(const Board& board, const Tetromino& tetromino, const int deleted_line, int is_game_over, int is_win, const char* another_user_ip, const char* my_id) @@ -123,13 +221,12 @@ void LinuxNetwork::send_udp(const Board& board, const Tetromino& tetromino, cons auto [pos_r, pos_c] = tetromino.get_pos(); sockaddr_in another_user; int send_result; + uint32_t buffer_size = 0; another_user.sin_family = AF_INET; another_user.sin_port = htons(PORT); inet_pton(AF_INET, another_user_ip, &another_user.sin_addr); - pkt.magic = PACKET_MAGIC; - for (int r = 0; r < 20; ++r) for (int c = 0; c < 10; ++c) pkt.board[r][c] = board.at(r + 2, c); @@ -143,9 +240,10 @@ void LinuxNetwork::send_udp(const Board& board, const Tetromino& tetromino, cons pkt.is_win = is_win; snprintf(pkt.id, sizeof(pkt.id), "%s", my_id); - serialize(buf, pkt); + buffer_size = serialize(buf, pkt); - send_result = sendto(client_sock, (char*) buf, PACKET_SIZE, 0, (sockaddr*) &another_user, sizeof(another_user)); + send_result = sendto(client_sock, (char*) buf, buffer_size, 0, (sockaddr*) &another_user, + sizeof(another_user)); if(send_result < 0) perror("sendto failed: "); @@ -166,6 +264,7 @@ void LinuxNetwork::send_relay_udp(const Packet& packet, char* another_user_ip; uint8_t buf[PACKET_SIZE]; int send_result; + uint32_t buffer_size = 0; for (const auto& [id, ip] : ids_ips) { if (strcmp(id.c_str(), packet.id) == 0) continue; @@ -178,8 +277,6 @@ void LinuxNetwork::send_relay_udp(const Packet& packet, inet_pton(AF_INET, ip.c_str(), &another_user.sin_addr); // 보드 데이터 복사 - pkt.magic = PACKET_MAGIC; - for (int r = 0; r < 20; ++r) for (int c = 0; c < 10; ++c) pkt.board[r][c] = packet.board[r][c]; // 숨겨진 2줄 제외하고 복사 @@ -193,9 +290,10 @@ void LinuxNetwork::send_relay_udp(const Packet& packet, pkt.is_win = packet.is_win; snprintf(pkt.id, sizeof(pkt.id), "%s", packet.id); - serialize(buf, pkt); + buffer_size = serialize(buf, pkt); - send_result = sendto(client_sock, (char*) buf, PACKET_SIZE, 0, (sockaddr*) &another_user, sizeof(another_user)); + send_result = sendto(client_sock, (char*) buf, buffer_size, 0, (sockaddr*) &another_user, + sizeof(another_user)); if (send_result < 0) { perror("sendto failed: "); @@ -207,6 +305,7 @@ bool LinuxNetwork::recv_udp(Packet& recv_pkt) { uint8_t buf[PACKET_SIZE]; int n = epoll_wait(epfd, events, MAX_EVENTS, 0); + bool is_deserialize_success = false; int r; if (n < 0) { @@ -221,25 +320,24 @@ bool LinuxNetwork::recv_udp(Packet& recv_pkt) sockaddr_in client{}; socklen_t len = sizeof(client); - r = recvfrom(server_sock, (char*) buf, PACKET_SIZE, 0, (sockaddr*) &client, &len); + r = recvfrom(server_sock, (char*)buf, PACKET_SIZE, 0, (sockaddr*) &client, &len); if (r < 0) { if (errno == EAGAIN || errno == EWOULDBLOCK) { // 수신 버퍼 비움 - break; + return false; } else { perror("recvfrom"); - break; + return false; } } - else if (r != PACKET_SIZE) - break; + else if (r < PACKET_MAGIC_SIZE) + return false; - deserialize(buf, recv_pkt); + is_deserialize_success = deserialize(buf, recv_pkt); - if (recv_pkt.magic != PACKET_MAGIC) - break; + if (is_deserialize_success == false) return false; return true; } diff --git a/platform/window/include/network/window_network.hpp b/platform/window/include/network/window_network.hpp index 18972f22..0c366249 100644 --- a/platform/window/include/network/window_network.hpp +++ b/platform/window/include/network/window_network.hpp @@ -26,10 +26,10 @@ class WindowNetwork : public INetwork void write_32b(uint8_t*& p, int32_t v); void write_bytes(uint8_t*& p, const void* data, size_t size); - void serialize(uint8_t* buf, const Packet& pkt); + uint32_t serialize(uint8_t* buf, const Packet& pkt); int32_t read_32b(const uint8_t*& p); void read_bytes(const uint8_t*& p, void* dst, size_t size); - void deserialize(const uint8_t* buf, Packet& pkt); + bool deserialize(const uint8_t* buf, Packet& pkt); public: WindowNetwork(); diff --git a/platform/window/source/network/window_network.cpp b/platform/window/source/network/window_network.cpp index 12bef561..5bc6a9f0 100644 --- a/platform/window/source/network/window_network.cpp +++ b/platform/window/source/network/window_network.cpp @@ -69,25 +69,78 @@ void WindowNetwork::write_bytes(uint8_t*& p, const void* data, size_t size) p += size; } -void WindowNetwork::serialize(uint8_t* buf, const Packet& pkt) +uint32_t WindowNetwork::serialize(uint8_t* buf, const Packet& pkt) { uint8_t* p = buf; + uint8_t* op = buf; + uint32_t size = 0; + uint32_t flag_bit = 0; + uint8_t itc = 0; - write_32b(p, pkt.magic); + write_32b(p, PACKET_MAGIC); + size += 4; + op += 4; - for (int i = 0; i < 20; ++i) - for (int j = 0; j < 10; ++j) - write_32b(p, pkt.board[i][j]); + // flag bit + p += 4; + size += 4; + + flag_bit |= BOARD_BIT; + for (int i = 0; i < 20; ++i) { + for (int j = 0; j < 10; ++j) { + itc = static_cast(pkt.board[i][j]); + write_bytes(p, &itc, 1); + size += 1; + } + } + + flag_bit |= TYPE_BIT; + itc = static_cast(pkt.type); + write_bytes(p, &itc, 1); + size += 1; + + flag_bit |= ROTATION_BIT; + itc = static_cast(pkt.rotation); + write_bytes(p, &itc, 1); + size += 1; + + flag_bit |= R_BIT; + itc = static_cast(pkt.r); + write_bytes(p, &itc, 1); + size += 1; + + flag_bit |= C_BIT; + itc = static_cast(pkt.c); + write_bytes(p, &itc, 1); + size += 1; + + flag_bit |= DELETED_LINE_BIT; + itc = static_cast(pkt.deleted_line); + write_bytes(p, &itc, 1); + size += 1; + + if (pkt.is_game_over == 1) { + flag_bit |= IS_GAME_OVER_BIT; + itc = static_cast(pkt.is_game_over); + write_bytes(p, &itc, 1); + size += 1; + } - write_32b(p, pkt.type); - write_32b(p, pkt.rotation); - write_32b(p, pkt.r); - write_32b(p, pkt.c); - write_32b(p, pkt.deleted_line); - write_32b(p, pkt.is_game_over); - write_32b(p, pkt.is_win); + if (pkt.is_win == 1) { + flag_bit |= IS_WIN_BIT; + itc = static_cast(pkt.is_win); + write_bytes(p, &itc, 1); + size += 1; + } + flag_bit |= ID_BIT; write_bytes(p, pkt.id, 9); + size += 9; + + // flag bit + write_32b(op, flag_bit); + + return size; } int32_t WindowNetwork::read_32b(const uint8_t*& p) @@ -104,26 +157,71 @@ void WindowNetwork::read_bytes(const uint8_t*& p, void* dst, size_t size) p += size; } -void WindowNetwork::deserialize(const uint8_t* buf, Packet& pkt) +bool WindowNetwork::deserialize(const uint8_t* buf, Packet& pkt) { const uint8_t* p = buf; - pkt.magic = read_32b(p); + uint32_t magic = 0; + uint32_t flag_bit = 0; + uint8_t itc = 0; + + magic = read_32b(p); + if (magic != PACKET_MAGIC) return false; + + flag_bit = read_32b(p); + + memset((void*) &pkt, 0, PACKET_SIZE); + + if (flag_bit & BOARD_BIT) { + for (int i = 0; i < 20; ++i) { + for (int j = 0; j < 10; ++j) { + read_bytes(p, &itc, 1); + pkt.board[i][j] = static_cast(itc); + } + } + } + + if (flag_bit & TYPE_BIT) { + read_bytes(p, &itc, 1); + pkt.type = static_cast(itc); + } + + if (flag_bit & ROTATION_BIT) { + read_bytes(p, &itc, 1); + pkt.rotation = static_cast(itc); + } + + if (flag_bit & R_BIT) { + read_bytes(p, &itc, 1); + pkt.r = static_cast(itc); + } + + if (flag_bit & C_BIT) { + read_bytes(p, &itc, 1); + pkt.c = static_cast(itc); + } + + if (flag_bit & DELETED_LINE_BIT) { + read_bytes(p, &itc, 1); + pkt.deleted_line = static_cast(itc); + } + + if (flag_bit & IS_GAME_OVER_BIT) { + read_bytes(p, &itc, 1); + pkt.is_game_over = static_cast(itc); + } - for (int i = 0; i < 20; ++i) - for (int j = 0; j < 10; ++j) - pkt.board[i][j] = read_32b(p); + if (flag_bit & IS_WIN_BIT) { + read_bytes(p, &itc, 1); + pkt.is_win = static_cast(itc); + } - pkt.type = read_32b(p); - pkt.rotation = read_32b(p); - pkt.r = read_32b(p); - pkt.c = read_32b(p); - pkt.deleted_line = read_32b(p); - pkt.is_game_over = read_32b(p); - pkt.is_win = read_32b(p); + if (flag_bit & ID_BIT) { + read_bytes(p, pkt.id, PACKET_ID_SIZE); + pkt.id[PACKET_ID_SIZE - 1] = '\0'; + } - read_bytes(p, pkt.id, 9); - pkt.id[8] = '\0'; + return true; } void WindowNetwork::send_udp(const Board& board, const Tetromino& tetromino, int deleted_line, int is_game_over, int is_win, @@ -136,14 +234,13 @@ void WindowNetwork::send_udp(const Board& board, const Tetromino& tetromino, int ZeroMemory(&another_user, sizeof(another_user)); another_user.sin_family = AF_INET; another_user.sin_port = htons(PORT); + uint32_t buffer_size = 0; // window에서는 inet_pton 사용 시 필요 inet_pton(AF_INET, another_user_ip, &another_user.sin_addr); // 보드 데이터 복사 - pkt.magic = PACKET_MAGIC; - for (int r = 0; r < 20; ++r) for (int c = 0; c < 10; ++c) pkt.board[r][c] = board.at(r + 2, c); // 숨겨진 2줄 제외하고 복사 @@ -155,11 +252,11 @@ void WindowNetwork::send_udp(const Board& board, const Tetromino& tetromino, int pkt.deleted_line = deleted_line; pkt.is_game_over = is_game_over; pkt.is_win = is_win; - snprintf(pkt.id, sizeof(pkt.id), "%s", my_id); + snprintf(pkt.id, PACKET_ID_SIZE, "%s", my_id); - serialize(buf, pkt); + buffer_size = serialize(buf, pkt); - int send_result = sendto(client_sock, (char*) buf, PACKET_SIZE, 0, (SOCKADDR*) &another_user, + int send_result = sendto(client_sock, (char*)buf, buffer_size, 0, (SOCKADDR*) &another_user, sizeof(another_user)); if (send_result == SOCKET_ERROR) { @@ -182,6 +279,8 @@ void WindowNetwork::send_relay_udp(const Packet& packet, char* another_user_ip; uint8_t buf[PACKET_SIZE]; SOCKADDR_IN another_user; + uint32_t buffer_size = 0; + int send_result = 0; for (const auto& [id, ip] : ids_ips) { if (strcmp(id.c_str(), packet.id) == 0) continue; @@ -194,9 +293,6 @@ void WindowNetwork::send_relay_udp(const Packet& packet, // window에서는 inet_pton 사용 시 필요 inet_pton(AF_INET, ip.c_str(), &another_user.sin_addr); - // 보드 데이터 복사 - pkt.magic = PACKET_MAGIC; - for (int r = 0; r < 20; ++r) for (int c = 0; c < 10; ++c) pkt.board[r][c] = packet.board[r][c]; // 숨겨진 2줄 제외하고 복사 @@ -208,12 +304,11 @@ void WindowNetwork::send_relay_udp(const Packet& packet, pkt.deleted_line = packet.deleted_line; pkt.is_game_over = packet.is_game_over; pkt.is_win = packet.is_win; - snprintf(pkt.id, sizeof(pkt.id), "%s", packet.id); + snprintf(pkt.id, PACKET_ID_SIZE, "%s", packet.id); - serialize(buf, pkt); + buffer_size = serialize(buf, pkt); - int send_result = sendto(client_sock, (char*) buf, PACKET_SIZE, 0, - (SOCKADDR*) &another_user, sizeof(another_user)); + send_result = sendto(client_sock, (char*)buf, buffer_size, 0, (SOCKADDR*) &another_user, sizeof(another_user)); if (send_result == SOCKET_ERROR) { cerr << "sendto failed: " << WSAGetLastError() << "\n"; @@ -227,13 +322,15 @@ bool WindowNetwork::recv_udp(Packet& recv_pkt) bool data_received = false; SOCKADDR_IN client_addr; int addr_len = sizeof(client_addr); + bool is_deserialize_success = false; + int r; // [window Poll 처리] int ret = WSAPoll(fds, 1, 0); if (ret > 0) { if (fds[0].revents & POLLIN) { - int r = recvfrom(server_sock, (char*) buf, PACKET_SIZE, 0, (SOCKADDR*) &client_addr, + r = recvfrom(server_sock, (char*) buf, PACKET_SIZE, 0, (SOCKADDR*) &client_addr, &addr_len); if (r == SOCKET_ERROR) { @@ -241,11 +338,13 @@ bool WindowNetwork::recv_udp(Packet& recv_pkt) cerr << "recvfrom failed: " << err << "\n"; return false; } + else if (r < PACKET_MAGIC_SIZE) + return false; // 데이터 수신 성공 - deserialize(buf, recv_pkt); + is_deserialize_success = deserialize(buf, recv_pkt); - if (recv_pkt.magic != PACKET_MAGIC) data_received = false; + if (is_deserialize_success == false) data_received = false; data_received = true; } From f7de65c329a68abff41d82335f16bd71774044b8 Mon Sep 17 00:00:00 2001 From: Choi Yusun <43121372+ggstone0523@users.noreply.github.com> Date: Fri, 13 Mar 2026 14:51:44 +0900 Subject: [PATCH 03/14] [Fix] Change packet type before --- core/include/util/network_packet.hpp | 27 ++++++++++++------- .../linux/source/network/linux_network.cpp | 16 +++++------ .../source/render/linux_multi_renderer.cpp | 2 +- .../window/source/network/window_network.cpp | 16 +++++------ .../source/render/window_multi_renderer.cpp | 2 +- 5 files changed, 36 insertions(+), 27 deletions(-) diff --git a/core/include/util/network_packet.hpp b/core/include/util/network_packet.hpp index 6af0e3e8..4c0f9249 100644 --- a/core/include/util/network_packet.hpp +++ b/core/include/util/network_packet.hpp @@ -15,7 +15,16 @@ enum PacketInfo serialilzation packet magic 4byte flag bit 4byte : 0 => board / 1 => type / 2 => rotation / 3 => r / 4 => c / 5 => deleted_line / 6 => is_game_over / 7 => is_win / 8 => id -data ? byte +data ? byte +uint32_t board[20][10]; +uint32_t type; +uint32_t rotation; +uint32_t r; +uint32_t c; +uint32_t deleted_line; +uint32_t is_game_over; +uint32_t is_win; +char id[9]; */ enum FlagBitInfo @@ -32,14 +41,14 @@ enum FlagBitInfo }; typedef struct PacketStruct { - uint32_t board[20][10]; - uint32_t type; - uint32_t rotation; - uint32_t r; - uint32_t c; - uint32_t deleted_line; - uint32_t is_game_over; - uint32_t is_win; + int32_t board[20][10]; + int32_t type; + int32_t rotation; + int32_t r; + int32_t c; + int32_t deleted_line; + int32_t is_game_over; + int32_t is_win; char id[9]; } Packet; diff --git a/platform/linux/source/network/linux_network.cpp b/platform/linux/source/network/linux_network.cpp index d60e1bea..50bc6e3f 100644 --- a/platform/linux/source/network/linux_network.cpp +++ b/platform/linux/source/network/linux_network.cpp @@ -166,44 +166,44 @@ bool LinuxNetwork::deserialize(const uint8_t* buf, Packet& pkt) for (int i = 0; i < 20; ++i) { for (int j = 0; j < 10; ++j) { read_bytes(p, &itc, 1); - pkt.board[i][j] = static_cast(itc); + pkt.board[i][j] = static_cast(itc); } } } if (flag_bit & TYPE_BIT) { read_bytes(p, &itc, 1); - pkt.type = static_cast(itc); + pkt.type = static_cast(itc); } if (flag_bit & ROTATION_BIT) { read_bytes(p, &itc, 1); - pkt.rotation = static_cast(itc); + pkt.rotation = static_cast(itc); } if (flag_bit & R_BIT) { read_bytes(p, &itc, 1); - pkt.r = static_cast(itc); + pkt.r = static_cast(itc); } if (flag_bit & C_BIT) { read_bytes(p, &itc, 1); - pkt.c = static_cast(itc); + pkt.c = static_cast(itc); } if (flag_bit & DELETED_LINE_BIT) { read_bytes(p, &itc, 1); - pkt.deleted_line = static_cast(itc); + pkt.deleted_line = static_cast(itc); } if (flag_bit & IS_GAME_OVER_BIT) { read_bytes(p, &itc, 1); - pkt.is_game_over = static_cast(itc); + pkt.is_game_over = static_cast(itc); } if (flag_bit & IS_WIN_BIT) { read_bytes(p, &itc, 1); - pkt.is_win = static_cast(itc); + pkt.is_win = static_cast(itc); } if (flag_bit & ID_BIT) { diff --git a/platform/linux/source/render/linux_multi_renderer.cpp b/platform/linux/source/render/linux_multi_renderer.cpp index f0e06726..d2e0ab0f 100644 --- a/platform/linux/source/render/linux_multi_renderer.cpp +++ b/platform/linux/source/render/linux_multi_renderer.cpp @@ -212,7 +212,7 @@ void LinuxMultiRenderer::render_board(const Board& board, const Tetromino& tetro void LinuxMultiRenderer::render_other_board(Packet& pkt) { auto [start_x, start_y] = other_render_loc_get_or_set(std::string(pkt.id)); - auto game_board = pkt.board; + auto& game_board = pkt.board; int pos_r = pkt.r; int pos_c = pkt.c; int mino_type = pkt.type; diff --git a/platform/window/source/network/window_network.cpp b/platform/window/source/network/window_network.cpp index 5bc6a9f0..2329acea 100644 --- a/platform/window/source/network/window_network.cpp +++ b/platform/window/source/network/window_network.cpp @@ -176,44 +176,44 @@ bool WindowNetwork::deserialize(const uint8_t* buf, Packet& pkt) for (int i = 0; i < 20; ++i) { for (int j = 0; j < 10; ++j) { read_bytes(p, &itc, 1); - pkt.board[i][j] = static_cast(itc); + pkt.board[i][j] = static_cast(itc); } } } if (flag_bit & TYPE_BIT) { read_bytes(p, &itc, 1); - pkt.type = static_cast(itc); + pkt.type = static_cast(itc); } if (flag_bit & ROTATION_BIT) { read_bytes(p, &itc, 1); - pkt.rotation = static_cast(itc); + pkt.rotation = static_cast(itc); } if (flag_bit & R_BIT) { read_bytes(p, &itc, 1); - pkt.r = static_cast(itc); + pkt.r = static_cast(itc); } if (flag_bit & C_BIT) { read_bytes(p, &itc, 1); - pkt.c = static_cast(itc); + pkt.c = static_cast(itc); } if (flag_bit & DELETED_LINE_BIT) { read_bytes(p, &itc, 1); - pkt.deleted_line = static_cast(itc); + pkt.deleted_line = static_cast(itc); } if (flag_bit & IS_GAME_OVER_BIT) { read_bytes(p, &itc, 1); - pkt.is_game_over = static_cast(itc); + pkt.is_game_over = static_cast(itc); } if (flag_bit & IS_WIN_BIT) { read_bytes(p, &itc, 1); - pkt.is_win = static_cast(itc); + pkt.is_win = static_cast(itc); } if (flag_bit & ID_BIT) { diff --git a/platform/window/source/render/window_multi_renderer.cpp b/platform/window/source/render/window_multi_renderer.cpp index 9957aa31..17df9e95 100644 --- a/platform/window/source/render/window_multi_renderer.cpp +++ b/platform/window/source/render/window_multi_renderer.cpp @@ -212,7 +212,7 @@ void WindowMultiRenderer::render_board(const Board& board, const Tetromino& tetr void WindowMultiRenderer::render_other_board(Packet& pkt) { auto [start_x, start_y] = other_render_loc_get_or_set(std::string(pkt.id)); - auto game_board = pkt.board; + auto& game_board = pkt.board; int pos_r = pkt.r; int pos_c = pkt.c; int mino_type = pkt.type; From e0561b6da295d80f1ab72a33c2b5e12eba78c01d Mon Sep 17 00:00:00 2001 From: Choi Yusun <43121372+ggstone0523@users.noreply.github.com> Date: Fri, 13 Mar 2026 17:42:09 +0900 Subject: [PATCH 04/14] [Refact] Change serialization logic to compress packets --- core/include/util/network_packet.hpp | 22 +- lobby/include/lobby_network_packet.hpp | 91 +++++- .../lobby_network/linux_lobby_network.hpp | 15 +- .../linux/include/network/linux_network.hpp | 9 +- .../lobby_network/linux_lobby_network.cpp | 259 +++++++++++++---- .../linux/source/network/linux_network.cpp | 173 +++++------ .../lobby_network/window_lobby_network.hpp | 15 +- .../window/include/network/window_network.hpp | 11 +- .../lobby_network/window_lobby_network.cpp | 270 +++++++++++++----- .../window/source/network/window_network.cpp | 181 +++++------- 10 files changed, 670 insertions(+), 376 deletions(-) diff --git a/core/include/util/network_packet.hpp b/core/include/util/network_packet.hpp index 4c0f9249..086af3a4 100644 --- a/core/include/util/network_packet.hpp +++ b/core/include/util/network_packet.hpp @@ -6,28 +6,30 @@ enum PacketInfo { PACKET_SIZE = ((20 * 10 * 4) + (7 * 4) + 9), + BUFFER_SIZE = 1024, PACKET_MAGIC = 0x5041434B, PACKET_MAGIC_SIZE = 4, PACKET_ID_SIZE = 9 }; /* -serialilzation packet +serialization packet magic 4byte flag bit 4byte : 0 => board / 1 => type / 2 => rotation / 3 => r / 4 => c / 5 => deleted_line / 6 => is_game_over / 7 => is_win / 8 => id data ? byte -uint32_t board[20][10]; -uint32_t type; -uint32_t rotation; -uint32_t r; -uint32_t c; -uint32_t deleted_line; -uint32_t is_game_over; -uint32_t is_win; +uint8_t board[20][10]; +uint8_t type; +uint8_t rotation; +uint8_t r; +uint8_t c; +uint8_t deleted_line; +uint8_t is_game_over; +uint8_t is_win; +uint8_t id_len; char id[9]; */ -enum FlagBitInfo +enum FlagBitInfo : uint32_t { BOARD_BIT = (1 << 0), TYPE_BIT = (1 << 1), diff --git a/lobby/include/lobby_network_packet.hpp b/lobby/include/lobby_network_packet.hpp index d78b7e90..05cb7ce2 100644 --- a/lobby/include/lobby_network_packet.hpp +++ b/lobby/include/lobby_network_packet.hpp @@ -2,19 +2,46 @@ #define __LOBBY_PACKET_HPP__ #include -#define USER_DATA_SIZE (4 + 13 + 4 + 4 + 101) -#define ROOM_DATA_SIZE (4 + 69 + 9 + 4 + 9 + 101) -#define IDSIZE 9 -#define MAXUSER 4 -#define ROOMNAMESIZE 9 -#define COMMENTSIZE 101 -#define USER_DATA_MAGIC 0x55534552 -#define ROOM_DATA_MAGIC 0x524F4F4D +enum LobbyPacketInfo +{ + USER_DATA_SIZE = (4 + 13 + 4 + 4 + 101), + ROOM_DATA_SIZE = (4 + 69 + 9 + 4 + 9 + 101), + LOBBY_BUFFER_SIZE = 1024, + IDSIZE = 9, + MAXUSER = 4, + ROOMNAMESIZE = 9, + COMMENTSIZE = 101, + LOBBY_MAGIC_SIZE = 4, + USER_DATA_MAGIC = 0x55534552, + ROOM_DATA_MAGIC = 0x524F4F4D +}; + +/* +serialization packet +magic 4byte +flag bit 4byte : 0 => id / 1 => is_enter / 2 => is_out / 3 => is_chat / 4 => comment +data ? byte +uint8_t id_len; +char id[IDSIZE]; +uint8_t is_enter; +uint8_t is_out; +uint8_t is_chat; +uint8_t comment_len; +char comment[COMMENTSIZE]; +*/ + +enum LobbyUserFlagBitInfo : uint32_t +{ + LOBBY_USER_ID_BIT = (1 << 0), + LOBBY_USER_IS_ENTER_BIT = (1 << 1), + LOBBY_USER_IS_OUT_BIT = (1 << 2), + LOBBY_USER_IS_CHAT_BIT = (1 << 3), + LOBBY_USER_COMMENT_BIT = (1 << 4), +}; typedef struct _user_data { - int32_t magic; char id[IDSIZE]; int32_t is_enter; int32_t is_out; @@ -22,13 +49,55 @@ typedef struct _user_data char comment[COMMENTSIZE]; } user_data; +/* +serialization packet +magic 4byte +flag bit 4byte : 0 => room_master_id / 1 => id / 2 => room_name / 3 => id_len / 4 => is_enter_not_success / 5 => is_game_start +/ 6 => is_broadcast / 7 => is_update / 8 => is_broadcast_delete / 9 => is_chat / 10 => comment_id / 11 => comment +data ? byte +uint8_t room_master_id_len; +char room_master_id[IDSIZE]; +uint8_t id_len; +[for id_len] +uint8_t user_per_id_len; +char id[MAXUSER][IDSIZE] +[end] +uint8_t room_name_len; +char room_name[ROOMNAMESIZE]; +uint8_t is_enter_not_success; +uint8_t is_game_start; +uint8_t is_broadcast; +uint8_t is_update; +uint8_t is_broadcast_delete; +uint8_t is_chat; +uint8_t comment_id_len; +char comment_id[IDSIZE]; +uint8_t comment_len; +char comment[COMMENTSIZE]; +*/ + +enum LobbyRoomFlagBitInfo : uint32_t +{ + LOBBY_ROOM_ROOM_MASTER_ID_BIT = (1 << 0), + LOBBY_ROOM_ID_BIT = (1 << 1), + LOBBY_ROOM_ROOM_NAME_BIT = (1 << 2), + LOBBY_ROOM_ID_LEN_BIT = (1 << 3), + LOBBY_ROOM_IS_ENTER_NOT_SUCCESS_BIT = (1 << 4), + LOBBY_ROOM_IS_GAME_START_BIT = (1 << 5), + LOBBY_ROOM_IS_BROADCAST_BIT = (1 << 6), + LOBBY_ROOM_IS_UPDATE_BIT = (1 << 7), + LOBBY_ROOM_IS_BROADCAST_DELETE_BIT = (1 << 8), + LOBBY_ROOM_IS_CHAT_BIT = (1 << 9), + LOBBY_ROOM_COMMENT_ID_BIT = (1 << 10), + LOBBY_ROOM_COMMENT_BIT = (1 << 11) +}; + typedef struct _room_data { - int32_t magic; char room_master_id[IDSIZE]; + int32_t id_len; char id[MAXUSER][IDSIZE]; char room_name[ROOMNAMESIZE]; - int32_t id_len; int32_t is_enter_not_success; int32_t is_game_start; int32_t is_broadcast; diff --git a/platform/linux/include/lobby_network/linux_lobby_network.hpp b/platform/linux/include/lobby_network/linux_lobby_network.hpp index 2aeaa063..f5b0a6bf 100644 --- a/platform/linux/include/lobby_network/linux_lobby_network.hpp +++ b/platform/linux/include/lobby_network/linux_lobby_network.hpp @@ -24,12 +24,19 @@ class LinuxLobbyNetwork : public ILobbyNetwork int32_t read_32b(const uint8_t*& p); void read_bytes(const uint8_t*& p, void* dst, size_t size); + void compress_32b(uint8_t*& p, uint32_t& flag_bit, int32_t v, uint32_t bit_check); + void compress_bytes(uint8_t*& p, uint32_t& flag_bit, const void* data, size_t size, + uint32_t bit_check); + void decompress_32b(const uint8_t*& p, int32_t& v); + void decompress_bytes(const uint8_t*& p, void* data, size_t size); + // user_data - void serialize(uint8_t* buf, const user_data& pkt); - void deserialize(const uint8_t* buf, user_data& pkt); + uint32_t serialize(uint8_t* buf, const user_data& pkt); + bool deserialize(const uint8_t* buf, user_data& pkt); // room_data - void serialize(uint8_t* buf, const room_data& pkt); - void deserialize(const uint8_t* buf, room_data& pkt); + uint32_t serialize(uint8_t* buf, const room_data& pkt); + bool deserialize(const uint8_t* buf, room_data& pkt); + public: LinuxLobbyNetwork(); void find_broadcast_ip(char* broadcast_ip) override; diff --git a/platform/linux/include/network/linux_network.hpp b/platform/linux/include/network/linux_network.hpp index ba7c6603..59cb0d86 100644 --- a/platform/linux/include/network/linux_network.hpp +++ b/platform/linux/include/network/linux_network.hpp @@ -22,9 +22,16 @@ class LinuxNetwork : public INetwork void write_32b(uint8_t*& p, int32_t v); void write_bytes(uint8_t*& p, const void* data, size_t size); - uint32_t serialize(uint8_t* buf, const Packet& pkt); int32_t read_32b(const uint8_t*& p); void read_bytes(const uint8_t*& p, void* dst, size_t size); + + void compress_32b(uint8_t*& p, uint32_t& flag_bit, int32_t v, uint32_t bit_check); + void compress_bytes(uint8_t*& p, uint32_t& flag_bit, const void* data, size_t size, + uint32_t bit_check); + void decompress_32b(const uint8_t*& p, int32_t& v); + void decompress_bytes(const uint8_t*& p, void* data, size_t size); + + uint32_t serialize(uint8_t* buf, const Packet& pkt); bool deserialize(const uint8_t* buf, Packet& pkt); public: diff --git a/platform/linux/source/lobby_network/linux_lobby_network.cpp b/platform/linux/source/lobby_network/linux_lobby_network.cpp index 64ae04a5..2ae20468 100644 --- a/platform/linux/source/lobby_network/linux_lobby_network.cpp +++ b/platform/linux/source/lobby_network/linux_lobby_network.cpp @@ -114,76 +114,211 @@ void LinuxLobbyNetwork::read_bytes(const uint8_t*& p, void* dst, size_t size) p += size; } +void LinuxLobbyNetwork::compress_32b(uint8_t*& p, uint32_t& flag_bit, int32_t v, + uint32_t bit_check) +{ + uint8_t itc = 0; + + flag_bit |= bit_check; + itc = static_cast(v); + write_bytes(p, &itc, 1); +} + +void LinuxLobbyNetwork::compress_bytes(uint8_t*& p, uint32_t& flag_bit, const void* data, + size_t size, uint32_t bit_check) +{ + flag_bit |= bit_check; + write_bytes(p, data, size); +} + +void LinuxLobbyNetwork::decompress_32b(const uint8_t*& p, int32_t& v) +{ + uint8_t itc; + read_bytes(p, &itc, 1); + v = static_cast(itc); +} + +void LinuxLobbyNetwork::decompress_bytes(const uint8_t*& p, void* data, size_t size) +{ + read_bytes(p, data, size); +} + // user_data -void LinuxLobbyNetwork::serialize(uint8_t* buf, const user_data& pkt) +uint32_t LinuxLobbyNetwork::serialize(uint8_t* buf, const user_data& pkt) { uint8_t* p = buf; + uint8_t* op = buf; + uint32_t flag_bit = 0; + uint8_t len = 0; - write_32b(p, pkt.magic); - write_bytes(p, pkt.id, 9); - write_32b(p, pkt.is_enter); - write_32b(p, pkt.is_out); - write_32b(p, pkt.is_chat); - write_bytes(p, pkt.comment, 101); + write_32b(p, USER_DATA_MAGIC); + op += 4; + + // flag bit + p += 4; + + len = static_cast(strlen(pkt.id)); + compress_bytes(p, flag_bit, &len, 1, LOBBY_USER_ID_BIT); + compress_bytes(p, flag_bit, pkt.id, len, LOBBY_USER_ID_BIT); + + if (pkt.is_enter == 1) compress_32b(p, flag_bit, pkt.is_enter, LOBBY_USER_IS_ENTER_BIT); + if (pkt.is_out == 1) compress_32b(p, flag_bit, pkt.is_out, LOBBY_USER_IS_OUT_BIT); + if (pkt.is_chat == 1) compress_32b(p, flag_bit, pkt.is_chat, LOBBY_USER_IS_CHAT_BIT); + + len = static_cast(strlen(pkt.comment)); + if (len > 0) { + compress_bytes(p, flag_bit, &len, 1, LOBBY_USER_COMMENT_BIT); + compress_bytes(p, flag_bit, pkt.comment, len, LOBBY_USER_COMMENT_BIT); + } + + write_32b(op, flag_bit); + + return (p - buf); } -void LinuxLobbyNetwork::deserialize(const uint8_t* buf, user_data& pkt) +bool LinuxLobbyNetwork::deserialize(const uint8_t* buf, user_data& pkt) { const uint8_t* p = buf; + uint32_t magic = 0; + uint32_t flag_bit = 0; + uint8_t len = 0; + + magic = read_32b(p); + if (magic != USER_DATA_MAGIC) return false; + + flag_bit = read_32b(p); + + memset((void*) &pkt, 0, USER_DATA_SIZE); + + if (flag_bit & LOBBY_USER_ID_BIT) { + decompress_bytes(p, &len, 1); + decompress_bytes(p, pkt.id, len); + pkt.id[len] = '\0'; + } + if (flag_bit & LOBBY_USER_IS_ENTER_BIT) decompress_32b(p, pkt.is_enter); + if (flag_bit & LOBBY_USER_IS_OUT_BIT) decompress_32b(p, pkt.is_out); + if (flag_bit & LOBBY_USER_IS_CHAT_BIT) decompress_32b(p, pkt.is_chat); + if (flag_bit & LOBBY_USER_COMMENT_BIT) { + decompress_bytes(p, &len, 1); + decompress_bytes(p, pkt.id, len); + pkt.id[len] = '\0'; + } - pkt.magic = read_32b(p); - read_bytes(p, pkt.id, 9); - pkt.id[8] = '\0'; - pkt.is_enter = read_32b(p); - pkt.is_out = read_32b(p); - pkt.is_chat = read_32b(p); - read_bytes(p, pkt.comment, 101); + return true; } // room_data -void LinuxLobbyNetwork::serialize(uint8_t* buf, const room_data& pkt) +uint32_t LinuxLobbyNetwork::serialize(uint8_t* buf, const room_data& pkt) { uint8_t* p = buf; + uint8_t* op = buf; + uint32_t flag_bit = 0; + uint8_t len = 0; + + write_32b(p, ROOM_DATA_MAGIC); + op += 4; + + // flag bit + p += 4; - write_32b(p, pkt.magic); - write_bytes(p, pkt.room_master_id, 9); - for (int i = 0; i < 4; ++i) - { - write_bytes(p, pkt.id[i], 9); + len = static_cast(strlen(pkt.room_master_id)); + compress_bytes(p, flag_bit, &len, 1, LOBBY_ROOM_ROOM_MASTER_ID_BIT); + compress_bytes(p, flag_bit, pkt.room_master_id, len, LOBBY_ROOM_ROOM_MASTER_ID_BIT); + + if (pkt.id_len > 0) { + compress_32b(p, flag_bit, pkt.id_len, LOBBY_ROOM_ID_LEN_BIT); + for (int i = 0; i < pkt.id_len; ++i) { + len = static_cast(strlen(pkt.id[i])); + compress_bytes(p, flag_bit, &len, 1, LOBBY_ROOM_ID_BIT); + compress_bytes(p, flag_bit, pkt.id[i], len, LOBBY_ROOM_ID_BIT); + } } - write_bytes(p, pkt.room_name, 9); - write_32b(p, pkt.id_len); - write_32b(p, pkt.is_enter_not_success); - write_32b(p, pkt.is_game_start); - write_32b(p, pkt.is_broadcast); - write_32b(p, pkt.is_update); - write_32b(p, pkt.is_broadcast_delete); - write_32b(p, pkt.is_chat); - write_bytes(p, pkt.comment_id, 9); - write_bytes(p, pkt.comment, 101); + + len = static_cast(strlen(pkt.room_name)); + compress_bytes(p, flag_bit, &len, 1, LOBBY_ROOM_ROOM_NAME_BIT); + compress_bytes(p, flag_bit, pkt.room_name, len, LOBBY_ROOM_ROOM_NAME_BIT); + + if (pkt.is_enter_not_success == 1) + compress_32b(p, flag_bit, pkt.is_enter_not_success, LOBBY_ROOM_IS_ENTER_NOT_SUCCESS_BIT); + if (pkt.is_game_start == 1) + compress_32b(p, flag_bit, pkt.is_game_start, LOBBY_ROOM_IS_GAME_START_BIT); + if (pkt.is_broadcast == 1) + compress_32b(p, flag_bit, pkt.is_broadcast, LOBBY_ROOM_IS_BROADCAST_BIT); + if (pkt.is_update == 1) compress_32b(p, flag_bit, pkt.is_update, LOBBY_ROOM_IS_UPDATE_BIT); + if (pkt.is_broadcast_delete == 1) + compress_32b(p, flag_bit, pkt.is_broadcast_delete, LOBBY_ROOM_IS_BROADCAST_DELETE_BIT); + if (pkt.is_chat == 1) compress_32b(p, flag_bit, pkt.is_chat, LOBBY_ROOM_IS_CHAT_BIT); + + if (pkt.is_chat == 1) { + len = static_cast(strlen(pkt.comment_id)); + compress_bytes(p, flag_bit, &len, 1, LOBBY_ROOM_COMMENT_ID_BIT); + compress_bytes(p, flag_bit, pkt.comment_id, len, LOBBY_ROOM_COMMENT_ID_BIT); + len = static_cast(strlen(pkt.comment)); + compress_bytes(p, flag_bit, &len, 1, LOBBY_ROOM_COMMENT_BIT); + compress_bytes(p, flag_bit, pkt.comment, len, LOBBY_ROOM_COMMENT_BIT); + } + + write_32b(op, flag_bit); + + return (p - buf); } -void LinuxLobbyNetwork::deserialize(const uint8_t* buf, room_data& pkt) +bool LinuxLobbyNetwork::deserialize(const uint8_t* buf, room_data& pkt) { const uint8_t* p = buf; + uint32_t magic = 0; + uint32_t flag_bit = 0; + uint8_t len = 0; + + magic = read_32b(p); + if (magic != USER_DATA_MAGIC) return false; + + flag_bit = read_32b(p); + + memset((void*) &pkt, 0, ROOM_DATA_SIZE); - pkt.magic = read_32b(p); - read_bytes(p, pkt.room_master_id, 9); - pkt.room_master_id[8] = '\0'; - for (int i = 0; i < 4; ++i) { - read_bytes(p, pkt.id[i], 9); - pkt.id[i][8] = '\0'; + if (flag_bit & LOBBY_ROOM_ROOM_MASTER_ID_BIT) { + decompress_bytes(p, &len, 1); + decompress_bytes(p, pkt.room_master_id, len); + pkt.room_master_id[len] = '\0'; } - read_bytes(p, pkt.room_name, 9); - pkt.id_len = read_32b(p); - pkt.is_enter_not_success = read_32b(p); - pkt.is_game_start = read_32b(p); - pkt.is_broadcast = read_32b(p); - pkt.is_update = read_32b(p); - pkt.is_broadcast_delete = read_32b(p); - pkt.is_chat = read_32b(p); - read_bytes(p, pkt.comment_id, 9); - read_bytes(p, pkt.comment, 101); + + if (flag_bit & LOBBY_ROOM_ID_LEN_BIT) decompress_32b(p, pkt.id_len); + + if (flag_bit & LOBBY_ROOM_ID_BIT) { + for (int i = 0; i < pkt.id_len; ++i) { + decompress_bytes(p, &len, 1); + decompress_bytes(p, pkt.id[i], len); + pkt.id[i][len] = '\0'; + } + } + + if (flag_bit & LOBBY_ROOM_ROOM_NAME_BIT) { + decompress_bytes(p, &len, 1); + decompress_bytes(p, pkt.room_name, len); + pkt.room_name[len] = '\0'; + } + + if (flag_bit & LOBBY_ROOM_IS_ENTER_NOT_SUCCESS_BIT) decompress_32b(p, pkt.is_enter_not_success); + if (flag_bit & LOBBY_ROOM_IS_GAME_START_BIT) decompress_32b(p, pkt.is_game_start); + if (flag_bit & LOBBY_ROOM_IS_BROADCAST_BIT) decompress_32b(p, pkt.is_broadcast); + if (flag_bit & LOBBY_ROOM_IS_UPDATE_BIT) decompress_32b(p, pkt.is_update); + if (flag_bit & LOBBY_ROOM_IS_BROADCAST_DELETE_BIT) decompress_32b(p, pkt.is_broadcast_delete); + if (flag_bit & LOBBY_ROOM_IS_CHAT_BIT) decompress_32b(p, pkt.is_chat); + + if (flag_bit & LOBBY_ROOM_COMMENT_ID_BIT) { + decompress_bytes(p, &len, 1); + decompress_bytes(p, pkt.comment_id, len); + pkt.comment_id[len] = '\0'; + } + + if (flag_bit & LOBBY_ROOM_COMMENT_BIT) { + decompress_bytes(p, &len, 1); + decompress_bytes(p, pkt.comment, len); + pkt.comment[len] = '\0'; + } + + return true; } void LinuxLobbyNetwork::send_udp(const char* id, int is_enter, int is_out, int is_chat, const char* comment, @@ -194,21 +329,21 @@ void LinuxLobbyNetwork::send_udp(const char* id, int is_enter, int is_out, int i user_data data{}; uint8_t buf[USER_DATA_SIZE]; int send_result; + uint32_t buffer_size = 0; addr_len = sizeof(addr); addr.sin_family = AF_INET; addr.sin_port = htons(LOBBY_PORT); inet_pton(AF_INET, send_ip, &addr.sin_addr); - data.magic = USER_DATA_MAGIC; snprintf(data.id, sizeof(data.id), "%s", id); data.is_enter = is_enter; data.is_out = is_out; data.is_chat = is_chat; snprintf(data.comment, sizeof(data.comment), "%s", comment); - serialize(buf, data); + buffer_size = serialize(buf, data); - send_result = sendto(sock, (char*) buf, USER_DATA_SIZE, 0, (sockaddr*) &addr, sizeof(addr)); + send_result = sendto(sock, (char*)buf, buffer_size, 0, (sockaddr*) &addr, sizeof(addr)); if (send_result < 0) perror("sendto failed: "); } @@ -217,6 +352,7 @@ bool LinuxLobbyNetwork::recv_udp(user_data& ud, char* ip) socklen_t addr_len; uint8_t buf[USER_DATA_SIZE]; int recv_result; + bool is_deserialize_success = false; int n = epoll_wait(epfd, events, MAX_EVENTS, 0); if (n < 0) { @@ -242,14 +378,13 @@ bool LinuxLobbyNetwork::recv_udp(user_data& ud, char* ip) break; } } - else if (recv_result != USER_DATA_SIZE) + else if (recv_result < LOBBY_MAGIC_SIZE) break; inet_ntop(AF_INET, &addr.sin_addr, ip, 16); - deserialize(buf, ud); + is_deserialize_success = deserialize(buf, ud); - if(ud.magic != USER_DATA_MAGIC) - break; + if (is_deserialize_success == false) break; return true; } @@ -270,13 +405,13 @@ void LinuxLobbyNetwork::send_udp(const char* room_master_id, uint8_t buf[ROOM_DATA_SIZE]; int send_result; int index = 0; + uint32_t buffer_size = 0; addr_len = sizeof(addr); addr.sin_family = AF_INET; addr.sin_port = htons(LOBBY_PORT); inet_pton(AF_INET, send_ip, &addr.sin_addr); - data.magic = ROOM_DATA_MAGIC; snprintf(data.room_master_id, sizeof(data.room_master_id), "%s", room_master_id); for (const auto& [id, ip] : ids_ips) snprintf(data.id[index++], sizeof(data.id[0]), "%s", id.c_str()); @@ -290,9 +425,9 @@ void LinuxLobbyNetwork::send_udp(const char* room_master_id, data.is_chat = is_chat; snprintf(data.comment_id, sizeof(data.comment_id), "%s", comment_id); snprintf(data.comment, sizeof(data.comment), "%s", comment); - serialize(buf, data); + buffer_size = serialize(buf, data); - send_result = sendto(sock, (char*) buf, ROOM_DATA_SIZE, 0, (sockaddr*) &addr, sizeof(addr)); + send_result = sendto(sock, (char*) buf, buffer_size, 0, (sockaddr*) &addr, sizeof(addr)); if (send_result < 0) perror("sendto failed: "); } @@ -301,6 +436,7 @@ bool LinuxLobbyNetwork::recv_udp(room_data& rd, char* ip) socklen_t addr_len; uint8_t buf[ROOM_DATA_SIZE]; int recv_result; + bool is_deserialize_success = false; int n = epoll_wait(epfd, events, MAX_EVENTS, 0); if (n < 0) { @@ -325,14 +461,13 @@ bool LinuxLobbyNetwork::recv_udp(room_data& rd, char* ip) break; } } - else if (recv_result != ROOM_DATA_SIZE) + else if (recv_result < LOBBY_MAGIC_SIZE) break; inet_ntop(AF_INET, &addr.sin_addr, ip, 16); - deserialize(buf, rd); + is_deserialize_success = deserialize(buf, rd); - if (rd.magic != ROOM_DATA_MAGIC) - break; + if (is_deserialize_success == false) break; return true; } diff --git a/platform/linux/source/network/linux_network.cpp b/platform/linux/source/network/linux_network.cpp index 50bc6e3f..aede227d 100644 --- a/platform/linux/source/network/linux_network.cpp +++ b/platform/linux/source/network/linux_network.cpp @@ -59,101 +59,91 @@ void LinuxNetwork::write_bytes(uint8_t*& p, const void* data, size_t size) p += size; } +int32_t LinuxNetwork::read_32b(const uint8_t*& p) +{ + int32_t n; + memcpy(&n, p, 4); + p += 4; + return ntohl(n); +} + +void LinuxNetwork::read_bytes(const uint8_t*& p, void* dst, size_t size) +{ + memcpy(dst, p, size); + p += size; +} + +void LinuxNetwork::compress_32b(uint8_t*& p, uint32_t& flag_bit, int32_t v, uint32_t bit_check) +{ + uint8_t itc = 0; + + flag_bit |= bit_check; + itc = static_cast(v); + write_bytes(p, &itc, 1); +} + +void LinuxNetwork::compress_bytes(uint8_t*& p, uint32_t& flag_bit, const void* data, size_t size, + uint32_t bit_check) +{ + flag_bit |= bit_check; + write_bytes(p, data, size); +} + +void LinuxNetwork::decompress_32b(const uint8_t*& p, int32_t& v) +{ + uint8_t itc; + read_bytes(p, &itc, 1); + v = static_cast(itc); +} + +void LinuxNetwork::decompress_bytes(const uint8_t*& p, void* data, size_t size) +{ + read_bytes(p, data, size); +} + uint32_t LinuxNetwork::serialize(uint8_t* buf, const Packet& pkt) { uint8_t* p = buf; uint8_t* op = buf; - uint32_t size = 0; uint32_t flag_bit = 0; - uint8_t itc = 0; + uint8_t len = 0; write_32b(p, PACKET_MAGIC); - size += 4; op += 4; // flag bit p += 4; - size += 4; - flag_bit |= BOARD_BIT; for (int i = 0; i < 20; ++i) { for (int j = 0; j < 10; ++j) { - itc = static_cast(pkt.board[i][j]); - write_bytes(p, &itc, 1); - size += 1; + compress_32b(p, flag_bit, pkt.board[i][j], BOARD_BIT); } } + compress_32b(p, flag_bit, pkt.type, TYPE_BIT); + compress_32b(p, flag_bit, pkt.rotation, ROTATION_BIT); + compress_32b(p, flag_bit, pkt.r, R_BIT); + compress_32b(p, flag_bit, pkt.c, C_BIT); + compress_32b(p, flag_bit, pkt.deleted_line, DELETED_LINE_BIT); - flag_bit |= TYPE_BIT; - itc = static_cast(pkt.type); - write_bytes(p, &itc, 1); - size += 1; - - flag_bit |= ROTATION_BIT; - itc = static_cast(pkt.rotation); - write_bytes(p, &itc, 1); - size += 1; - - flag_bit |= R_BIT; - itc = static_cast(pkt.r); - write_bytes(p, &itc, 1); - size += 1; - - flag_bit |= C_BIT; - itc = static_cast(pkt.c); - write_bytes(p, &itc, 1); - size += 1; - - flag_bit |= DELETED_LINE_BIT; - itc = static_cast(pkt.deleted_line); - write_bytes(p, &itc, 1); - size += 1; - - if (pkt.is_game_over == 1) { - flag_bit |= IS_GAME_OVER_BIT; - itc = static_cast(pkt.is_game_over); - write_bytes(p, &itc, 1); - size += 1; - } - - if (pkt.is_win == 1) { - flag_bit |= IS_WIN_BIT; - itc = static_cast(pkt.is_win); - write_bytes(p, &itc, 1); - size += 1; - } + if (pkt.is_game_over == 1) compress_32b(p, flag_bit, pkt.is_game_over, IS_GAME_OVER_BIT); + if (pkt.is_win == 1) compress_32b(p, flag_bit, pkt.is_win, IS_WIN_BIT); - flag_bit |= ID_BIT; - write_bytes(p, pkt.id, 9); - size += 9; + len = static_cast(strlen(pkt.id)); + compress_bytes(p, flag_bit, &len, 1, ID_BIT); + compress_bytes(p, flag_bit, pkt.id, len, ID_BIT); // flag bit write_32b(op, flag_bit); - return size; -} - -int32_t LinuxNetwork::read_32b(const uint8_t*& p) -{ - int32_t n; - memcpy(&n, p, 4); - p += 4; - return ntohl(n); -} - -void LinuxNetwork::read_bytes(const uint8_t*& p, void* dst, size_t size) -{ - memcpy(dst, p, size); - p += size; + return (p - buf); } bool LinuxNetwork::deserialize(const uint8_t* buf, Packet& pkt) { const uint8_t* p = buf; - uint32_t magic = 0; uint32_t flag_bit = 0; - uint8_t itc = 0; + uint8_t len = 0; magic = read_32b(p); if (magic != PACKET_MAGIC) return false; @@ -165,50 +155,21 @@ bool LinuxNetwork::deserialize(const uint8_t* buf, Packet& pkt) if (flag_bit & BOARD_BIT) { for (int i = 0; i < 20; ++i) { for (int j = 0; j < 10; ++j) { - read_bytes(p, &itc, 1); - pkt.board[i][j] = static_cast(itc); + decompress_32b(p, pkt.board[i][j]); } } } - - if (flag_bit & TYPE_BIT) { - read_bytes(p, &itc, 1); - pkt.type = static_cast(itc); - } - - if (flag_bit & ROTATION_BIT) { - read_bytes(p, &itc, 1); - pkt.rotation = static_cast(itc); - } - - if (flag_bit & R_BIT) { - read_bytes(p, &itc, 1); - pkt.r = static_cast(itc); - } - - if (flag_bit & C_BIT) { - read_bytes(p, &itc, 1); - pkt.c = static_cast(itc); - } - - if (flag_bit & DELETED_LINE_BIT) { - read_bytes(p, &itc, 1); - pkt.deleted_line = static_cast(itc); - } - - if (flag_bit & IS_GAME_OVER_BIT) { - read_bytes(p, &itc, 1); - pkt.is_game_over = static_cast(itc); - } - - if (flag_bit & IS_WIN_BIT) { - read_bytes(p, &itc, 1); - pkt.is_win = static_cast(itc); - } - + if (flag_bit & TYPE_BIT) decompress_32b(p, pkt.type); + if (flag_bit & ROTATION_BIT) decompress_32b(p, pkt.rotation); + if (flag_bit & R_BIT) decompress_32b(p, pkt.r); + if (flag_bit & C_BIT) decompress_32b(p, pkt.c); + if (flag_bit & DELETED_LINE_BIT) decompress_32b(p, pkt.deleted_line); + if (flag_bit & IS_GAME_OVER_BIT) decompress_32b(p, pkt.is_game_over); + if (flag_bit & IS_WIN_BIT) decompress_32b(p, pkt.is_win); if (flag_bit & ID_BIT) { - read_bytes(p, pkt.id, PACKET_ID_SIZE); - pkt.id[PACKET_ID_SIZE - 1] = '\0'; + decompress_bytes(p, &len, 1); + decompress_bytes(p, pkt.id, len); + pkt.id[len] = '\0'; } return true; diff --git a/platform/window/include/lobby_network/window_lobby_network.hpp b/platform/window/include/lobby_network/window_lobby_network.hpp index c4680b55..cbcdbce3 100644 --- a/platform/window/include/lobby_network/window_lobby_network.hpp +++ b/platform/window/include/lobby_network/window_lobby_network.hpp @@ -20,13 +20,20 @@ class WindowLobbyNetwork : public ILobbyNetwork void write_bytes(uint8_t*& p, const void* data, size_t size); int32_t read_32b(const uint8_t*& p); void read_bytes(const uint8_t*& p, void* dst, size_t size); + + void compress_32b(uint8_t*& p, uint32_t& flag_bit, int32_t v, uint32_t bit_check); + void compress_bytes(uint8_t*& p, uint32_t& flag_bit, const void* data, size_t size, + uint32_t bit_check); + void decompress_32b(const uint8_t*& p, int32_t& v); + void decompress_bytes(const uint8_t*& p, void* data, size_t size); // user_data - void serialize(uint8_t* buf, const user_data& pkt); - void deserialize(const uint8_t* buf, user_data& pkt); + uint32_t serialize(uint8_t* buf, const user_data& pkt); + bool deserialize(const uint8_t* buf, user_data& pkt); // room_data - void serialize(uint8_t* buf, const room_data& pkt); - void deserialize(const uint8_t* buf, room_data& pkt); + uint32_t serialize(uint8_t* buf, const room_data& pkt); + bool deserialize(const uint8_t* buf, room_data& pkt); + public: WindowLobbyNetwork(); void find_broadcast_ip(char* broadcast_ip) override; diff --git a/platform/window/include/network/window_network.hpp b/platform/window/include/network/window_network.hpp index 0c366249..4fc9d015 100644 --- a/platform/window/include/network/window_network.hpp +++ b/platform/window/include/network/window_network.hpp @@ -26,12 +26,19 @@ class WindowNetwork : public INetwork void write_32b(uint8_t*& p, int32_t v); void write_bytes(uint8_t*& p, const void* data, size_t size); - uint32_t serialize(uint8_t* buf, const Packet& pkt); int32_t read_32b(const uint8_t*& p); void read_bytes(const uint8_t*& p, void* dst, size_t size); + + void compress_32b(uint8_t*& p, uint32_t& flag_bit, int32_t v, uint32_t bit_check); + void compress_bytes(uint8_t*& p, uint32_t& flag_bit, const void* data, + size_t size, uint32_t bit_check); + void decompress_32b(const uint8_t*& p, int32_t& v); + void decompress_bytes(const uint8_t*& p, void* data, size_t size); + + uint32_t serialize(uint8_t* buf, const Packet& pkt); bool deserialize(const uint8_t* buf, Packet& pkt); -public: + public: WindowNetwork(); // 부모 클래스(INetwork)의 가상 함수 오버라이드 diff --git a/platform/window/source/lobby_network/window_lobby_network.cpp b/platform/window/source/lobby_network/window_lobby_network.cpp index f444dbb4..9fa392b9 100644 --- a/platform/window/source/lobby_network/window_lobby_network.cpp +++ b/platform/window/source/lobby_network/window_lobby_network.cpp @@ -137,76 +137,212 @@ void WindowLobbyNetwork::read_bytes(const uint8_t*& p, void* dst, size_t size) p += size; } +void WindowLobbyNetwork::compress_32b(uint8_t*& p, uint32_t& flag_bit, int32_t v, + uint32_t bit_check) +{ + uint8_t itc = 0; + + flag_bit |= bit_check; + itc = static_cast(v); + write_bytes(p, &itc, 1); +} + +void WindowLobbyNetwork::compress_bytes(uint8_t*& p, uint32_t& flag_bit, const void* data, + size_t size, uint32_t bit_check) +{ + flag_bit |= bit_check; + write_bytes(p, data, size); +} + +void WindowLobbyNetwork::decompress_32b(const uint8_t*& p, int32_t& v) +{ + uint8_t itc; + read_bytes(p, &itc, 1); + v = static_cast(itc); +} + +void WindowLobbyNetwork::decompress_bytes(const uint8_t*& p, void* data, size_t size) +{ + read_bytes(p, data, size); +} + // user_data -void WindowLobbyNetwork::serialize(uint8_t* buf, const user_data& pkt) +uint32_t WindowLobbyNetwork::serialize(uint8_t* buf, const user_data& pkt) { uint8_t* p = buf; + uint8_t* op = buf; + uint32_t flag_bit = 0; + uint8_t len = 0; - write_32b(p, pkt.magic); - write_bytes(p, pkt.id, 9); - write_32b(p, pkt.is_enter); - write_32b(p, pkt.is_out); - write_32b(p, pkt.is_chat); - write_bytes(p, pkt.comment, 101); + write_32b(p, USER_DATA_MAGIC); + op += 4; + + // flag bit + p += 4; + + len = static_cast(strlen(pkt.id)); + compress_bytes(p, flag_bit, &len, 1, LOBBY_USER_ID_BIT); + compress_bytes(p, flag_bit, pkt.id, len, LOBBY_USER_ID_BIT); + + if (pkt.is_enter == 1) compress_32b(p, flag_bit, pkt.is_enter, LOBBY_USER_IS_ENTER_BIT); + if (pkt.is_out == 1) compress_32b(p, flag_bit, pkt.is_out, LOBBY_USER_IS_OUT_BIT); + if (pkt.is_chat == 1) compress_32b(p, flag_bit, pkt.is_chat, LOBBY_USER_IS_CHAT_BIT); + + len = static_cast(strlen(pkt.comment)); + if (len > 0) { + compress_bytes(p, flag_bit, &len, 1, LOBBY_USER_COMMENT_BIT); + compress_bytes(p, flag_bit, pkt.comment, len, LOBBY_USER_COMMENT_BIT); + } + + write_32b(op, flag_bit); + + return (p - buf); } -void WindowLobbyNetwork::deserialize(const uint8_t* buf, user_data& pkt) +bool WindowLobbyNetwork::deserialize(const uint8_t* buf, user_data& pkt) { const uint8_t* p = buf; + uint32_t magic = 0; + uint32_t flag_bit = 0; + uint8_t len = 0; + + magic = read_32b(p); + if (magic != USER_DATA_MAGIC) return false; + + flag_bit = read_32b(p); + + memset((void*) &pkt, 0, USER_DATA_SIZE); + + if (flag_bit & LOBBY_USER_ID_BIT) { + decompress_bytes(p, &len, 1); + decompress_bytes(p, pkt.id, len); + pkt.id[len] = '\0'; + } + if (flag_bit & LOBBY_USER_IS_ENTER_BIT) decompress_32b(p, pkt.is_enter); + if (flag_bit & LOBBY_USER_IS_OUT_BIT) decompress_32b(p, pkt.is_out); + if (flag_bit & LOBBY_USER_IS_CHAT_BIT) decompress_32b(p, pkt.is_chat); + if (flag_bit & LOBBY_USER_COMMENT_BIT) { + decompress_bytes(p, &len, 1); + decompress_bytes(p, pkt.id, len); + pkt.id[len] = '\0'; + } - pkt.magic = read_32b(p); - read_bytes(p, pkt.id, 9); - pkt.id[8] = '\0'; - pkt.is_enter = read_32b(p); - pkt.is_out = read_32b(p); - pkt.is_chat = read_32b(p); - read_bytes(p, pkt.comment, 101); + return true; } // room_data -void WindowLobbyNetwork::serialize(uint8_t* buf, const room_data& pkt) +uint32_t WindowLobbyNetwork::serialize(uint8_t* buf, const room_data& pkt) { uint8_t* p = buf; - - write_32b(p, pkt.magic); - write_bytes(p, pkt.room_master_id, 9); - for (int i = 0; i < 4; ++i) - { - write_bytes(p, pkt.id[i], 9); + uint8_t* op = buf; + uint32_t flag_bit = 0; + uint8_t len = 0; + + write_32b(p, ROOM_DATA_MAGIC); + op += 4; + + // flag bit + p += 4; + + len = static_cast(strlen(pkt.room_master_id)); + compress_bytes(p, flag_bit, &len, 1, LOBBY_ROOM_ROOM_MASTER_ID_BIT); + compress_bytes(p, flag_bit, pkt.room_master_id, len, LOBBY_ROOM_ROOM_MASTER_ID_BIT); + + if (pkt.id_len > 0) { + compress_32b(p, flag_bit, pkt.id_len, LOBBY_ROOM_ID_LEN_BIT); + for (int i = 0; i < pkt.id_len; ++i) { + len = static_cast(strlen(pkt.id[i])); + compress_bytes(p, flag_bit, &len, 1, LOBBY_ROOM_ID_BIT); + compress_bytes(p, flag_bit, pkt.id[i], len, LOBBY_ROOM_ID_BIT); + } } - write_bytes(p, pkt.room_name, 9); - write_32b(p, pkt.id_len); - write_32b(p, pkt.is_enter_not_success); - write_32b(p, pkt.is_game_start); - write_32b(p, pkt.is_broadcast); - write_32b(p, pkt.is_update); - write_32b(p, pkt.is_broadcast_delete); - write_32b(p, pkt.is_chat); - write_bytes(p, pkt.comment_id, 9); - write_bytes(p, pkt.comment, 101); + + len = static_cast(strlen(pkt.room_name)); + compress_bytes(p, flag_bit, &len, 1, LOBBY_ROOM_ROOM_NAME_BIT); + compress_bytes(p, flag_bit, pkt.room_name, len, LOBBY_ROOM_ROOM_NAME_BIT); + + if (pkt.is_enter_not_success == 1) + compress_32b(p, flag_bit, pkt.is_enter_not_success, LOBBY_ROOM_IS_ENTER_NOT_SUCCESS_BIT); + if (pkt.is_game_start == 1) + compress_32b(p, flag_bit, pkt.is_game_start, LOBBY_ROOM_IS_GAME_START_BIT); + if (pkt.is_broadcast == 1) + compress_32b(p, flag_bit, pkt.is_broadcast, LOBBY_ROOM_IS_BROADCAST_BIT); + if (pkt.is_update == 1) compress_32b(p, flag_bit, pkt.is_update, LOBBY_ROOM_IS_UPDATE_BIT); + if (pkt.is_broadcast_delete == 1) + compress_32b(p, flag_bit, pkt.is_broadcast_delete, LOBBY_ROOM_IS_BROADCAST_DELETE_BIT); + if (pkt.is_chat == 1) + compress_32b(p, flag_bit, pkt.is_chat, LOBBY_ROOM_IS_CHAT_BIT); + + if (pkt.is_chat == 1) { + len = static_cast(strlen(pkt.comment_id)); + compress_bytes(p, flag_bit, &len, 1, LOBBY_ROOM_COMMENT_ID_BIT); + compress_bytes(p, flag_bit, pkt.comment_id, len, LOBBY_ROOM_COMMENT_ID_BIT); + len = static_cast(strlen(pkt.comment)); + compress_bytes(p, flag_bit, &len, 1, LOBBY_ROOM_COMMENT_BIT); + compress_bytes(p, flag_bit, pkt.comment, len, LOBBY_ROOM_COMMENT_BIT); + } + + write_32b(op, flag_bit); + + return (p - buf); } -void WindowLobbyNetwork::deserialize(const uint8_t* buf, room_data& pkt) +bool WindowLobbyNetwork::deserialize(const uint8_t* buf, room_data& pkt) { const uint8_t* p = buf; + uint32_t magic = 0; + uint32_t flag_bit = 0; + uint8_t len = 0; + + magic = read_32b(p); + if (magic != USER_DATA_MAGIC) return false; + + flag_bit = read_32b(p); - pkt.magic = read_32b(p); - read_bytes(p, pkt.room_master_id, 9); - pkt.room_master_id[8] = '\0'; - for (int i = 0; i < 4; ++i) { - read_bytes(p, pkt.id[i], 9); - pkt.id[i][8] = '\0'; + memset((void*) &pkt, 0, ROOM_DATA_SIZE); + + if (flag_bit & LOBBY_ROOM_ROOM_MASTER_ID_BIT) { + decompress_bytes(p, &len, 1); + decompress_bytes(p, pkt.room_master_id, len); + pkt.room_master_id[len] = '\0'; + } + + if (flag_bit & LOBBY_ROOM_ID_LEN_BIT) decompress_32b(p, pkt.id_len); + + if (flag_bit & LOBBY_ROOM_ID_BIT) { + for (int i = 0; i < pkt.id_len; ++i) { + decompress_bytes(p, &len, 1); + decompress_bytes(p, pkt.id[i], len); + pkt.id[i][len] = '\0'; + } + } + + if (flag_bit & LOBBY_ROOM_ROOM_NAME_BIT) { + decompress_bytes(p, &len, 1); + decompress_bytes(p, pkt.room_name, len); + pkt.room_name[len] = '\0'; + } + + if (flag_bit & LOBBY_ROOM_IS_ENTER_NOT_SUCCESS_BIT) decompress_32b(p, pkt.is_enter_not_success); + if (flag_bit & LOBBY_ROOM_IS_GAME_START_BIT) decompress_32b(p, pkt.is_game_start); + if (flag_bit & LOBBY_ROOM_IS_BROADCAST_BIT) decompress_32b(p, pkt.is_broadcast); + if (flag_bit & LOBBY_ROOM_IS_UPDATE_BIT) decompress_32b(p, pkt.is_update); + if (flag_bit & LOBBY_ROOM_IS_BROADCAST_DELETE_BIT) decompress_32b(p, pkt.is_broadcast_delete); + if (flag_bit & LOBBY_ROOM_IS_CHAT_BIT) decompress_32b(p, pkt.is_chat); + + if (flag_bit & LOBBY_ROOM_COMMENT_ID_BIT) { + decompress_bytes(p, &len, 1); + decompress_bytes(p, pkt.comment_id, len); + pkt.comment_id[len] = '\0'; } - read_bytes(p, pkt.room_name, 9); - pkt.id_len = read_32b(p); - pkt.is_enter_not_success = read_32b(p); - pkt.is_game_start = read_32b(p); - pkt.is_broadcast = read_32b(p); - pkt.is_update = read_32b(p); - pkt.is_broadcast_delete = read_32b(p); - pkt.is_chat = read_32b(p); - read_bytes(p, pkt.comment_id, 9); - read_bytes(p, pkt.comment, 101); + + if (flag_bit & LOBBY_ROOM_COMMENT_BIT) { + decompress_bytes(p, &len, 1); + decompress_bytes(p, pkt.comment, len); + pkt.comment[len] = '\0'; + } + + return true; } void WindowLobbyNetwork::send_udp(const char* id, int is_enter, int is_out, int is_chat, const char* comment, @@ -215,8 +351,9 @@ void WindowLobbyNetwork::send_udp(const char* id, int is_enter, int is_out, int SOCKADDR_IN addr; int addr_len; user_data data{}; - uint8_t buf[USER_DATA_SIZE]; + uint8_t buf[LOBBY_BUFFER_SIZE]; int send_result; + uint32_t buffer_size = 0; ZeroMemory(&addr, sizeof(addr)); addr_len = sizeof(addr); @@ -224,16 +361,15 @@ void WindowLobbyNetwork::send_udp(const char* id, int is_enter, int is_out, int addr.sin_port = htons(LOBBY_PORT); inet_pton(AF_INET, send_ip, &addr.sin_addr); - data.magic = USER_DATA_MAGIC; snprintf(data.id, sizeof(data.id), "%s", id); data.is_enter = is_enter; data.is_out = is_out; data.is_chat = is_chat; snprintf(data.comment, sizeof(data.comment), "%s", comment); - serialize(buf, data); + buffer_size = serialize(buf, data); - send_result = sendto(sock, (char*) buf, USER_DATA_SIZE, 0, (SOCKADDR*) &addr, - sizeof(addr)); + send_result = sendto(sock, (char*)buf, buffer_size, 0, (SOCKADDR*) &addr, + sizeof(addr)); if (send_result == SOCKET_ERROR) printf("sendto failed: %d\n", send_result); } @@ -241,9 +377,10 @@ bool WindowLobbyNetwork::recv_udp(user_data& ud, char* ip) { SOCKADDR_IN addr; int addr_len; - uint8_t buf[USER_DATA_SIZE]; + uint8_t buf[LOBBY_BUFFER_SIZE]; int recv_result; bool data_received = false; + bool is_deserialize_success = false; ZeroMemory(&addr, sizeof(addr)); addr_len = sizeof(addr); @@ -262,14 +399,14 @@ bool WindowLobbyNetwork::recv_udp(user_data& ud, char* ip) printf("recvfrom failed: %d\n", err); return false; } - else if (recv_result != USER_DATA_SIZE) + else if (recv_result < LOBBY_MAGIC_SIZE) return false; // inet_ntop(AF_INET, &addr.sin_addr, ip, 16); - deserialize(buf, ud); + is_deserialize_success = deserialize(buf, ud); - if (ud.magic != USER_DATA_MAGIC) data_received = false; + if (is_deserialize_success == false) data_received = false; data_received = true; } @@ -288,9 +425,10 @@ void WindowLobbyNetwork::send_udp(const char* room_master_id, SOCKADDR_IN addr; int addr_len; room_data data{}; - uint8_t buf[ROOM_DATA_SIZE]; + uint8_t buf[LOBBY_BUFFER_SIZE]; int send_result; int index = 0; + uint32_t buffer_size = 0; ZeroMemory(&addr, sizeof(addr)); addr_len = sizeof(addr); @@ -298,7 +436,6 @@ void WindowLobbyNetwork::send_udp(const char* room_master_id, addr.sin_port = htons(LOBBY_PORT); inet_pton(AF_INET, send_ip, &addr.sin_addr); - data.magic = ROOM_DATA_MAGIC; snprintf(data.room_master_id, sizeof(data.room_master_id), "%s", room_master_id); for (const auto& [id, ip] : ids_ips) snprintf(data.id[index++], sizeof(data.id[0]), "%s", id.c_str()); @@ -312,9 +449,9 @@ void WindowLobbyNetwork::send_udp(const char* room_master_id, data.is_chat = is_chat; snprintf(data.comment_id, sizeof(data.comment_id), "%s", comment_id); snprintf(data.comment, sizeof(data.comment), "%s", comment); - serialize(buf, data); + buffer_size = serialize(buf, data); - send_result = sendto(sock, (char*) buf, ROOM_DATA_SIZE, 0, (SOCKADDR*) &addr, sizeof(addr)); + send_result = sendto(sock, (char*)buf, buffer_size, 0, (SOCKADDR*) &addr, sizeof(addr)); if (send_result == SOCKET_ERROR) printf("sendto failed: %d\n", send_result); } @@ -322,9 +459,10 @@ bool WindowLobbyNetwork::recv_udp(room_data& rd, char* ip) { SOCKADDR_IN addr; int addr_len; - uint8_t buf[ROOM_DATA_SIZE]; + uint8_t buf[LOBBY_BUFFER_SIZE]; int recv_result; bool data_received = false; + bool is_deserialize_success = false; ZeroMemory(&addr, sizeof(addr)); addr_len = sizeof(addr); @@ -342,14 +480,14 @@ bool WindowLobbyNetwork::recv_udp(room_data& rd, char* ip) printf("recvfrom failed: %d\n", err); return false; } - else if (recv_result != ROOM_DATA_SIZE) + else if (recv_result < LOBBY_MAGIC_SIZE) return false; // inet_ntop(AF_INET, &addr.sin_addr, ip, 16); - deserialize(buf, rd); + is_deserialize_success = deserialize(buf, rd); - if (rd.magic != ROOM_DATA_MAGIC) data_received = false; + if (is_deserialize_success == false) data_received = false; data_received = true; } diff --git a/platform/window/source/network/window_network.cpp b/platform/window/source/network/window_network.cpp index 2329acea..d804d7c7 100644 --- a/platform/window/source/network/window_network.cpp +++ b/platform/window/source/network/window_network.cpp @@ -69,101 +69,91 @@ void WindowNetwork::write_bytes(uint8_t*& p, const void* data, size_t size) p += size; } +int32_t WindowNetwork::read_32b(const uint8_t*& p) +{ + int32_t n; + memcpy(&n, p, 4); + p += 4; + return ntohl(n); +} + +void WindowNetwork::read_bytes(const uint8_t*& p, void* dst, size_t size) +{ + memcpy(dst, p, size); + p += size; +} + +void WindowNetwork::compress_32b(uint8_t*& p, uint32_t& flag_bit, int32_t v, uint32_t bit_check) +{ + uint8_t itc = 0; + + flag_bit |= bit_check; + itc = static_cast(v); + write_bytes(p, &itc, 1); +} + +void WindowNetwork::compress_bytes(uint8_t*& p, uint32_t& flag_bit, const void* data, + size_t size, uint32_t bit_check) +{ + flag_bit |= bit_check; + write_bytes(p, data, size); +} + +void WindowNetwork::decompress_32b(const uint8_t*& p, int32_t& v) +{ + uint8_t itc; + read_bytes(p, &itc, 1); + v = static_cast(itc); +} + +void WindowNetwork::decompress_bytes(const uint8_t*& p, void* data, size_t size) +{ + read_bytes(p, data, size); +} + uint32_t WindowNetwork::serialize(uint8_t* buf, const Packet& pkt) { uint8_t* p = buf; uint8_t* op = buf; - uint32_t size = 0; uint32_t flag_bit = 0; - uint8_t itc = 0; + uint8_t len = 0; write_32b(p, PACKET_MAGIC); - size += 4; op += 4; // flag bit p += 4; - size += 4; - flag_bit |= BOARD_BIT; for (int i = 0; i < 20; ++i) { for (int j = 0; j < 10; ++j) { - itc = static_cast(pkt.board[i][j]); - write_bytes(p, &itc, 1); - size += 1; + compress_32b(p, flag_bit, pkt.board[i][j], BOARD_BIT); } } + compress_32b(p, flag_bit, pkt.type, TYPE_BIT); + compress_32b(p, flag_bit, pkt.rotation, ROTATION_BIT); + compress_32b(p, flag_bit, pkt.r, R_BIT); + compress_32b(p, flag_bit, pkt.c, C_BIT); + compress_32b(p, flag_bit, pkt.deleted_line, DELETED_LINE_BIT); - flag_bit |= TYPE_BIT; - itc = static_cast(pkt.type); - write_bytes(p, &itc, 1); - size += 1; - - flag_bit |= ROTATION_BIT; - itc = static_cast(pkt.rotation); - write_bytes(p, &itc, 1); - size += 1; - - flag_bit |= R_BIT; - itc = static_cast(pkt.r); - write_bytes(p, &itc, 1); - size += 1; - - flag_bit |= C_BIT; - itc = static_cast(pkt.c); - write_bytes(p, &itc, 1); - size += 1; - - flag_bit |= DELETED_LINE_BIT; - itc = static_cast(pkt.deleted_line); - write_bytes(p, &itc, 1); - size += 1; - - if (pkt.is_game_over == 1) { - flag_bit |= IS_GAME_OVER_BIT; - itc = static_cast(pkt.is_game_over); - write_bytes(p, &itc, 1); - size += 1; - } - - if (pkt.is_win == 1) { - flag_bit |= IS_WIN_BIT; - itc = static_cast(pkt.is_win); - write_bytes(p, &itc, 1); - size += 1; - } + if (pkt.is_game_over == 1) compress_32b(p, flag_bit, pkt.is_game_over, IS_GAME_OVER_BIT); + if (pkt.is_win == 1) compress_32b(p, flag_bit, pkt.is_win, IS_WIN_BIT); - flag_bit |= ID_BIT; - write_bytes(p, pkt.id, 9); - size += 9; + len = static_cast(strlen(pkt.id)); + compress_bytes(p, flag_bit, &len, 1, ID_BIT); + compress_bytes(p, flag_bit, pkt.id, len, ID_BIT); // flag bit write_32b(op, flag_bit); - return size; -} - -int32_t WindowNetwork::read_32b(const uint8_t*& p) -{ - int32_t n; - memcpy(&n, p, 4); - p += 4; - return ntohl(n); -} - -void WindowNetwork::read_bytes(const uint8_t*& p, void* dst, size_t size) -{ - memcpy(dst, p, size); - p += size; + return (p - buf); } bool WindowNetwork::deserialize(const uint8_t* buf, Packet& pkt) { const uint8_t* p = buf; - uint32_t magic = 0; uint32_t flag_bit = 0; - uint8_t itc = 0; + uint8_t len = 0; magic = read_32b(p); if (magic != PACKET_MAGIC) return false; @@ -175,50 +165,21 @@ bool WindowNetwork::deserialize(const uint8_t* buf, Packet& pkt) if (flag_bit & BOARD_BIT) { for (int i = 0; i < 20; ++i) { for (int j = 0; j < 10; ++j) { - read_bytes(p, &itc, 1); - pkt.board[i][j] = static_cast(itc); + decompress_32b(p, pkt.board[i][j]); } } } - - if (flag_bit & TYPE_BIT) { - read_bytes(p, &itc, 1); - pkt.type = static_cast(itc); - } - - if (flag_bit & ROTATION_BIT) { - read_bytes(p, &itc, 1); - pkt.rotation = static_cast(itc); - } - - if (flag_bit & R_BIT) { - read_bytes(p, &itc, 1); - pkt.r = static_cast(itc); - } - - if (flag_bit & C_BIT) { - read_bytes(p, &itc, 1); - pkt.c = static_cast(itc); - } - - if (flag_bit & DELETED_LINE_BIT) { - read_bytes(p, &itc, 1); - pkt.deleted_line = static_cast(itc); - } - - if (flag_bit & IS_GAME_OVER_BIT) { - read_bytes(p, &itc, 1); - pkt.is_game_over = static_cast(itc); - } - - if (flag_bit & IS_WIN_BIT) { - read_bytes(p, &itc, 1); - pkt.is_win = static_cast(itc); - } - + if (flag_bit & TYPE_BIT) decompress_32b(p, pkt.type); + if (flag_bit & ROTATION_BIT) decompress_32b(p, pkt.rotation); + if (flag_bit & R_BIT) decompress_32b(p, pkt.r); + if (flag_bit & C_BIT) decompress_32b(p, pkt.c); + if (flag_bit & DELETED_LINE_BIT) decompress_32b(p, pkt.deleted_line); + if (flag_bit & IS_GAME_OVER_BIT) decompress_32b(p, pkt.is_game_over); + if (flag_bit & IS_WIN_BIT) decompress_32b(p, pkt.is_win); if (flag_bit & ID_BIT) { - read_bytes(p, pkt.id, PACKET_ID_SIZE); - pkt.id[PACKET_ID_SIZE - 1] = '\0'; + decompress_bytes(p, &len, 1); + decompress_bytes(p, pkt.id, len); + pkt.id[len] = '\0'; } return true; @@ -229,7 +190,7 @@ void WindowNetwork::send_udp(const Board& board, const Tetromino& tetromino, int { Packet pkt{}; auto [pos_r, pos_c] = tetromino.get_pos(); - uint8_t buf[PACKET_SIZE]; + uint8_t buf[BUFFER_SIZE]; SOCKADDR_IN another_user; ZeroMemory(&another_user, sizeof(another_user)); another_user.sin_family = AF_INET; @@ -277,7 +238,7 @@ void WindowNetwork::send_relay_udp(const Packet& packet, std::vector> ids_ips) { char* another_user_ip; - uint8_t buf[PACKET_SIZE]; + uint8_t buf[BUFFER_SIZE]; SOCKADDR_IN another_user; uint32_t buffer_size = 0; int send_result = 0; @@ -318,7 +279,7 @@ void WindowNetwork::send_relay_udp(const Packet& packet, bool WindowNetwork::recv_udp(Packet& recv_pkt) { - uint8_t buf[PACKET_SIZE]; + uint8_t buf[BUFFER_SIZE]; bool data_received = false; SOCKADDR_IN client_addr; int addr_len = sizeof(client_addr); @@ -330,7 +291,7 @@ bool WindowNetwork::recv_udp(Packet& recv_pkt) if (ret > 0) { if (fds[0].revents & POLLIN) { - r = recvfrom(server_sock, (char*) buf, PACKET_SIZE, 0, (SOCKADDR*) &client_addr, + r = recvfrom(server_sock, (char*) buf, BUFFER_SIZE, 0, (SOCKADDR*) &client_addr, &addr_len); if (r == SOCKET_ERROR) { From d17d5ea828d63420dbcf59dff44ce4f910fe461a Mon Sep 17 00:00:00 2001 From: Choi Yusun <43121372+ggstone0523@users.noreply.github.com> Date: Fri, 13 Mar 2026 18:02:55 +0900 Subject: [PATCH 05/14] [Fix] Change buffer size of linux --- .../linux/source/lobby_network/linux_lobby_network.cpp | 8 ++++---- platform/linux/source/network/linux_network.cpp | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/platform/linux/source/lobby_network/linux_lobby_network.cpp b/platform/linux/source/lobby_network/linux_lobby_network.cpp index 2ae20468..aab9459b 100644 --- a/platform/linux/source/lobby_network/linux_lobby_network.cpp +++ b/platform/linux/source/lobby_network/linux_lobby_network.cpp @@ -327,7 +327,7 @@ void LinuxLobbyNetwork::send_udp(const char* id, int is_enter, int is_out, int i sockaddr_in addr{}; int addr_len; user_data data{}; - uint8_t buf[USER_DATA_SIZE]; + uint8_t buf[LOBBY_BUFFER_SIZE]; int send_result; uint32_t buffer_size = 0; @@ -350,7 +350,7 @@ void LinuxLobbyNetwork::send_udp(const char* id, int is_enter, int is_out, int i bool LinuxLobbyNetwork::recv_udp(user_data& ud, char* ip) { socklen_t addr_len; - uint8_t buf[USER_DATA_SIZE]; + uint8_t buf[LOBBY_BUFFER_SIZE]; int recv_result; bool is_deserialize_success = false; int n = epoll_wait(epfd, events, MAX_EVENTS, 0); @@ -402,7 +402,7 @@ void LinuxLobbyNetwork::send_udp(const char* room_master_id, sockaddr_in addr{}; int addr_len; room_data data{}; - uint8_t buf[ROOM_DATA_SIZE]; + uint8_t buf[LOBBY_BUFFER_SIZE]; int send_result; int index = 0; uint32_t buffer_size = 0; @@ -434,7 +434,7 @@ void LinuxLobbyNetwork::send_udp(const char* room_master_id, bool LinuxLobbyNetwork::recv_udp(room_data& rd, char* ip) { socklen_t addr_len; - uint8_t buf[ROOM_DATA_SIZE]; + uint8_t buf[LOBBY_BUFFER_SIZE]; int recv_result; bool is_deserialize_success = false; int n = epoll_wait(epfd, events, MAX_EVENTS, 0); diff --git a/platform/linux/source/network/linux_network.cpp b/platform/linux/source/network/linux_network.cpp index aede227d..fd93d50e 100644 --- a/platform/linux/source/network/linux_network.cpp +++ b/platform/linux/source/network/linux_network.cpp @@ -178,7 +178,7 @@ bool LinuxNetwork::deserialize(const uint8_t* buf, Packet& pkt) void LinuxNetwork::send_udp(const Board& board, const Tetromino& tetromino, const int deleted_line, int is_game_over, int is_win, const char* another_user_ip, const char* my_id) { Packet pkt; - uint8_t buf[PACKET_SIZE]; + uint8_t buf[BUFFER_SIZE]; auto [pos_r, pos_c] = tetromino.get_pos(); sockaddr_in another_user; int send_result; @@ -223,7 +223,7 @@ void LinuxNetwork::send_relay_udp(const Packet& packet, std::vector> ids_ips) { char* another_user_ip; - uint8_t buf[PACKET_SIZE]; + uint8_t buf[BUFFER_SIZE]; int send_result; uint32_t buffer_size = 0; @@ -264,7 +264,7 @@ void LinuxNetwork::send_relay_udp(const Packet& packet, bool LinuxNetwork::recv_udp(Packet& recv_pkt) { - uint8_t buf[PACKET_SIZE]; + uint8_t buf[BUFFER_SIZE]; int n = epoll_wait(epfd, events, MAX_EVENTS, 0); bool is_deserialize_success = false; int r; @@ -281,7 +281,7 @@ bool LinuxNetwork::recv_udp(Packet& recv_pkt) sockaddr_in client{}; socklen_t len = sizeof(client); - r = recvfrom(server_sock, (char*)buf, PACKET_SIZE, 0, (sockaddr*) &client, &len); + r = recvfrom(server_sock, (char*)buf, BUFFER_SIZE, 0, (sockaddr*) &client, &len); if (r < 0) { if (errno == EAGAIN || errno == EWOULDBLOCK) { From 2a3ebaaf5a9e72bf22adb65b9facbff875529602 Mon Sep 17 00:00:00 2001 From: Choi Yusun <43121372+ggstone0523@users.noreply.github.com> Date: Fri, 13 Mar 2026 18:10:07 +0900 Subject: [PATCH 06/14] [Fix] fix magic value check logic --- platform/linux/source/lobby_network/linux_lobby_network.cpp | 2 +- platform/window/source/lobby_network/window_lobby_network.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/linux/source/lobby_network/linux_lobby_network.cpp b/platform/linux/source/lobby_network/linux_lobby_network.cpp index aab9459b..1d839864 100644 --- a/platform/linux/source/lobby_network/linux_lobby_network.cpp +++ b/platform/linux/source/lobby_network/linux_lobby_network.cpp @@ -271,7 +271,7 @@ bool LinuxLobbyNetwork::deserialize(const uint8_t* buf, room_data& pkt) uint8_t len = 0; magic = read_32b(p); - if (magic != USER_DATA_MAGIC) return false; + if (magic != ROOM_DATA_MAGIC) return false; flag_bit = read_32b(p); diff --git a/platform/window/source/lobby_network/window_lobby_network.cpp b/platform/window/source/lobby_network/window_lobby_network.cpp index 9fa392b9..b1aef190 100644 --- a/platform/window/source/lobby_network/window_lobby_network.cpp +++ b/platform/window/source/lobby_network/window_lobby_network.cpp @@ -295,7 +295,7 @@ bool WindowLobbyNetwork::deserialize(const uint8_t* buf, room_data& pkt) uint8_t len = 0; magic = read_32b(p); - if (magic != USER_DATA_MAGIC) return false; + if (magic != ROOM_DATA_MAGIC) return false; flag_bit = read_32b(p); From 6d803355350da3e737a21cdbc67d3cf4fe6ec19d Mon Sep 17 00:00:00 2001 From: Choi Yusun <43121372+ggstone0523@users.noreply.github.com> Date: Fri, 13 Mar 2026 18:33:05 +0900 Subject: [PATCH 07/14] [Fix] fix non init packet structure to init --- lobby/source/lobby.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lobby/source/lobby.cpp b/lobby/source/lobby.cpp index b183990c..a9c7eee4 100644 --- a/lobby/source/lobby.cpp +++ b/lobby/source/lobby.cpp @@ -183,7 +183,7 @@ bool Lobby::waiting_client() } memset(ip, 16, sizeof(ip)); - user_data received_data; + user_data received_data{}; if (network->recv_udp(received_data, ip) == false) continue; if (index >= 4 || @@ -309,7 +309,7 @@ bool Lobby::enter_lobby() } memset(room_ip, 16, sizeof(room_ip)); - room_data received_data; + room_data received_data{}; if (network->recv_udp(received_data, room_ip) == false) continue; if (received_data.is_broadcast && From b617c06644f19f5c9b78ba7a0b459c018d6fc635 Mon Sep 17 00:00:00 2001 From: Choi Yusun <43121372+ggstone0523@users.noreply.github.com> Date: Fri, 13 Mar 2026 18:42:43 +0900 Subject: [PATCH 08/14] [Fix] fix decompress comment in user_data deserialize --- platform/linux/source/lobby_network/linux_lobby_network.cpp | 2 +- platform/window/source/lobby_network/window_lobby_network.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/linux/source/lobby_network/linux_lobby_network.cpp b/platform/linux/source/lobby_network/linux_lobby_network.cpp index 1d839864..2ac7fc69 100644 --- a/platform/linux/source/lobby_network/linux_lobby_network.cpp +++ b/platform/linux/source/lobby_network/linux_lobby_network.cpp @@ -200,7 +200,7 @@ bool LinuxLobbyNetwork::deserialize(const uint8_t* buf, user_data& pkt) if (flag_bit & LOBBY_USER_IS_CHAT_BIT) decompress_32b(p, pkt.is_chat); if (flag_bit & LOBBY_USER_COMMENT_BIT) { decompress_bytes(p, &len, 1); - decompress_bytes(p, pkt.id, len); + decompress_bytes(p, pkt.comment, len); pkt.id[len] = '\0'; } diff --git a/platform/window/source/lobby_network/window_lobby_network.cpp b/platform/window/source/lobby_network/window_lobby_network.cpp index b1aef190..9af25583 100644 --- a/platform/window/source/lobby_network/window_lobby_network.cpp +++ b/platform/window/source/lobby_network/window_lobby_network.cpp @@ -223,7 +223,7 @@ bool WindowLobbyNetwork::deserialize(const uint8_t* buf, user_data& pkt) if (flag_bit & LOBBY_USER_IS_CHAT_BIT) decompress_32b(p, pkt.is_chat); if (flag_bit & LOBBY_USER_COMMENT_BIT) { decompress_bytes(p, &len, 1); - decompress_bytes(p, pkt.id, len); + decompress_bytes(p, pkt.comment, len); pkt.id[len] = '\0'; } From 39c2161821a8e74639ead66e29f962a86132c55e Mon Sep 17 00:00:00 2001 From: Choi Yusun <43121372+ggstone0523@users.noreply.github.com> Date: Fri, 13 Mar 2026 18:53:52 +0900 Subject: [PATCH 09/14] [Fix] fix user_data deserialize --- platform/linux/source/lobby_network/linux_lobby_network.cpp | 2 +- platform/window/source/lobby_network/window_lobby_network.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/linux/source/lobby_network/linux_lobby_network.cpp b/platform/linux/source/lobby_network/linux_lobby_network.cpp index 2ac7fc69..94888fc5 100644 --- a/platform/linux/source/lobby_network/linux_lobby_network.cpp +++ b/platform/linux/source/lobby_network/linux_lobby_network.cpp @@ -201,7 +201,7 @@ bool LinuxLobbyNetwork::deserialize(const uint8_t* buf, user_data& pkt) if (flag_bit & LOBBY_USER_COMMENT_BIT) { decompress_bytes(p, &len, 1); decompress_bytes(p, pkt.comment, len); - pkt.id[len] = '\0'; + pkt.comment[len] = '\0'; } return true; diff --git a/platform/window/source/lobby_network/window_lobby_network.cpp b/platform/window/source/lobby_network/window_lobby_network.cpp index 9af25583..c6506b27 100644 --- a/platform/window/source/lobby_network/window_lobby_network.cpp +++ b/platform/window/source/lobby_network/window_lobby_network.cpp @@ -224,7 +224,7 @@ bool WindowLobbyNetwork::deserialize(const uint8_t* buf, user_data& pkt) if (flag_bit & LOBBY_USER_COMMENT_BIT) { decompress_bytes(p, &len, 1); decompress_bytes(p, pkt.comment, len); - pkt.id[len] = '\0'; + pkt.comment[len] = '\0'; } return true; From b685633a991ccccd7a937b3fc3b338a848dafe9b Mon Sep 17 00:00:00 2001 From: Choi Yusun <43121372+ggstone0523@users.noreply.github.com> Date: Fri, 13 Mar 2026 19:39:21 +0900 Subject: [PATCH 10/14] [Refact] Add compress board array logic --- core/include/util/network_packet.hpp | 2 +- .../linux/source/network/linux_network.cpp | 26 ++++++++++++++++--- .../window/source/network/window_network.cpp | 25 +++++++++++++++--- 3 files changed, 44 insertions(+), 9 deletions(-) diff --git a/core/include/util/network_packet.hpp b/core/include/util/network_packet.hpp index 086af3a4..a1f608cb 100644 --- a/core/include/util/network_packet.hpp +++ b/core/include/util/network_packet.hpp @@ -17,7 +17,7 @@ serialization packet magic 4byte flag bit 4byte : 0 => board / 1 => type / 2 => rotation / 3 => r / 4 => c / 5 => deleted_line / 6 => is_game_over / 7 => is_win / 8 => id data ? byte -uint8_t board[20][10]; +uint8_t board[20][10]; => compress len + compress data uint8_t type; uint8_t rotation; uint8_t r; diff --git a/platform/linux/source/network/linux_network.cpp b/platform/linux/source/network/linux_network.cpp index fd93d50e..62b75e3e 100644 --- a/platform/linux/source/network/linux_network.cpp +++ b/platform/linux/source/network/linux_network.cpp @@ -107,6 +107,8 @@ uint32_t LinuxNetwork::serialize(uint8_t* buf, const Packet& pkt) uint8_t* op = buf; uint32_t flag_bit = 0; uint8_t len = 0; + int32_t board_block_num = 0; + int32_t board_block_type = 0; write_32b(p, PACKET_MAGIC); op += 4; @@ -114,9 +116,18 @@ uint32_t LinuxNetwork::serialize(uint8_t* buf, const Packet& pkt) // flag bit p += 4; + board_block_type = pkt.board[0][0]; for (int i = 0; i < 20; ++i) { for (int j = 0; j < 10; ++j) { - compress_32b(p, flag_bit, pkt.board[i][j], BOARD_BIT); + if (board_block_type == pkt.board[i][j]) + board_block_num++; + else + { + compress_32b(p, flag_bit, board_block_num, BOARD_BIT); + compress_32b(p, flag_bit, board_block_type, BOARD_BIT); + board_block_num = 1; + board_block_type = pkt.board[i][j]; + } } } compress_32b(p, flag_bit, pkt.type, TYPE_BIT); @@ -144,6 +155,10 @@ bool LinuxNetwork::deserialize(const uint8_t* buf, Packet& pkt) uint32_t magic = 0; uint32_t flag_bit = 0; uint8_t len = 0; + uint32_t board_size = 200; + int32_t board_block_num = 0; + int32_t board_block_type = 0; + auto* board = &pkt.board[0][0]; magic = read_32b(p); if (magic != PACKET_MAGIC) return false; @@ -153,10 +168,13 @@ bool LinuxNetwork::deserialize(const uint8_t* buf, Packet& pkt) memset((void*) &pkt, 0, PACKET_SIZE); if (flag_bit & BOARD_BIT) { - for (int i = 0; i < 20; ++i) { - for (int j = 0; j < 10; ++j) { - decompress_32b(p, pkt.board[i][j]); + while (board_size > 0) { + decompress_32b(p, board_block_num); + decompress_32b(p, board_block_type); + for (int i = 0; i < board_block_num; ++i) { + *(board++) = board_block_type; } + board_size -= board_block_num; } } if (flag_bit & TYPE_BIT) decompress_32b(p, pkt.type); diff --git a/platform/window/source/network/window_network.cpp b/platform/window/source/network/window_network.cpp index d804d7c7..c36ad839 100644 --- a/platform/window/source/network/window_network.cpp +++ b/platform/window/source/network/window_network.cpp @@ -117,6 +117,8 @@ uint32_t WindowNetwork::serialize(uint8_t* buf, const Packet& pkt) uint8_t* op = buf; uint32_t flag_bit = 0; uint8_t len = 0; + int32_t board_block_num = 0; + int32_t board_block_type = 0; write_32b(p, PACKET_MAGIC); op += 4; @@ -124,9 +126,17 @@ uint32_t WindowNetwork::serialize(uint8_t* buf, const Packet& pkt) // flag bit p += 4; + board_block_type = pkt.board[0][0]; for (int i = 0; i < 20; ++i) { for (int j = 0; j < 10; ++j) { - compress_32b(p, flag_bit, pkt.board[i][j], BOARD_BIT); + if (board_block_type == pkt.board[i][j]) + board_block_num++; + else { + compress_32b(p, flag_bit, board_block_num, BOARD_BIT); + compress_32b(p, flag_bit, board_block_type, BOARD_BIT); + board_block_num = 1; + board_block_type = pkt.board[i][j]; + } } } compress_32b(p, flag_bit, pkt.type, TYPE_BIT); @@ -154,6 +164,10 @@ bool WindowNetwork::deserialize(const uint8_t* buf, Packet& pkt) uint32_t magic = 0; uint32_t flag_bit = 0; uint8_t len = 0; + uint32_t board_size = 200; + int32_t board_block_num = 0; + int32_t board_block_type = 0; + auto* board = &pkt.board[0][0]; magic = read_32b(p); if (magic != PACKET_MAGIC) return false; @@ -163,10 +177,13 @@ bool WindowNetwork::deserialize(const uint8_t* buf, Packet& pkt) memset((void*) &pkt, 0, PACKET_SIZE); if (flag_bit & BOARD_BIT) { - for (int i = 0; i < 20; ++i) { - for (int j = 0; j < 10; ++j) { - decompress_32b(p, pkt.board[i][j]); + while (board_size > 0) { + decompress_32b(p, board_block_num); + decompress_32b(p, board_block_type); + for (int i = 0; i < board_block_num; ++i) { + *(board++) = board_block_type; } + board_size -= board_block_num; } } if (flag_bit & TYPE_BIT) decompress_32b(p, pkt.type); From c8a1201f5d5c7ad3a066be7379f93f6a1abb6500 Mon Sep 17 00:00:00 2001 From: Choi Yusun <43121372+ggstone0523@users.noreply.github.com> Date: Fri, 13 Mar 2026 19:49:34 +0900 Subject: [PATCH 11/14] [Fix] fix board serialize logic --- platform/linux/source/network/linux_network.cpp | 4 ++++ platform/window/source/network/window_network.cpp | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/platform/linux/source/network/linux_network.cpp b/platform/linux/source/network/linux_network.cpp index 62b75e3e..27442a7d 100644 --- a/platform/linux/source/network/linux_network.cpp +++ b/platform/linux/source/network/linux_network.cpp @@ -130,6 +130,10 @@ uint32_t LinuxNetwork::serialize(uint8_t* buf, const Packet& pkt) } } } + if (board_block_num > 0) { + compress_32b(p, flag_bit, board_block_num, BOARD_BIT); + compress_32b(p, flag_bit, board_block_type, BOARD_BIT); + } compress_32b(p, flag_bit, pkt.type, TYPE_BIT); compress_32b(p, flag_bit, pkt.rotation, ROTATION_BIT); compress_32b(p, flag_bit, pkt.r, R_BIT); diff --git a/platform/window/source/network/window_network.cpp b/platform/window/source/network/window_network.cpp index c36ad839..a8e835d8 100644 --- a/platform/window/source/network/window_network.cpp +++ b/platform/window/source/network/window_network.cpp @@ -139,6 +139,10 @@ uint32_t WindowNetwork::serialize(uint8_t* buf, const Packet& pkt) } } } + if (board_block_num > 0) { + compress_32b(p, flag_bit, board_block_num, BOARD_BIT); + compress_32b(p, flag_bit, board_block_type, BOARD_BIT); + } compress_32b(p, flag_bit, pkt.type, TYPE_BIT); compress_32b(p, flag_bit, pkt.rotation, ROTATION_BIT); compress_32b(p, flag_bit, pkt.r, R_BIT); From b381b4e78071c5e48c56865ea9586d9f5de2d9c6 Mon Sep 17 00:00:00 2001 From: Choi Yusun <43121372+ggstone0523@users.noreply.github.com> Date: Fri, 13 Mar 2026 19:51:53 +0900 Subject: [PATCH 12/14] [Fix] fix if statement in board serialize --- platform/linux/source/network/linux_network.cpp | 2 +- platform/window/source/network/window_network.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/linux/source/network/linux_network.cpp b/platform/linux/source/network/linux_network.cpp index 27442a7d..2ac291e3 100644 --- a/platform/linux/source/network/linux_network.cpp +++ b/platform/linux/source/network/linux_network.cpp @@ -130,7 +130,7 @@ uint32_t LinuxNetwork::serialize(uint8_t* buf, const Packet& pkt) } } } - if (board_block_num > 0) { + if (board_block_num > 1) { compress_32b(p, flag_bit, board_block_num, BOARD_BIT); compress_32b(p, flag_bit, board_block_type, BOARD_BIT); } diff --git a/platform/window/source/network/window_network.cpp b/platform/window/source/network/window_network.cpp index a8e835d8..bd7cc57b 100644 --- a/platform/window/source/network/window_network.cpp +++ b/platform/window/source/network/window_network.cpp @@ -139,7 +139,7 @@ uint32_t WindowNetwork::serialize(uint8_t* buf, const Packet& pkt) } } } - if (board_block_num > 0) { + if (board_block_num > 1) { compress_32b(p, flag_bit, board_block_num, BOARD_BIT); compress_32b(p, flag_bit, board_block_type, BOARD_BIT); } From 82dcaa3c5c44305fe3662bc4090ac40824cdfcfc Mon Sep 17 00:00:00 2001 From: Choi Yusun <43121372+ggstone0523@users.noreply.github.com> Date: Fri, 13 Mar 2026 20:26:57 +0900 Subject: [PATCH 13/14] [Refact] Change to avoid board compression if compressed is greater than uncompressed --- core/include/util/network_packet.hpp | 1 + .../linux/source/network/linux_network.cpp | 47 +++++++++++++++---- .../window/source/network/window_network.cpp | 45 ++++++++++++++---- 3 files changed, 73 insertions(+), 20 deletions(-) diff --git a/core/include/util/network_packet.hpp b/core/include/util/network_packet.hpp index a1f608cb..b261f2ec 100644 --- a/core/include/util/network_packet.hpp +++ b/core/include/util/network_packet.hpp @@ -17,6 +17,7 @@ serialization packet magic 4byte flag bit 4byte : 0 => board / 1 => type / 2 => rotation / 3 => r / 4 => c / 5 => deleted_line / 6 => is_game_over / 7 => is_win / 8 => id data ? byte +uint8_t is_board_compressed => 1: compress, 0: non-compress uint8_t board[20][10]; => compress len + compress data uint8_t type; uint8_t rotation; diff --git a/platform/linux/source/network/linux_network.cpp b/platform/linux/source/network/linux_network.cpp index 2ac291e3..bee31e9f 100644 --- a/platform/linux/source/network/linux_network.cpp +++ b/platform/linux/source/network/linux_network.cpp @@ -109,6 +109,10 @@ uint32_t LinuxNetwork::serialize(uint8_t* buf, const Packet& pkt) uint8_t len = 0; int32_t board_block_num = 0; int32_t board_block_type = 0; + uint8_t compress_board[400]; + uint8_t non_compress_board[200]; + uint8_t* c_board_p = compress_board; + uint8_t* n_c_board_p = non_compress_board; write_32b(p, PACKET_MAGIC); op += 4; @@ -123,17 +127,30 @@ uint32_t LinuxNetwork::serialize(uint8_t* buf, const Packet& pkt) board_block_num++; else { - compress_32b(p, flag_bit, board_block_num, BOARD_BIT); - compress_32b(p, flag_bit, board_block_type, BOARD_BIT); + compress_32b(c_board_p, flag_bit, board_block_num, BOARD_BIT); + compress_32b(c_board_p, flag_bit, board_block_type, BOARD_BIT); board_block_num = 1; board_block_type = pkt.board[i][j]; } + compress_32b(n_c_board_p, flag_bit, pkt.board[i][j], BOARD_BIT); } } if (board_block_num > 1) { - compress_32b(p, flag_bit, board_block_num, BOARD_BIT); - compress_32b(p, flag_bit, board_block_type, BOARD_BIT); + compress_32b(c_board_p, flag_bit, board_block_num, BOARD_BIT); + compress_32b(c_board_p, flag_bit, board_block_type, BOARD_BIT); } + + if (c_board_p - compress_board >= 200) + { + compress_32b(p, flag_bit, 0, BOARD_BIT); + compress_bytes(p, flag_bit, non_compress_board, 200, BOARD_BIT); + } + else + { + compress_32b(p, flag_bit, 1, BOARD_BIT); + compress_bytes(p, flag_bit, compress_board, c_board_p - compress_board, BOARD_BIT); + } + compress_32b(p, flag_bit, pkt.type, TYPE_BIT); compress_32b(p, flag_bit, pkt.rotation, ROTATION_BIT); compress_32b(p, flag_bit, pkt.r, R_BIT); @@ -162,6 +179,7 @@ bool LinuxNetwork::deserialize(const uint8_t* buf, Packet& pkt) uint32_t board_size = 200; int32_t board_block_num = 0; int32_t board_block_type = 0; + int32_t is_board_compressed = 0; auto* board = &pkt.board[0][0]; magic = read_32b(p); @@ -172,13 +190,22 @@ bool LinuxNetwork::deserialize(const uint8_t* buf, Packet& pkt) memset((void*) &pkt, 0, PACKET_SIZE); if (flag_bit & BOARD_BIT) { - while (board_size > 0) { - decompress_32b(p, board_block_num); - decompress_32b(p, board_block_type); - for (int i = 0; i < board_block_num; ++i) { - *(board++) = board_block_type; + decompress_32b(p, is_board_compressed); + + if (is_board_compressed == 1) { + while (board_size > 0) { + decompress_32b(p, board_block_num); + decompress_32b(p, board_block_type); + for (int i = 0; i < board_block_num; ++i) { + *(board++) = board_block_type; + } + board_size -= board_block_num; } - board_size -= board_block_num; + } + else { + for (int i = 0; i < 20; ++i) + for (int j = 0; j < 10; ++j) + decompress_32b(p, pkt.board[i][j]); } } if (flag_bit & TYPE_BIT) decompress_32b(p, pkt.type); diff --git a/platform/window/source/network/window_network.cpp b/platform/window/source/network/window_network.cpp index bd7cc57b..d26a9376 100644 --- a/platform/window/source/network/window_network.cpp +++ b/platform/window/source/network/window_network.cpp @@ -119,6 +119,10 @@ uint32_t WindowNetwork::serialize(uint8_t* buf, const Packet& pkt) uint8_t len = 0; int32_t board_block_num = 0; int32_t board_block_type = 0; + uint8_t compress_board[400]; + uint8_t non_compress_board[200]; + uint8_t* c_board_p = compress_board; + uint8_t* n_c_board_p = non_compress_board; write_32b(p, PACKET_MAGIC); op += 4; @@ -132,17 +136,28 @@ uint32_t WindowNetwork::serialize(uint8_t* buf, const Packet& pkt) if (board_block_type == pkt.board[i][j]) board_block_num++; else { - compress_32b(p, flag_bit, board_block_num, BOARD_BIT); - compress_32b(p, flag_bit, board_block_type, BOARD_BIT); + compress_32b(c_board_p, flag_bit, board_block_num, BOARD_BIT); + compress_32b(c_board_p, flag_bit, board_block_type, BOARD_BIT); board_block_num = 1; board_block_type = pkt.board[i][j]; } + compress_32b(n_c_board_p, flag_bit, pkt.board[i][j], BOARD_BIT); } } if (board_block_num > 1) { - compress_32b(p, flag_bit, board_block_num, BOARD_BIT); - compress_32b(p, flag_bit, board_block_type, BOARD_BIT); + compress_32b(c_board_p, flag_bit, board_block_num, BOARD_BIT); + compress_32b(c_board_p, flag_bit, board_block_type, BOARD_BIT); } + + if (c_board_p - compress_board >= 200) { + compress_32b(p, flag_bit, 0, BOARD_BIT); + compress_bytes(p, flag_bit, non_compress_board, 200, BOARD_BIT); + } + else { + compress_32b(p, flag_bit, 1, BOARD_BIT); + compress_bytes(p, flag_bit, compress_board, c_board_p - compress_board, BOARD_BIT); + } + compress_32b(p, flag_bit, pkt.type, TYPE_BIT); compress_32b(p, flag_bit, pkt.rotation, ROTATION_BIT); compress_32b(p, flag_bit, pkt.r, R_BIT); @@ -171,6 +186,7 @@ bool WindowNetwork::deserialize(const uint8_t* buf, Packet& pkt) uint32_t board_size = 200; int32_t board_block_num = 0; int32_t board_block_type = 0; + int32_t is_board_compressed = 0; auto* board = &pkt.board[0][0]; magic = read_32b(p); @@ -181,13 +197,22 @@ bool WindowNetwork::deserialize(const uint8_t* buf, Packet& pkt) memset((void*) &pkt, 0, PACKET_SIZE); if (flag_bit & BOARD_BIT) { - while (board_size > 0) { - decompress_32b(p, board_block_num); - decompress_32b(p, board_block_type); - for (int i = 0; i < board_block_num; ++i) { - *(board++) = board_block_type; + decompress_32b(p, is_board_compressed); + + if (is_board_compressed == 1) { + while (board_size > 0) { + decompress_32b(p, board_block_num); + decompress_32b(p, board_block_type); + for (int i = 0; i < board_block_num; ++i) { + *(board++) = board_block_type; + } + board_size -= board_block_num; } - board_size -= board_block_num; + } + else { + for (int i = 0; i < 20; ++i) + for (int j = 0; j < 10; ++j) + decompress_32b(p, pkt.board[i][j]); } } if (flag_bit & TYPE_BIT) decompress_32b(p, pkt.type); From 4798f2298c8ce2477264f5c986b5b473ff95e0c1 Mon Sep 17 00:00:00 2001 From: Choi Yusun <43121372+ggstone0523@users.noreply.github.com> Date: Fri, 13 Mar 2026 20:45:19 +0900 Subject: [PATCH 14/14] [Fix] Fix serialize seg fault error --- platform/linux/source/network/linux_network.cpp | 6 ++---- platform/window/source/network/window_network.cpp | 6 ++---- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/platform/linux/source/network/linux_network.cpp b/platform/linux/source/network/linux_network.cpp index bee31e9f..7b9eefe9 100644 --- a/platform/linux/source/network/linux_network.cpp +++ b/platform/linux/source/network/linux_network.cpp @@ -135,10 +135,8 @@ uint32_t LinuxNetwork::serialize(uint8_t* buf, const Packet& pkt) compress_32b(n_c_board_p, flag_bit, pkt.board[i][j], BOARD_BIT); } } - if (board_block_num > 1) { - compress_32b(c_board_p, flag_bit, board_block_num, BOARD_BIT); - compress_32b(c_board_p, flag_bit, board_block_type, BOARD_BIT); - } + compress_32b(c_board_p, flag_bit, board_block_num, BOARD_BIT); + compress_32b(c_board_p, flag_bit, board_block_type, BOARD_BIT); if (c_board_p - compress_board >= 200) { diff --git a/platform/window/source/network/window_network.cpp b/platform/window/source/network/window_network.cpp index d26a9376..a610f4bc 100644 --- a/platform/window/source/network/window_network.cpp +++ b/platform/window/source/network/window_network.cpp @@ -144,10 +144,8 @@ uint32_t WindowNetwork::serialize(uint8_t* buf, const Packet& pkt) compress_32b(n_c_board_p, flag_bit, pkt.board[i][j], BOARD_BIT); } } - if (board_block_num > 1) { - compress_32b(c_board_p, flag_bit, board_block_num, BOARD_BIT); - compress_32b(c_board_p, flag_bit, board_block_type, BOARD_BIT); - } + compress_32b(c_board_p, flag_bit, board_block_num, BOARD_BIT); + compress_32b(c_board_p, flag_bit, board_block_type, BOARD_BIT); if (c_board_p - compress_board >= 200) { compress_32b(p, flag_bit, 0, BOARD_BIT);