From 6b4140f530af5e46ce907e73ef98275847ffb8c7 Mon Sep 17 00:00:00 2001 From: Onran0 Date: Wed, 10 Sep 2025 04:36:21 +0900 Subject: [PATCH 1/2] case fix --- src/network/Network.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/network/Network.cpp b/src/network/Network.cpp index b0482258..fe0eb28d 100644 --- a/src/network/Network.cpp +++ b/src/network/Network.cpp @@ -642,19 +642,19 @@ public: ) { SOCKET descriptor = socket(AF_INET, SOCK_DGRAM, 0); if (descriptor == -1) { - throw std::runtime_error("could not create UDP socket"); + throw std::runtime_error("could not create udp socket"); } sockaddr_in serverAddr{}; serverAddr.sin_family = AF_INET; if (inet_pton(AF_INET, address.c_str(), &serverAddr.sin_addr) <= 0) { closesocket(descriptor); - throw std::runtime_error("invalid UDP address: " + address); + throw std::runtime_error("invalid udp address: " + address); } serverAddr.sin_port = htons(port); if (::connect(descriptor, (sockaddr*)&serverAddr, sizeof(serverAddr)) < 0) { - auto err = handle_socket_error("UDP connect failed"); + auto err = handle_socket_error("udp connect failed"); closesocket(descriptor); throw err; } @@ -810,7 +810,7 @@ public: u64id_t id, Network* network, int port, const ServerDatagramCallback& handler ) { SOCKET descriptor = socket(AF_INET, SOCK_DGRAM, 0); - if (descriptor == -1) throw std::runtime_error("Could not create UDP socket"); + if (descriptor == -1) throw std::runtime_error("could not create udp socket"); sockaddr_in address{}; address.sin_family = AF_INET; @@ -819,7 +819,7 @@ public: if (bind(descriptor, (sockaddr*)&address, sizeof(address)) < 0) { closesocket(descriptor); - throw std::runtime_error("Could not bind UDP port " + std::to_string(port)); + throw std::runtime_error("could not bind udp port " + std::to_string(port)); } auto server = std::make_shared(id, network, descriptor, port); From ba8d85c00de688c2c408f7e558fbbae4e916acc7 Mon Sep 17 00:00:00 2001 From: Onran0 Date: Wed, 10 Sep 2025 05:50:11 +0900 Subject: [PATCH 2/2] fixes: implemented buffer copying; fixed access race (now the code is thread-safe) --- src/logic/scripting/lua/libs/libnetwork.cpp | 50 ++++++++++++++------- 1 file changed, 33 insertions(+), 17 deletions(-) diff --git a/src/logic/scripting/lua/libs/libnetwork.cpp b/src/logic/scripting/lua/libs/libnetwork.cpp index 18d26644..4a8446c0 100644 --- a/src/logic/scripting/lua/libs/libnetwork.cpp +++ b/src/logic/scripting/lua/libs/libnetwork.cpp @@ -1,3 +1,5 @@ +#include + #include "api_lua.hpp" #include "coders/json.hpp" #include "engine/Engine.hpp" @@ -263,8 +265,7 @@ struct NetworkDatagramEvent : NetworkEvent { NetworkDatagramSide side; std::string addr; int port; - const char* buffer; - size_t length; + std::vector buffer; NetworkDatagramEvent( NetworkEventType datagram, @@ -273,25 +274,25 @@ struct NetworkDatagramEvent : NetworkEvent { NetworkDatagramSide side, const std::string& addr, int port, - const char* data, - size_t length + std::vector buffer ) : NetworkEvent(DATAGRAM, sid, cid) { this->side = side; this->addr = addr; this->port = port; - buffer = data; - - this->length = length; + this->buffer = std::move(buffer); } }; static std::vector> events_queue {}; +static std::mutex events_queue_mutex; static int l_connect_tcp(lua::State* L, network::Network& network) { std::string address = lua::require_string(L, 1); int port = lua::tointeger(L, 2); u64id_t id = network.connectTcp(address, port, [](u64id_t cid) { + std::lock_guard lock(events_queue_mutex); + events_queue.push_back(std::make_unique(CONNECTED_TO_SERVER, 0, cid)); }); return lua::pushinteger(L, id); @@ -300,6 +301,8 @@ static int l_connect_tcp(lua::State* L, network::Network& network) { static int l_open_tcp(lua::State* L, network::Network& network) { int port = lua::tointeger(L, 1); u64id_t id = network.openTcpServer(port, [](u64id_t sid, u64id_t id) { + std::lock_guard lock(events_queue_mutex); + events_queue.push_back(std::make_unique(CLIENT_CONNECTED, sid, id)); }); return lua::pushinteger(L, id); @@ -309,16 +312,20 @@ static int l_connect_udp(lua::State* L, network::Network& network) { std::string address = lua::require_string(L, 1); int port = lua::tointeger(L, 2); u64id_t id = network.connectUdp(address, port, [](u64id_t cid) { + std::lock_guard lock(events_queue_mutex); + events_queue.push_back(std::make_unique(CONNECTED_TO_SERVER, 0, cid)); }, [address, port]( u64id_t cid, const char* buffer, size_t length ) { + std::lock_guard lock(events_queue_mutex); + events_queue.push_back( std::make_unique( DATAGRAM, 0, cid, ON_CLIENT, - address, port, buffer, length + address, port, std::vector(buffer, buffer + length) ) ); }); @@ -333,10 +340,12 @@ static int l_open_udp(lua::State* L, network::Network& network) { int port, const char* buffer, size_t length) { + std::lock_guard lock(events_queue_mutex); + events_queue.push_back( std::make_unique( DATAGRAM, sid, 0, ON_SERVER, - addr, port, buffer, length + addr, port, std::vector(buffer, buffer + length) ) ); }); @@ -403,20 +412,27 @@ static int l_get_total_download(lua::State* L, network::Network& network) { } static int l_pull_events(lua::State* L, network::Network& network) { - lua::createtable(L, events_queue.size(), 0); + std::vector> local_queue; - for (size_t i = 0; i < events_queue.size(); i++) { - const auto* datagramEvent = dynamic_cast(events_queue[i].get()); + { + std::lock_guard lock(events_queue_mutex); + local_queue.swap(events_queue); + } + + lua::createtable(L, local_queue.size(), 0); + + for (size_t i = 0; i < local_queue.size(); i++) { + const auto* datagramEvent = dynamic_cast(local_queue[i].get()); lua::createtable(L, datagramEvent ? 7 : 3, 0); - lua::pushinteger(L, events_queue[i]->type); + lua::pushinteger(L, local_queue[i]->type); lua::rawseti(L, 1); - lua::pushinteger(L, events_queue[i]->server); + lua::pushinteger(L, local_queue[i]->server); lua::rawseti(L, 2); - lua::pushinteger(L, events_queue[i]->client); + lua::pushinteger(L, local_queue[i]->client); lua::rawseti(L, 3); if (datagramEvent) { @@ -429,13 +445,13 @@ static int l_pull_events(lua::State* L, network::Network& network) { lua::pushinteger(L, datagramEvent->side); lua::rawseti(L, 6); - lua::create_bytearray(L, datagramEvent->buffer, datagramEvent->length); + lua::create_bytearray(L, datagramEvent->buffer.data(), datagramEvent->buffer.size()); lua::rawseti(L, 7); } lua::rawseti(L, i + 1); } - events_queue.clear(); + return 1; }