From f9d923101a53580e8a58d2a1523e11c09bce3ec4 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Wed, 10 Sep 2025 00:16:24 +0300 Subject: [PATCH] replace http-callbacks with events_queue entries --- res/scripts/classes.lua | 49 +++ src/logic/scripting/lua/libs/libnetwork.cpp | 346 +++++++++++--------- 2 files changed, 239 insertions(+), 156 deletions(-) diff --git a/res/scripts/classes.lua b/res/scripts/classes.lua index e63d5a5a..c50443f8 100644 --- a/res/scripts/classes.lua +++ b/res/scripts/classes.lua @@ -72,6 +72,38 @@ local _tcp_client_callbacks = {} local _udp_server_callbacks = {} local _udp_client_datagram_callbacks = {} local _udp_client_open_callbacks = {} +local _http_response_callbacks = {} +local _http_error_callbacks = {} + +network.get = function(url, callback, errorCallback, headers) + local id = network.__get(url, headers) + if callback then + _http_response_callbacks[id] = callback + end + if errorCallback then + _http_error_callbacks[id] = errorCallback + end +end + +network.get_binary = function(url, callback, errorCallback, headers) + local id = network.__get_binary(url, headers) + if callback then + _http_response_callbacks[id] = callback + end + if errorCallback then + _http_error_callbacks[id] = errorCallback + end +end + +network.post = function(url, data, callback, errorCallback, headers) + local id = network.__post(url, data, headers) + if callback then + _http_response_callbacks[id] = callback + end + if errorCallback then + _http_error_callbacks[id] = errorCallback + end +end network.tcp_open = function (port, handler) local socket = setmetatable({id=network.__open_tcp(port)}, ServerSocket) @@ -133,6 +165,7 @@ network.__process_events = function() local CLIENT_CONNECTED = 1 local CONNECTED_TO_SERVER = 2 local DATAGRAM = 3 + local RESPONSE = 4 local ON_SERVER = 1 local ON_CLIENT = 2 @@ -158,6 +191,22 @@ network.__process_events = function() elseif side == ON_SERVER then _udp_server_callbacks[sid](addr, port, data) end + elseif etype == RESPONSE then + if event[2] / 100 == 2 then + local callback = _http_response_callbacks[event[3]] + _http_response_callbacks[event[3]] = nil + _http_error_callbacks[event[3]] = nil + if callback then + callback(event[4]) + end + else + local callback = _http_error_callbacks[event[3]] + _http_response_callbacks[event[3]] = nil + _http_error_callbacks[event[3]] = nil + if callback then + callback(event[2]) + end + end end -- remove dead servers diff --git a/src/logic/scripting/lua/libs/libnetwork.cpp b/src/logic/scripting/lua/libs/libnetwork.cpp index 18d26644..a4cc88ab 100644 --- a/src/logic/scripting/lua/libs/libnetwork.cpp +++ b/src/logic/scripting/lua/libs/libnetwork.cpp @@ -3,8 +3,64 @@ #include "engine/Engine.hpp" #include "network/Network.hpp" +#include + using namespace scripting; +enum NetworkEventType { + CLIENT_CONNECTED = 1, + CONNECTED_TO_SERVER, + DATAGRAM, + RESPONSE, +}; + +struct ConnectionEventDto { + u64id_t server; + u64id_t client; +}; + +struct ResponseEventDto { + int status; + bool binary; + int requestId; + std::vector bytes; +}; + +enum NetworkDatagramSide { + ON_SERVER = 1, + ON_CLIENT +}; + +struct NetworkDatagramEventDto { + NetworkDatagramSide side; + u64id_t server; + u64id_t client; + std::string addr; + int port; + const char* buffer; + size_t length; +}; + +struct NetworkEvent { + using Payload = std::variant< + ConnectionEventDto, + ResponseEventDto, + NetworkDatagramEventDto + >; + NetworkEventType type; + + Payload payload; + + NetworkEvent( + NetworkEventType type, + Payload payload + ) : type(type), payload(std::move(payload)) {} + + virtual ~NetworkEvent() = default; +}; + +static std::vector events_queue {}; + static std::vector read_headers(lua::State* L, int index) { std::vector headers; if (lua::istable(L, index)) { @@ -18,76 +74,50 @@ static std::vector read_headers(lua::State* L, int index) { return headers; } -static int l_get(lua::State* L, network::Network& network) { +static int request_id = 1; + +static int perform_get(lua::State* L, network::Network& network, bool binary) { std::string url(lua::require_lstring(L, 1)); + auto headers = read_headers(L, 2); - lua::pushvalue(L, 2); - auto onResponse = lua::create_lambda_nothrow(L); + int currentRequestId = request_id; - network::OnReject onReject = nullptr; - if (!lua::isnoneornil(L, 3)) { - lua::pushvalue(L, 3); - auto callback = lua::create_lambda_nothrow(L); - onReject = [callback](int code) { - callback({code}); - }; - } + network.get(url, [currentRequestId, binary](std::vector bytes) { + events_queue.push_back(NetworkEvent( + RESPONSE, + ResponseEventDto { + 200, + binary, + currentRequestId, + std::move(bytes) + } + )); + }, [currentRequestId](int code) { + events_queue.push_back(NetworkEvent( + RESPONSE, + ResponseEventDto { + code, + false, + currentRequestId, + {} + } + )); + }, std::move(headers)); + return lua::pushinteger(L, request_id++); +} - auto headers = read_headers(L, 4); - - network.get(url, [onResponse](std::vector bytes) { - engine->postRunnable([=]() { - onResponse({std::string(bytes.data(), bytes.size())}); - }); - }, std::move(onReject), std::move(headers)); - return 0; +static int l_get(lua::State* L, network::Network& network) { + return perform_get(L, network, false); } static int l_get_binary(lua::State* L, network::Network& network) { - std::string url(lua::require_lstring(L, 1)); - - lua::pushvalue(L, 2); - auto onResponse = lua::create_lambda_nothrow(L); - - network::OnReject onReject = nullptr; - if (!lua::isnoneornil(L, 3)) { - lua::pushvalue(L, 3); - auto callback = lua::create_lambda_nothrow(L); - onReject = [callback](int code) { - callback({code}); - }; - } - - auto headers = read_headers(L, 4); - - network.get(url, [onResponse](std::vector bytes) { - auto buffer = std::make_shared>( - reinterpret_cast(bytes.data()), bytes.size() - ); - engine->postRunnable([=]() { - onResponse({buffer}); - }); - }, std::move(onReject), std::move(headers)); - - return 0; + return perform_get(L, network, true); } static int l_post(lua::State* L, network::Network& network) { std::string url(lua::require_lstring(L, 1)); auto data = lua::tovalue(L, 2); - lua::pushvalue(L, 3); - auto onResponse = lua::create_lambda_nothrow(L); - - network::OnReject onReject = nullptr; - if (!lua::isnoneornil(L, 4)) { - lua::pushvalue(L, 4); - auto callback = lua::create_lambda_nothrow(L); - onReject = [callback](int code) { - callback({code}); - }; - } - std::string string; if (data.isString()) { string = data.asString(); @@ -95,16 +125,32 @@ static int l_post(lua::State* L, network::Network& network) { string = json::stringify(data, false); } - auto headers = read_headers(L, 5); + auto headers = read_headers(L, 3); + int currentRequestId = request_id; - engine->getNetwork().post(url, string, [onResponse](std::vector bytes) { - auto buffer = std::make_shared>( - reinterpret_cast(bytes.data()), bytes.size() - ); - engine->postRunnable([=]() { - onResponse({std::string(bytes.data(), bytes.size())}); - }); - }, std::move(onReject), std::move(headers)); + engine->getNetwork().post( + url, + string, + [currentRequestId](std::vector bytes) { + auto buffer = std::make_shared>( + reinterpret_cast(bytes.data()), bytes.size() + ); + events_queue.push_back(NetworkEvent( + RESPONSE, + ResponseEventDto { + 200, + false, + currentRequestId, + std::vector(buffer->begin(), buffer->end())} + )); + }, + [currentRequestId](int code) { + events_queue.push_back(NetworkEvent( + RESPONSE, ResponseEventDto {code, false, currentRequestId, {}} + )); + }, + std::move(headers) + ); return 0; } @@ -230,69 +276,14 @@ static int l_available(lua::State* L, network::Network& network) { return 0; } -enum NetworkEventType { - CLIENT_CONNECTED = 1, - CONNECTED_TO_SERVER, - DATAGRAM -}; - -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 { - ON_SERVER = 1, - ON_CLIENT -}; - -struct NetworkDatagramEvent : NetworkEvent { - NetworkDatagramSide side; - std::string addr; - int port; - const char* buffer; - size_t length; - - NetworkDatagramEvent( - NetworkEventType datagram, - u64id_t sid, - u64id_t cid, - NetworkDatagramSide side, - const std::string& addr, - 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 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(std::make_unique(CONNECTED_TO_SERVER, 0, cid)); + events_queue.push_back(NetworkEvent( + CONNECTED_TO_SERVER, + ConnectionEventDto {0, cid} + )); }); return lua::pushinteger(L, id); } @@ -300,7 +291,10 @@ 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(std::make_unique(CLIENT_CONNECTED, sid, id)); + events_queue.push_back(NetworkEvent( + CLIENT_CONNECTED, + ConnectionEventDto {sid, id} + )); }); return lua::pushinteger(L, id); } @@ -309,18 +303,22 @@ 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(std::make_unique(CONNECTED_TO_SERVER, 0, cid)); + events_queue.push_back(NetworkEvent( + CONNECTED_TO_SERVER, + ConnectionEventDto {0, cid} + )); }, [address, port]( u64id_t cid, const char* buffer, size_t length ) { - events_queue.push_back( - std::make_unique( - DATAGRAM, 0, cid, ON_CLIENT, + events_queue.push_back(NetworkEvent( + DATAGRAM, + NetworkDatagramEventDto { + ON_CLIENT, 0, cid, address, port, buffer, length - ) - ); + } + )); }); return lua::pushinteger(L, id); } @@ -334,9 +332,12 @@ static int l_open_udp(lua::State* L, network::Network& network) { const char* buffer, size_t length) { events_queue.push_back( - std::make_unique( - DATAGRAM, sid, 0, ON_SERVER, - addr, port, buffer, length + NetworkEvent( + DATAGRAM, + NetworkDatagramEventDto { + ON_SERVER, sid, 0, + addr, port, buffer, length + } ) ); }); @@ -406,33 +407,66 @@ 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++) { - const auto* datagramEvent = dynamic_cast(events_queue[i].get()); + lua::createtable(L, 7, 0); - lua::createtable(L, datagramEvent ? 7 : 3, 0); + switch (events_queue[i].type) { + case CLIENT_CONNECTED: + case CONNECTED_TO_SERVER: { + const auto& dto = std::get(events_queue[i].payload); + lua::pushinteger(L, events_queue[i].type); + lua::rawseti(L, 1); - lua::pushinteger(L, events_queue[i]->type); - lua::rawseti(L, 1); + lua::pushinteger(L, dto.server); + lua::rawseti(L, 2); - lua::pushinteger(L, events_queue[i]->server); - lua::rawseti(L, 2); + lua::pushinteger(L, dto.client); + lua::rawseti(L, 3); + break; + } + case DATAGRAM: { + const auto& dto = std::get(events_queue[i].payload); + lua::pushinteger(L, events_queue[i].type); + lua::rawseti(L, 1); - lua::pushinteger(L, events_queue[i]->client); - lua::rawseti(L, 3); + lua::pushinteger(L, dto.server); + lua::rawseti(L, 2); - if (datagramEvent) { - lua::pushstring(L, datagramEvent->addr); - lua::rawseti(L, 4); + lua::pushinteger(L, dto.client); + lua::rawseti(L, 3); - lua::pushinteger(L, datagramEvent->port); - lua::rawseti(L, 5); + lua::pushstring(L, dto.addr); + lua::rawseti(L, 4); - lua::pushinteger(L, datagramEvent->side); - lua::rawseti(L, 6); + lua::pushinteger(L, dto.port); + lua::rawseti(L, 5); - lua::create_bytearray(L, datagramEvent->buffer, datagramEvent->length); - lua::rawseti(L, 7); + lua::pushinteger(L, dto.side); + lua::rawseti(L, 6); + + lua::create_bytearray(L, dto.buffer, dto.length); + lua::rawseti(L, 7); + break; + } + case RESPONSE: { + const auto& dto = std::get(events_queue[i].payload); + lua::pushinteger(L, events_queue[i].type); + lua::rawseti(L, 1); + + lua::pushinteger(L, dto.status); + lua::rawseti(L, 2); + + lua::pushinteger(L, dto.requestId); + lua::rawseti(L, 3); + + if (dto.binary) { + lua::create_bytearray(L, dto.bytes.data(), dto.bytes.size()); + } else { + lua::pushlstring(L, std::string_view(dto.bytes.data(), dto.bytes.size())); + } + lua::rawseti(L, 4); + break; + } } - lua::rawseti(L, i + 1); } events_queue.clear(); @@ -457,9 +491,9 @@ int wrap(lua_State* L) { } const luaL_Reg networklib[] = { - {"get", wrap}, - {"get_binary", wrap}, - {"post", wrap}, + {"__get", wrap}, + {"__get_binary", wrap}, + {"__post", wrap}, {"get_total_upload", wrap}, {"get_total_download", wrap}, {"__pull_events", wrap},