VoxelEngine/src/network/Network.cpp
2025-11-15 12:46:36 +03:00

193 lines
5.0 KiB
C++

#include "Network.hpp"
#include <stdexcept>
#include <limits>
#include <queue>
#include <thread>
#include "debug/Logger.hpp"
#include "util/stringutil.hpp"
using namespace network;
static debug::Logger logger("network");
namespace network {
std::unique_ptr<Requests> create_curl_requests();
std::shared_ptr<TcpConnection> connect_tcp(
const std::string& address,
int port,
runnable callback,
stringconsumer errorCallback
);
std::shared_ptr<TcpServer> open_tcp_server(
u64id_t id, Network* network, int port, ConnectCallback handler
);
std::shared_ptr<UdpConnection> connect_udp(
u64id_t id,
const std::string& address,
int port,
ClientDatagramCallback handler,
runnable callback
);
std::shared_ptr<UdpServer> open_udp_server(
u64id_t id,
Network* network,
int port,
const ServerDatagramCallback& handler
);
}
Network::Network(std::unique_ptr<Requests> requests)
: requests(std::move(requests)) {
}
Network::~Network() = default;
void Network::get(
const std::string& url,
OnResponse onResponse,
OnReject onReject,
std::vector<std::string> headers,
long maxSize
) {
requests->get(url, onResponse, onReject, std::move(headers), maxSize);
}
void Network::post(
const std::string& url,
const std::string& fieldsData,
OnResponse onResponse,
OnReject onReject,
std::vector<std::string> headers,
long maxSize
) {
requests->post(
url, fieldsData, onResponse, onReject, std::move(headers), maxSize
);
}
Connection* Network::getConnection(u64id_t id, bool includePrivate) {
std::lock_guard lock(connectionsMutex);
const auto& found = connections.find(id);
if (found == connections.end() || (!includePrivate && found->second->isPrivate())) {
return nullptr;
}
return found->second.get();
}
Server* Network::getServer(u64id_t id, bool includePrivate) const {
const auto& found = servers.find(id);
if (found == servers.end() || (!includePrivate && found->second->isPrivate())) {
return nullptr;
}
return found->second.get();
}
u64id_t Network::connectTcp(
const std::string& address,
int port,
consumer<u64id_t> callback,
ConnectErrorCallback errorCallback
) {
std::lock_guard lock(connectionsMutex);
u64id_t id = nextConnection++;
auto socket = connect_tcp(address, port, [id, callback]() {
callback(id);
}, [id, errorCallback](auto errorMessage) {
errorCallback(id, errorMessage);
});
connections[id] = std::move(socket);
return id;
}
u64id_t Network::openTcpServer(int port, ConnectCallback handler) {
u64id_t id = nextServer++;
auto server = open_tcp_server(id, this, port, handler);
servers[id] = std::move(server);
return id;
}
u64id_t Network::connectUdp(
const std::string& address,
int port,
const consumer<u64id_t>& callback,
ClientDatagramCallback handler
) {
std::lock_guard lock(connectionsMutex);
u64id_t id = nextConnection++;
auto socket = connect_udp(id, address, port, std::move(handler), [id, callback]() {
callback(id);
});
connections[id] = std::move(socket);
return id;
}
u64id_t Network::openUdpServer(int port, const ServerDatagramCallback& handler) {
u64id_t id = nextServer++;
auto server = open_udp_server(id, this, port, handler);
servers[id] = std::move(server);
return id;
}
u64id_t Network::addConnection(const std::shared_ptr<Connection>& socket) {
std::lock_guard lock(connectionsMutex);
u64id_t id = nextConnection++;
connections[id] = std::move(socket);
return id;
}
size_t Network::getTotalUpload() const {
return requests->getTotalUpload() + totalUpload;
}
size_t Network::getTotalDownload() const {
return requests->getTotalDownload() + totalDownload;
}
void Network::update() {
requests->update();
{
std::lock_guard lock(connectionsMutex);
auto socketiter = connections.begin();
while (socketiter != connections.end()) {
auto socket = socketiter->second.get();
totalDownload += socket->pullDownload();
totalUpload += socket->pullUpload();
if (
( socket->getTransportType() == TransportType::UDP ||
dynamic_cast<TcpConnection*>(socket)->available() == 0
) &&
socket->getState() == ConnectionState::CLOSED) {
socketiter = connections.erase(socketiter);
continue;
}
++socketiter;
}
}
auto serveriter = servers.begin();
while (serveriter != servers.end()) {
auto server = serveriter->second.get();
if (!server->isOpen()) {
serveriter = servers.erase(serveriter);
continue;
}
server->update();
++serveriter;
}
}
std::unique_ptr<Network> Network::create(const NetworkSettings& settings) {
return std::make_unique<Network>(network::create_curl_requests());
}