From 1bea391f1d7fb71ddc6095d064a013cd1cdae7d5 Mon Sep 17 00:00:00 2001 From: Onran0 Date: Sun, 24 Aug 2025 08:31:13 +0900 Subject: [PATCH] fixes --- doc/ru/scripting/builtins/libnetwork.md | 2 +- res/scripts/classes.lua | 8 ++- src/logic/scripting/lua/libs/libnetwork.cpp | 73 ++++++++++++++------- src/network/Network.cpp | 25 +++---- 4 files changed, 64 insertions(+), 44 deletions(-) diff --git a/doc/ru/scripting/builtins/libnetwork.md b/doc/ru/scripting/builtins/libnetwork.md index 0e9a02b1..30bc4135 100644 --- a/doc/ru/scripting/builtins/libnetwork.md +++ b/doc/ru/scripting/builtins/libnetwork.md @@ -135,7 +135,7 @@ network.udp_open( port: int, -- Функция, вызываемая при получении датаграмы -- В параметры передаётся адрес и порт отправителя, а также сами данные - datagramHandler: function(address: str, port: int, data: Bytearray) + datagramHandler: function(server: DatagramServerSocket, address: str, port: int, data: Bytearray) ) --> DatagramServerSocket ``` diff --git a/res/scripts/classes.lua b/res/scripts/classes.lua index 30354050..aadbc308 100644 --- a/res/scripts/classes.lua +++ b/res/scripts/classes.lua @@ -90,19 +90,21 @@ network.tcp_connect = function(address, port, callback) end network.udp_open = function (port, datagramHandler) - if type(datagramHandler) ~= 'func' then + if type(datagramHandler) ~= 'function' then error "udp server cannot be opened without datagram handler" end local socket = setmetatable({id=network.__open_udp(port)}, DatagramServerSocket) - _udp_server_callbacks[socket.id] = datagramHandler + _udp_server_callbacks[socket.id] = function(...) + datagramHandler(socket, ...) + end return socket end network.udp_connect = function (address, port, datagramHandler, openCallback) - if type(datagramHandler) ~= 'func' then + if type(datagramHandler) ~= 'function' then error "udp client socket cannot be opened without datagram handler" end diff --git a/src/logic/scripting/lua/libs/libnetwork.cpp b/src/logic/scripting/lua/libs/libnetwork.cpp index dc2eff65..bfa67af6 100644 --- a/src/logic/scripting/lua/libs/libnetwork.cpp +++ b/src/logic/scripting/lua/libs/libnetwork.cpp @@ -1,8 +1,9 @@ -#include "api_lua.hpp" +#include +#include "api_lua.hpp" +#include "coders/json.hpp" #include "engine/Engine.hpp" #include "network/Network.hpp" -#include "coders/json.hpp" using namespace scripting; @@ -221,6 +222,18 @@ struct NetworkEvent { NetworkEventType type; u64id_t server; u64id_t client; + + NetworkEvent( + NetworkEventType type, + u64id_t server, + u64id_t client + ) { + this->type = type; + this->server = server; + this->client = client; + } + + virtual ~NetworkEvent() = default; }; enum NetworkDatagramSide { @@ -232,10 +245,11 @@ struct NetworkDatagramEvent : NetworkEvent { NetworkDatagramSide side; std::string addr; int port; - char* buffer; + const char* buffer; size_t length; - NetworkDatagramEvent(NetworkEventType datagram, + NetworkDatagramEvent( + NetworkEventType datagram, u64id_t sid, u64id_t cid, NetworkDatagramSide side, @@ -243,16 +257,24 @@ struct NetworkDatagramEvent : NetworkEvent { int port, const char* data, size_t length - ); + ) : NetworkEvent(DATAGRAM, sid, cid) { + this->side = side; + this->addr = addr; + this->port = port; + + buffer = data; + + this->length = length; + } }; -static std::vector events_queue {}; +static std::vector> events_queue {}; 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) { - events_queue.push_back({CONNECTED_TO_SERVER, 0, cid}); + events_queue.push_back(std::make_unique(CONNECTED_TO_SERVER, 0, cid)); }); return lua::pushinteger(L, id); } @@ -260,7 +282,7 @@ 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) { - events_queue.push_back({CLIENT_CONNECTED, sid, id}); + events_queue.push_back(std::make_unique(CLIENT_CONNECTED, sid, id)); }); return lua::pushinteger(L, id); } @@ -269,17 +291,17 @@ 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) { - events_queue.push_back({CONNECTED_TO_SERVER, 0, cid}); + events_queue.push_back(std::make_unique(CONNECTED_TO_SERVER, 0, cid)); }, [address, port]( u64id_t cid, const char* buffer, size_t length ) { events_queue.push_back( - NetworkDatagramEvent{ + std::make_unique( DATAGRAM, 0, cid, ON_CLIENT, address, port, buffer, length - } + ) ); }); return lua::pushinteger(L, id); @@ -294,10 +316,10 @@ static int l_open_udp(lua::State* L, network::Network& network) { const char* buffer, size_t length) { events_queue.push_back( - NetworkDatagramEvent{ + std::make_unique( DATAGRAM, sid, 0, ON_SERVER, addr, port, buffer, length - } + ) ); }); return lua::pushinteger(L, id); @@ -364,31 +386,32 @@ 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); - for (size_t i = 0; i < events_queue.size(); i++) { - lua::createtable(L, 3, 0); - lua::pushinteger(L, events_queue[i].type); + for (size_t i = 0; i < events_queue.size(); i++) { + const auto* datagramEvent = dynamic_cast(events_queue[i].get()); + + lua::createtable(L, datagramEvent ? 7 : 3, 0); + + lua::pushinteger(L, events_queue[i]->type); lua::rawseti(L, 1); - lua::pushinteger(L, events_queue[i].server); + lua::pushinteger(L, events_queue[i]->server); lua::rawseti(L, 2); - lua::pushinteger(L, events_queue[i].client); + lua::pushinteger(L, events_queue[i]->client); lua::rawseti(L, 3); - if (typeid(events_queue[i]) == typeid(NetworkDatagramEvent)) { - const NetworkDatagramEvent& de = (NetworkDatagramEvent&) events_queue[i]; - - lua::pushstring(L, de.addr); + if (datagramEvent) { + lua::pushstring(L, datagramEvent->addr); lua::rawseti(L, 4); - lua::pushinteger(L, de.port); + lua::pushinteger(L, datagramEvent->port); lua::rawseti(L, 5); - lua::pushinteger(L, de.side); + lua::pushinteger(L, datagramEvent->side); lua::rawseti(L, 6); - lua::pushvalue(L, lua::create_bytearray(L, de.buffer, de.length)); + lua::create_bytearray(L, datagramEvent->buffer, datagramEvent->length); lua::rawseti(L, 7); } diff --git a/src/network/Network.cpp b/src/network/Network.cpp index 92be35a2..234197e4 100644 --- a/src/network/Network.cpp +++ b/src/network/Network.cpp @@ -442,8 +442,6 @@ public: return to_string(addr, false); } - TransportType getTransportType() const override { return TransportType::TCP; } - static std::shared_ptr connect( const std::string& address, int port, runnable callback ) { @@ -611,7 +609,7 @@ public: : id(id), descriptor(descriptor), addr(std::move(addr)) {} ~SocketUdpConnection() override { - close(); + SocketUdpConnection::close(); } static std::shared_ptr connect( @@ -623,18 +621,17 @@ 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); - // вызов connect() на UDP сокете → ограничиваем только одним адресом if (::connect(descriptor, (sockaddr*)&serverAddr, sizeof(serverAddr)) < 0) { auto err = handle_socket_error("UDP connect failed"); closesocket(descriptor); @@ -721,10 +718,6 @@ public: [[nodiscard]] ConnectionState getState() const override { return state; } - - [[nodiscard]] TransportType getTransportType() const noexcept override { - return TransportType::UDP; - } }; class SocketUdpServer : public UdpServer { @@ -737,14 +730,16 @@ class SocketUdpServer : public UdpServer { ServerDatagramCallback callback; public: - SocketUdpServer(u64id_t id, Network* network, SOCKET descriptor, int port, ServerDatagramCallback cb) - : id(id), network(network), descriptor(descriptor), port(port), callback(std::move(cb)) {} + SocketUdpServer(u64id_t id, Network* network, SOCKET descriptor, int port) + : id(id), network(network), descriptor(descriptor), port(port) {} ~SocketUdpServer() override { SocketUdpServer::close(); } - void startListen() { + void startListen(ServerDatagramCallback handler) { + callback = std::move(handler); + thread = std::make_unique([this]() { util::Buffer buffer(16384); sockaddr_in clientAddr{}; @@ -806,8 +801,8 @@ public: throw std::runtime_error("Could not bind UDP port " + std::to_string(port)); } - auto server = std::make_shared(id, network, descriptor, port, std::move(handler)); - server->startListen(); + auto server = std::make_shared(id, network, descriptor, port); + server->startListen(std::move(handler)); return server; } };