#include #include namespace blitz { namespace network { EnetServer::EnetServer(std::uint16_t a_Port) : m_Running(true) { m_Running = m_Host.Create(Nz::NetProtocol::Any, a_Port, 80); if (m_Running) { m_Host.AllowsIncomingConnections(true); m_Thread = std::jthread(&EnetServer::WorkerThread, this); } } void EnetServer::WorkerThread() { while (m_Running) { Update(); } } EnetServer::~EnetServer() { if (m_Running) Destroy(); } void EnetServer::Update() { Nz::ENetEvent event; int service = m_Host.Service(&event, 5); if (service > 0) { do { switch (event.type) { case Nz::ENetEventType::Disconnect: { EnetConnection* connection = GetConnection(event.peer->GetPeerId()); if (!connection) break; OnClientDisconnect(*connection); RemoveConnection(connection->GetPeerId()); break; } case Nz::ENetEventType::DisconnectTimeout: { EnetConnection* connection = GetConnection(event.peer->GetPeerId()); if (!connection) break; OnClientDisconnectTimeout(*connection); RemoveConnection(connection->GetPeerId()); break; } case Nz::ENetEventType::IncomingConnect: { Nz::ENetPeer* peer = event.peer; auto con = std::make_unique(peer); m_Connections.insert({peer->GetPeerId(), std::move(con)}); OnClientConnect(*GetConnection(peer->GetPeerId())); break; } case Nz::ENetEventType::Receive: { EnetConnection* connection = GetConnection(event.peer->GetPeerId()); if (!connection) break; connection->Recieve(event.packet.m_packet->data); break; } case Nz::ENetEventType::OutgoingConnect: case Nz::ENetEventType::None: break; } } while (m_Host.CheckEvents(&event)); } else if (service < 0) { m_Running = false; } } EnetConnection* EnetServer::GetConnection(std::uint16_t a_PeerId) { auto it = m_Connections.find(a_PeerId); if (it == m_Connections.end()) return nullptr; return it->second.get(); } void EnetServer::CloseConnection(std::uint16_t a_PeerId) { auto connection = GetConnection(a_PeerId); if (!connection) return; connection->m_Peer->DisconnectNow(0); OnClientDisconnect(*connection); RemoveConnection(a_PeerId); } void EnetServer::RemoveConnection(std::uint16_t a_PeerId) { m_Connections.erase(a_PeerId); } void EnetServer::Destroy() { m_Running = false; m_Thread.request_stop(); m_Host.Destroy(); } bool EnetServer::IsClosed() const { return !m_Running; } } // namespace network } // namespace blitz