fully implement KeepAlive behavior
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <Nazara/Network/ENetHost.hpp>
|
#include <Nazara/Network/ENetHost.hpp>
|
||||||
#include <blitz/network/EnetConnexion.h>
|
#include <blitz/network/EnetConnection.h>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
namespace blitz {
|
namespace blitz {
|
||||||
@@ -18,12 +18,12 @@ class EnetClient : private NonCopyable {
|
|||||||
NazaraSignal(OnDisconnect);
|
NazaraSignal(OnDisconnect);
|
||||||
NazaraSignal(OnDisconnectTimeout);
|
NazaraSignal(OnDisconnectTimeout);
|
||||||
|
|
||||||
const EnetConnexion& GetConnexion() const {
|
EnetConnection& GetConnection() {
|
||||||
return m_Connexion;
|
return m_Connection;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
EnetConnexion m_Connexion;
|
EnetConnection m_Connection;
|
||||||
Nz::ENetHost m_Host;
|
Nz::ENetHost m_Host;
|
||||||
Nz::ENetPeer* m_Peer;
|
Nz::ENetPeer* m_Peer;
|
||||||
std::thread m_Thread;
|
std::thread m_Thread;
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \file EnetConnexion.h
|
* \file EnetConnection.h
|
||||||
* \brief File containing the blitz::network::EnetConnexion class
|
* \brief File containing the blitz::network::EnetConnection class
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <Nazara/Core/ByteArray.hpp>
|
#include <Nazara/Core/ByteArray.hpp>
|
||||||
@@ -35,12 +35,14 @@ class EnetServer;
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
class EnetConnexion : private NonCopyable {
|
class EnetConnection : private NonCopyable {
|
||||||
public:
|
public:
|
||||||
EnetConnexion(Nz::ENetPeer* a_Peer = nullptr);
|
EnetConnection(Nz::ENetPeer* a_Peer = nullptr);
|
||||||
|
|
||||||
bool IsConnected() const;
|
bool IsConnected() const;
|
||||||
|
|
||||||
|
std::uint16_t GetPeerId() const;
|
||||||
|
|
||||||
DeclareAllPacket();
|
DeclareAllPacket();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include <Nazara/Core/ThreadExt.hpp>
|
#include <Nazara/Core/ThreadExt.hpp>
|
||||||
#include <Nazara/Network/ENetHost.hpp>
|
#include <Nazara/Network/ENetHost.hpp>
|
||||||
#include <blitz/network/EnetConnexion.h>
|
#include <blitz/network/EnetConnection.h>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
@@ -17,24 +17,24 @@ class EnetServer : private NonCopyable {
|
|||||||
|
|
||||||
void Destroy();
|
void Destroy();
|
||||||
|
|
||||||
// void BroadcastPacket(const protocol::Packet& a_Packet, Nz::ENetPacketFlags a_Flags);
|
void CloseConnection(std::uint16_t a_PeerId);
|
||||||
|
|
||||||
EnetConnexion* GetConnexion(std::uint16_t a_PeerId);
|
EnetConnection* GetConnection(std::uint16_t a_PeerId);
|
||||||
|
|
||||||
NazaraSignal(OnClientConnect, EnetConnexion& /*a_Peer*/);
|
NazaraSignal(OnClientConnect, EnetConnection& /*a_Peer*/);
|
||||||
NazaraSignal(OnClientDisconnect, EnetConnexion& /*a_Peer*/);
|
NazaraSignal(OnClientDisconnect, EnetConnection& /*a_Peer*/);
|
||||||
NazaraSignal(OnClientDisconnectTimeout, EnetConnexion& /*a_Peer*/);
|
NazaraSignal(OnClientDisconnectTimeout, EnetConnection& /*a_Peer*/);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void Update();
|
void Update();
|
||||||
void WorkerThread();
|
void WorkerThread();
|
||||||
|
|
||||||
void RemoveConnexion(std::uint16_t a_PeerId);
|
void RemoveConnection(std::uint16_t a_PeerId);
|
||||||
|
|
||||||
Nz::ENetHost m_Host;
|
Nz::ENetHost m_Host;
|
||||||
bool m_Running;
|
bool m_Running;
|
||||||
std::thread m_Thread;
|
std::thread m_Thread;
|
||||||
std::map<std::uint16_t, std::unique_ptr<EnetConnexion>> m_Connexion;
|
std::map<std::uint16_t, std::unique_ptr<EnetConnection>> m_Connections;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace network
|
} // namespace network
|
||||||
|
|||||||
23
include/blitz/protocol/PacketHandler.h
Normal file
23
include/blitz/protocol/PacketHandler.h
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <Nazara/Core/EnttWorld.hpp>
|
||||||
|
#include <blitz/network/EnetConnection.h>
|
||||||
|
|
||||||
|
namespace blitz {
|
||||||
|
|
||||||
|
using EnttWorld = std::atomic<std::shared_ptr<Nz::EnttWorld>>;
|
||||||
|
|
||||||
|
namespace protocol {
|
||||||
|
|
||||||
|
class PacketHandler : private NonCopyable {
|
||||||
|
public:
|
||||||
|
PacketHandler(network::EnetConnection& a_Connection, EnttWorld& a_World);
|
||||||
|
virtual ~PacketHandler();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
network::EnetConnection& m_Connection;
|
||||||
|
EnttWorld& m_World;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace protocol
|
||||||
|
} // namespace blitz
|
||||||
31
include/client/Client.h
Normal file
31
include/client/Client.h
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <Nazara/Core/EnttWorld.hpp>
|
||||||
|
#include <atomic>
|
||||||
|
#include <blitz/network/EnetClient.h>
|
||||||
|
#include <blitz/protocol/PacketHandler.h>
|
||||||
|
|
||||||
|
namespace blitz {
|
||||||
|
namespace client {
|
||||||
|
|
||||||
|
class Client : private NonCopyable {
|
||||||
|
public:
|
||||||
|
Client();
|
||||||
|
~Client();
|
||||||
|
|
||||||
|
void Connect(const Nz::IpAddress& a_Ip);
|
||||||
|
void Disconnect();
|
||||||
|
|
||||||
|
bool IsConnected();
|
||||||
|
|
||||||
|
private:
|
||||||
|
EnttWorld m_World;
|
||||||
|
std::unique_ptr<network::EnetClient> m_NetworkClient;
|
||||||
|
std::vector<std::unique_ptr<protocol::PacketHandler>> m_Handlers;
|
||||||
|
|
||||||
|
void BindHandlers();
|
||||||
|
void UnbindHandlers();
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace client
|
||||||
|
} // namespace blitz
|
||||||
15
include/client/handlers/KeepAliveHandler.h
Normal file
15
include/client/handlers/KeepAliveHandler.h
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
#include <blitz/protocol/PacketHandler.h>
|
||||||
|
|
||||||
|
namespace blitz {
|
||||||
|
namespace client {
|
||||||
|
|
||||||
|
class KeepAliveHandler : public protocol::PacketHandler {
|
||||||
|
public:
|
||||||
|
KeepAliveHandler(network::EnetConnection& a_Connection, EnttWorld& a_World);
|
||||||
|
~KeepAliveHandler();
|
||||||
|
|
||||||
|
NazaraSlot(network::EnetConnection, OnKeepAlive, m_Slot);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace client
|
||||||
|
} // namespace blitz
|
||||||
37
include/server/Server.h
Normal file
37
include/server/Server.h
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <blitz/network/EnetServer.h>
|
||||||
|
#include <blitz/protocol/PacketHandler.h>
|
||||||
|
|
||||||
|
namespace blitz {
|
||||||
|
namespace server {
|
||||||
|
|
||||||
|
class Server {
|
||||||
|
public:
|
||||||
|
Server(std::uint16_t a_Port, std::shared_ptr<Nz::EnttWorld> a_World);
|
||||||
|
~Server();
|
||||||
|
|
||||||
|
network::EnetConnection* GetConnection(std::uint16_t a_PeerId);
|
||||||
|
|
||||||
|
void CloseConnection(std::uint16_t a_PeerId);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void HandleConnect(network::EnetConnection&);
|
||||||
|
void HandleDisconnect(network::EnetConnection&);
|
||||||
|
|
||||||
|
struct Session {
|
||||||
|
network::EnetConnection* m_Connection;
|
||||||
|
std::vector<std::unique_ptr<protocol::PacketHandler>> m_Handlers;
|
||||||
|
};
|
||||||
|
|
||||||
|
EnttWorld m_World;
|
||||||
|
std::map<std::uint16_t, Session> m_Sessions;
|
||||||
|
network::EnetServer m_NetworkServer;
|
||||||
|
|
||||||
|
void RegisterHandlers(Session& session);
|
||||||
|
void RegisterSystems();
|
||||||
|
void CreateEntity(network::EnetConnection&);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace server
|
||||||
|
} // namespace blitz
|
||||||
13
include/server/components/Disconnect.h
Normal file
13
include/server/components/Disconnect.h
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace blitz {
|
||||||
|
namespace server {
|
||||||
|
|
||||||
|
enum Reason { Timeout };
|
||||||
|
|
||||||
|
struct DisconnectComponent {
|
||||||
|
Reason m_Reason;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace server
|
||||||
|
} // namespace blitz
|
||||||
13
include/server/components/EnetConnection.h
Normal file
13
include/server/components/EnetConnection.h
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <blitz/network/EnetConnection.h>
|
||||||
|
|
||||||
|
namespace blitz {
|
||||||
|
namespace server {
|
||||||
|
|
||||||
|
struct EnetConnectionComponent {
|
||||||
|
network::EnetConnection* m_Connection;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace server
|
||||||
|
} // namespace blitz
|
||||||
17
include/server/components/KeepAliveSession.h
Normal file
17
include/server/components/KeepAliveSession.h
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <Nazara/Core/Time.hpp>
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
namespace blitz {
|
||||||
|
namespace server {
|
||||||
|
|
||||||
|
struct KeepAliveSessionComponent {
|
||||||
|
std::uint16_t m_PeerId;
|
||||||
|
std::uint64_t m_LastKeepAliveId;
|
||||||
|
Nz::Time m_LastTime;
|
||||||
|
bool m_RecievedResponse = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace server
|
||||||
|
} // namespace blitz
|
||||||
20
include/server/handlers/KeepAliveHandler.h
Normal file
20
include/server/handlers/KeepAliveHandler.h
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <blitz/protocol/PacketHandler.h>
|
||||||
|
|
||||||
|
namespace blitz {
|
||||||
|
namespace server {
|
||||||
|
|
||||||
|
class KeepAliveHandler : public protocol::PacketHandler {
|
||||||
|
public:
|
||||||
|
KeepAliveHandler(network::EnetConnection& a_Connection, EnttWorld& a_World);
|
||||||
|
~KeepAliveHandler();
|
||||||
|
|
||||||
|
NazaraSlot(network::EnetConnection, OnKeepAlive, m_Slot);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void Handle(std::uint16_t, const protocol::data::KeepAlive&);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace server
|
||||||
|
} // namespace blitz
|
||||||
23
include/server/systems/DisconnectSystem.h
Normal file
23
include/server/systems/DisconnectSystem.h
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <Nazara/Core/Time.hpp>
|
||||||
|
#include <entt/entity/registry.hpp>
|
||||||
|
|
||||||
|
namespace blitz {
|
||||||
|
namespace server {
|
||||||
|
|
||||||
|
class Server;
|
||||||
|
|
||||||
|
class DisconectSystem {
|
||||||
|
public:
|
||||||
|
DisconectSystem(entt::registry& a_Registry, Server& a_Server);
|
||||||
|
|
||||||
|
void Update(Nz::Time elapsedTime);
|
||||||
|
|
||||||
|
private:
|
||||||
|
entt::registry& m_Registry;
|
||||||
|
Server& m_Server;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace server
|
||||||
|
} // namespace blitz
|
||||||
20
include/server/systems/KeepAliveSystem.h
Normal file
20
include/server/systems/KeepAliveSystem.h
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <Nazara/Core/Time.hpp>
|
||||||
|
#include <entt/entity/registry.hpp>
|
||||||
|
|
||||||
|
namespace blitz {
|
||||||
|
namespace server {
|
||||||
|
|
||||||
|
class KeepAliveSystem {
|
||||||
|
public:
|
||||||
|
KeepAliveSystem(entt::registry& a_Registry);
|
||||||
|
|
||||||
|
void Update(Nz::Time elapsedTime);
|
||||||
|
|
||||||
|
private:
|
||||||
|
entt::registry& m_Registry;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace server
|
||||||
|
} // namespace blitz
|
||||||
@@ -1,18 +1,13 @@
|
|||||||
#include <blitz/network/EnetClient.h>
|
#include <blitz/network/EnetClient.h>
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
namespace blitz {
|
namespace blitz {
|
||||||
namespace network {
|
namespace network {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
EnetClient::EnetClient(const Nz::IpAddress& address) : m_Running(true) {
|
EnetClient::EnetClient(const Nz::IpAddress& address) : m_Running(true) {
|
||||||
m_Host.Create(Nz::IpAddress::LoopbackIpV4, 1);
|
m_Host.Create(Nz::IpAddress::LoopbackIpV4, 1);
|
||||||
m_Peer = m_Host.Connect(address);
|
m_Peer = m_Host.Connect(address);
|
||||||
m_Thread = std::thread(&EnetClient::WorkerThread, this);
|
m_Thread = std::thread(&EnetClient::WorkerThread, this);
|
||||||
m_Connexion.SetPeer(m_Peer);
|
m_Connection.SetPeer(m_Peer);
|
||||||
}
|
}
|
||||||
|
|
||||||
EnetClient::~EnetClient() {
|
EnetClient::~EnetClient() {
|
||||||
@@ -25,7 +20,7 @@ EnetClient::~EnetClient() {
|
|||||||
|
|
||||||
void EnetClient::Disconnect() {
|
void EnetClient::Disconnect() {
|
||||||
m_Peer->DisconnectNow(0);
|
m_Peer->DisconnectNow(0);
|
||||||
m_Connexion.SetPeer(nullptr);
|
m_Connection.SetPeer(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EnetClient::WorkerThread() {
|
void EnetClient::WorkerThread() {
|
||||||
@@ -53,7 +48,7 @@ void EnetClient::Update() {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case Nz::ENetEventType::Receive:
|
case Nz::ENetEventType::Receive:
|
||||||
m_Connexion.Recieve(event.packet.m_packet->data);
|
m_Connection.Recieve(event.packet.m_packet->data);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Nz::ENetEventType::None:
|
case Nz::ENetEventType::None:
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#include <blitz/network/EnetConnexion.h>
|
#include <blitz/network/EnetConnection.h>
|
||||||
|
|
||||||
#include <Nazara/Network/ENetPeer.hpp>
|
#include <Nazara/Network/ENetPeer.hpp>
|
||||||
#include <blitz/protocol/PacketSerializer.h>
|
#include <blitz/protocol/PacketSerializer.h>
|
||||||
@@ -11,20 +11,17 @@ namespace packets = blitz::protocol::packets;
|
|||||||
|
|
||||||
|
|
||||||
#define DeclarePacket(PacketName, ...) \
|
#define DeclarePacket(PacketName, ...) \
|
||||||
void Visit(const protocol::packets::PacketName& a_Packet) { \
|
void Visit(const protocol::packets::PacketName& a_Packet) { m_Connection.On##PacketName(a_Packet.m_Data); }
|
||||||
m_Connexion.On##PacketName(a_Packet.m_Data); \
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class PacketDispatcher : public protocol::PacketVisitor {
|
class PacketDispatcher : public protocol::PacketVisitor {
|
||||||
public:
|
public:
|
||||||
PacketDispatcher(EnetConnexion& a_Connexion) : m_Connexion(a_Connexion) {}
|
PacketDispatcher(EnetConnection& a_Connection) : m_Connection(a_Connection) {}
|
||||||
|
|
||||||
DeclareAllPacket()
|
DeclareAllPacket()
|
||||||
|
|
||||||
private:
|
private : EnetConnection& m_Connection;
|
||||||
EnetConnexion& m_Connexion;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#undef DeclarePacket
|
#undef DeclarePacket
|
||||||
@@ -33,19 +30,24 @@ class PacketDispatcher : public protocol::PacketVisitor {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
EnetConnexion::EnetConnexion(Nz::ENetPeer* a_Peer) : m_Peer(a_Peer) {}
|
EnetConnection::EnetConnection(Nz::ENetPeer* a_Peer) : m_Peer(a_Peer) {}
|
||||||
|
|
||||||
void EnetConnexion::SetPeer(Nz::ENetPeer* a_Peer) {
|
void EnetConnection::SetPeer(Nz::ENetPeer* a_Peer) {
|
||||||
m_Peer = a_Peer;
|
m_Peer = a_Peer;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EnetConnexion::IsConnected() const {
|
std::uint16_t EnetConnection::GetPeerId() const {
|
||||||
|
assert(m_Peer);
|
||||||
|
return m_Peer->GetPeerId();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EnetConnection::IsConnected() const {
|
||||||
if (!m_Peer)
|
if (!m_Peer)
|
||||||
return false;
|
return false;
|
||||||
return m_Peer->IsConnected();
|
return m_Peer->IsConnected();
|
||||||
}
|
}
|
||||||
|
|
||||||
void EnetConnexion::Recieve(Nz::ByteArray& a_Data) {
|
void EnetConnection::Recieve(Nz::ByteArray& a_Data) {
|
||||||
auto packet = protocol::PacketSerializer::Deserialize(a_Data);
|
auto packet = protocol::PacketSerializer::Deserialize(a_Data);
|
||||||
if (!packet)
|
if (!packet)
|
||||||
return;
|
return;
|
||||||
@@ -54,8 +56,8 @@ void EnetConnexion::Recieve(Nz::ByteArray& a_Data) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#define DeclarePacket(Name, NFlag, ...) \
|
#define DeclarePacket(Name, NFlag, ...) \
|
||||||
void EnetConnexion::Send##Name(const blitz::protocol::data::Name& a_##Name) const { \
|
void EnetConnection::Send##Name(const blitz::protocol::data::Name& a_##Name) const { \
|
||||||
m_Peer->Send(0, Nz::ENetPacketFlag::NFlag, protocol::PacketSerializer::Serialize(protocol::packets::Name(a_##Name))); \
|
m_Peer->Send(0, Nz::ENetPacketFlag::NFlag, protocol::PacketSerializer::Serialize(protocol::packets::Name(a_##Name))); \
|
||||||
}
|
}
|
||||||
|
|
||||||
DeclareAllPacket()
|
DeclareAllPacket()
|
||||||
@@ -29,34 +29,36 @@ void EnetServer::Update() {
|
|||||||
do {
|
do {
|
||||||
switch (event.type) {
|
switch (event.type) {
|
||||||
case Nz::ENetEventType::Disconnect: {
|
case Nz::ENetEventType::Disconnect: {
|
||||||
EnetConnexion* connexion = GetConnexion(event.peer->GetPeerId());
|
EnetConnection* connection = GetConnection(event.peer->GetPeerId());
|
||||||
if (!connexion)
|
if (!connection)
|
||||||
break;
|
break;
|
||||||
OnClientDisconnect(*connexion);
|
OnClientDisconnect(*connection);
|
||||||
|
RemoveConnection(connection->GetPeerId());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case Nz::ENetEventType::DisconnectTimeout: {
|
case Nz::ENetEventType::DisconnectTimeout: {
|
||||||
EnetConnexion* connexion = GetConnexion(event.peer->GetPeerId());
|
EnetConnection* connection = GetConnection(event.peer->GetPeerId());
|
||||||
if (!connexion)
|
if (!connection)
|
||||||
break;
|
break;
|
||||||
OnClientDisconnectTimeout(*connexion);
|
OnClientDisconnectTimeout(*connection);
|
||||||
|
RemoveConnection(connection->GetPeerId());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case Nz::ENetEventType::IncomingConnect: {
|
case Nz::ENetEventType::IncomingConnect: {
|
||||||
Nz::ENetPeer* peer = event.peer;
|
Nz::ENetPeer* peer = event.peer;
|
||||||
auto con = std::make_unique<EnetConnexion>(peer);
|
auto con = std::make_unique<EnetConnection>(peer);
|
||||||
m_Connexion.insert({peer->GetPeerId(), std::move(con)});
|
m_Connections.insert({peer->GetPeerId(), std::move(con)});
|
||||||
OnClientConnect(*GetConnexion(peer->GetPeerId()));
|
OnClientConnect(*GetConnection(peer->GetPeerId()));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case Nz::ENetEventType::Receive: {
|
case Nz::ENetEventType::Receive: {
|
||||||
EnetConnexion* connexion = GetConnexion(event.peer->GetPeerId());
|
EnetConnection* connection = GetConnection(event.peer->GetPeerId());
|
||||||
if (!connexion)
|
if (!connection)
|
||||||
break;
|
break;
|
||||||
connexion->Recieve(event.packet.m_packet->data);
|
connection->Recieve(event.packet.m_packet->data);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,21 +70,28 @@ void EnetServer::Update() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
EnetConnexion* EnetServer::GetConnexion(std::uint16_t a_PeerId) {
|
EnetConnection* EnetServer::GetConnection(std::uint16_t a_PeerId) {
|
||||||
auto it = m_Connexion.find(a_PeerId);
|
auto it = m_Connections.find(a_PeerId);
|
||||||
|
|
||||||
if (it == m_Connexion.end())
|
if (it == m_Connections.end())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
return it->second.get();
|
return it->second.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*void EnetServer::BroadcastPacket(const protocol::Packet& a_Packet, Nz::ENetPacketFlags a_Flags) {
|
void EnetServer::CloseConnection(std::uint16_t a_PeerId) {
|
||||||
m_Host.Broadcast(0, a_Flags, std::move(a_Data));
|
auto connection = GetConnection(a_PeerId);
|
||||||
}*/
|
|
||||||
|
|
||||||
void EnetServer::RemoveConnexion(std::uint16_t a_PeerId) {
|
if (!connection)
|
||||||
m_Connexion.erase(a_PeerId);
|
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() {
|
void EnetServer::Destroy() {
|
||||||
|
|||||||
12
src/blitz/protocol/PacketHandler.cpp
Normal file
12
src/blitz/protocol/PacketHandler.cpp
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
#include <blitz/protocol/PacketHandler.h>
|
||||||
|
|
||||||
|
namespace blitz {
|
||||||
|
namespace protocol {
|
||||||
|
|
||||||
|
PacketHandler::PacketHandler(network::EnetConnection& a_Connection, EnttWorld& a_World) :
|
||||||
|
m_Connection(a_Connection), m_World(a_World) {}
|
||||||
|
|
||||||
|
PacketHandler::~PacketHandler() {}
|
||||||
|
|
||||||
|
} // namespace protocol
|
||||||
|
} // namespace blitz
|
||||||
@@ -4,8 +4,6 @@
|
|||||||
#include <blitz/protocol/PacketFactory.h>
|
#include <blitz/protocol/PacketFactory.h>
|
||||||
#include <blitz/protocol/PacketVisitor.h>
|
#include <blitz/protocol/PacketVisitor.h>
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
namespace blitz {
|
namespace blitz {
|
||||||
namespace protocol {
|
namespace protocol {
|
||||||
|
|
||||||
|
|||||||
45
src/client/Client.cpp
Normal file
45
src/client/Client.cpp
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
#include <client/Client.h>
|
||||||
|
|
||||||
|
#include <client/handlers/KeepAliveHandler.h>
|
||||||
|
|
||||||
|
namespace blitz {
|
||||||
|
namespace client {
|
||||||
|
|
||||||
|
Client::Client() : m_World() {
|
||||||
|
m_World.store(std::make_shared<Nz::EnttWorld>());
|
||||||
|
}
|
||||||
|
|
||||||
|
Client::~Client() {
|
||||||
|
Disconnect();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Client::BindHandlers() {
|
||||||
|
m_Handlers.push_back(std::make_unique<KeepAliveHandler>(m_NetworkClient->GetConnection(), m_World));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Client::UnbindHandlers() {
|
||||||
|
m_Handlers.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Client::Connect(const Nz::IpAddress& a_Ip) {
|
||||||
|
m_NetworkClient = std::make_unique<network::EnetClient>(a_Ip);
|
||||||
|
BindHandlers();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Client::Disconnect() {
|
||||||
|
if (!m_NetworkClient)
|
||||||
|
return;
|
||||||
|
m_NetworkClient->Disconnect();
|
||||||
|
UnbindHandlers();
|
||||||
|
m_NetworkClient.reset(nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Client::IsConnected() {
|
||||||
|
if (!m_NetworkClient)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return m_NetworkClient->GetConnection().IsConnected();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace client
|
||||||
|
} // namespace blitz
|
||||||
15
src/client/handlers/KeepAliveHandler.cpp
Normal file
15
src/client/handlers/KeepAliveHandler.cpp
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
#include <client/handlers/KeepAliveHandler.h>
|
||||||
|
|
||||||
|
namespace blitz {
|
||||||
|
namespace client {
|
||||||
|
|
||||||
|
KeepAliveHandler::KeepAliveHandler(network::EnetConnection& a_Connection, EnttWorld& a_World) :
|
||||||
|
protocol::PacketHandler(a_Connection, a_World) {
|
||||||
|
m_Slot.Connect(m_Connection.OnKeepAlive,
|
||||||
|
[this](const blitz::protocol::data::KeepAlive& a_KeepAlive) { m_Connection.SendKeepAlive(a_KeepAlive); });
|
||||||
|
}
|
||||||
|
|
||||||
|
KeepAliveHandler::~KeepAliveHandler() {}
|
||||||
|
|
||||||
|
} // namespace client
|
||||||
|
} // namespace blitz
|
||||||
70
src/server/Server.cpp
Normal file
70
src/server/Server.cpp
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
#include <server/Server.h>
|
||||||
|
|
||||||
|
#include <server/components/EnetConnection.h>
|
||||||
|
#include <server/components/KeepAliveSession.h>
|
||||||
|
#include <server/handlers/KeepAliveHandler.h>
|
||||||
|
#include <server/systems/DisconnectSystem.h>
|
||||||
|
#include <server/systems/KeepAliveSystem.h>
|
||||||
|
|
||||||
|
namespace blitz {
|
||||||
|
namespace server {
|
||||||
|
|
||||||
|
Server::Server(std::uint16_t a_Port, std::shared_ptr<Nz::EnttWorld> a_World) : m_NetworkServer(a_Port) {
|
||||||
|
m_World.store(a_World);
|
||||||
|
RegisterSystems();
|
||||||
|
m_NetworkServer.OnClientConnect.Connect(this, &Server::HandleConnect);
|
||||||
|
m_NetworkServer.OnClientDisconnect.Connect(this, &Server::HandleDisconnect);
|
||||||
|
m_NetworkServer.OnClientDisconnectTimeout.Connect(this, &Server::HandleDisconnect);
|
||||||
|
}
|
||||||
|
|
||||||
|
Server::~Server() {}
|
||||||
|
|
||||||
|
void Server::HandleConnect(network::EnetConnection& a_Connection) {
|
||||||
|
Session newSession;
|
||||||
|
newSession.m_Connection = &a_Connection;
|
||||||
|
|
||||||
|
RegisterHandlers(newSession);
|
||||||
|
|
||||||
|
m_Sessions.insert({a_Connection.GetPeerId(), std::move(newSession)});
|
||||||
|
|
||||||
|
CreateEntity(a_Connection);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Server::HandleDisconnect(network::EnetConnection& a_Connection) {
|
||||||
|
m_Sessions.erase(a_Connection.GetPeerId());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Server::CreateEntity(network::EnetConnection& a_Connection) {
|
||||||
|
auto world = m_World.load();
|
||||||
|
|
||||||
|
auto entity = world->CreateEntity();
|
||||||
|
|
||||||
|
entity.emplace<KeepAliveSessionComponent>(a_Connection.GetPeerId(), 69, Nz::GetElapsedMilliseconds(), true);
|
||||||
|
entity.emplace<EnetConnectionComponent>(&a_Connection);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Server::RegisterSystems() {
|
||||||
|
auto world = m_World.load();
|
||||||
|
world->AddSystem<KeepAliveSystem>();
|
||||||
|
world->AddSystem<DisconectSystem>(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Server::RegisterHandlers(Session& session) {
|
||||||
|
session.m_Handlers.push_back(std::make_unique<KeepAliveHandler>(*session.m_Connection, m_World));
|
||||||
|
}
|
||||||
|
|
||||||
|
network::EnetConnection* Server::GetConnection(std::uint16_t a_PeerId) {
|
||||||
|
auto it = m_Sessions.find(a_PeerId);
|
||||||
|
|
||||||
|
if (it == m_Sessions.end())
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
return it->second.m_Connection;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Server::CloseConnection(std::uint16_t a_PeerId) {
|
||||||
|
m_NetworkServer.CloseConnection(a_PeerId);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace server
|
||||||
|
} // namespace blitz
|
||||||
29
src/server/handlers/KeepAliveHandler.cpp
Normal file
29
src/server/handlers/KeepAliveHandler.cpp
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
#include <server/handlers/KeepAliveHandler.h>
|
||||||
|
|
||||||
|
#include <server/components/KeepAliveSession.h>
|
||||||
|
|
||||||
|
#include <Nazara/Core/Time.hpp>
|
||||||
|
|
||||||
|
namespace blitz {
|
||||||
|
namespace server {
|
||||||
|
|
||||||
|
KeepAliveHandler::KeepAliveHandler(network::EnetConnection& a_Connection, EnttWorld& a_World) :
|
||||||
|
protocol::PacketHandler(a_Connection, a_World) {
|
||||||
|
m_Slot.Connect(a_Connection.OnKeepAlive,
|
||||||
|
[this](const protocol::data::KeepAlive& a_KeepAlive) { Handle(m_Connection.GetPeerId(), a_KeepAlive); });
|
||||||
|
}
|
||||||
|
|
||||||
|
KeepAliveHandler::~KeepAliveHandler() {}
|
||||||
|
|
||||||
|
void KeepAliveHandler::Handle(std::uint16_t a_PeerId, const protocol::data::KeepAlive& a_KeepAlive) {
|
||||||
|
auto world = m_World.load();
|
||||||
|
world->GetRegistry().view<KeepAliveSessionComponent>().each([a_PeerId, &a_KeepAlive](auto& keepAliveSession) {
|
||||||
|
if (keepAliveSession.m_PeerId == a_PeerId && keepAliveSession.m_LastKeepAliveId == a_KeepAlive.m_KeepAliveId) {
|
||||||
|
keepAliveSession.m_LastTime = Nz::GetElapsedMilliseconds();
|
||||||
|
keepAliveSession.m_RecievedResponse = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace server
|
||||||
|
} // namespace blitz
|
||||||
25
src/server/systems/DisconnectSystem.cpp
Normal file
25
src/server/systems/DisconnectSystem.cpp
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
#include <server/systems/DisconnectSystem.h>
|
||||||
|
|
||||||
|
#include <server/components/Disconnect.h>
|
||||||
|
#include <server/components/EnetConnection.h>
|
||||||
|
|
||||||
|
#include <server/Server.h>
|
||||||
|
|
||||||
|
namespace blitz {
|
||||||
|
namespace server {
|
||||||
|
|
||||||
|
DisconectSystem::DisconectSystem(entt::registry& a_Registry, Server& a_Server) : m_Registry(a_Registry), m_Server(a_Server) {}
|
||||||
|
|
||||||
|
void DisconectSystem::Update(Nz::Time elapsedTime) {
|
||||||
|
m_Registry.view<EnetConnectionComponent, DisconnectComponent>().each(
|
||||||
|
[this](auto entity, EnetConnectionComponent& connection, DisconnectComponent disconnect) {
|
||||||
|
m_Server.CloseConnection(connection.m_Connection->GetPeerId());
|
||||||
|
});
|
||||||
|
|
||||||
|
// remove the entities
|
||||||
|
auto it = m_Registry.view<DisconnectComponent>();
|
||||||
|
m_Registry.destroy(it.begin(), it.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace server
|
||||||
|
} // namespace blitz
|
||||||
38
src/server/systems/KeepAliveSystem.cpp
Normal file
38
src/server/systems/KeepAliveSystem.cpp
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
#include <server/systems/KeepAliveSystem.h>
|
||||||
|
|
||||||
|
#include <server/components/Disconnect.h>
|
||||||
|
#include <server/components/EnetConnection.h>
|
||||||
|
#include <server/components/KeepAliveSession.h>
|
||||||
|
|
||||||
|
#include <random>
|
||||||
|
|
||||||
|
namespace blitz {
|
||||||
|
namespace server {
|
||||||
|
|
||||||
|
KeepAliveSystem::KeepAliveSystem(entt::registry& a_Registry) : m_Registry(a_Registry) {}
|
||||||
|
|
||||||
|
void KeepAliveSystem::Update(Nz::Time elapsedTime) {
|
||||||
|
m_Registry.view<KeepAliveSessionComponent, EnetConnectionComponent>().each(
|
||||||
|
[this](auto entity, auto& keepAliveSession, auto& connection) {
|
||||||
|
auto duration = Nz::GetElapsedMilliseconds() - keepAliveSession.m_LastTime;
|
||||||
|
if (duration > Nz::Time::Seconds(10)) {
|
||||||
|
if (keepAliveSession.m_RecievedResponse) {
|
||||||
|
keepAliveSession.m_RecievedResponse = false;
|
||||||
|
keepAliveSession.m_LastTime = Nz::GetElapsedMilliseconds();
|
||||||
|
|
||||||
|
std::random_device rd;
|
||||||
|
std::uniform_int_distribution<std::uint64_t> dis(0, std::numeric_limits<std::uint64_t>::max());
|
||||||
|
std::uint64_t keepAliveId = dis(rd);
|
||||||
|
|
||||||
|
keepAliveSession.m_LastKeepAliveId = keepAliveId;
|
||||||
|
connection.m_Connection->SendKeepAlive({keepAliveId});
|
||||||
|
} else {
|
||||||
|
// We kick the player because he's not responding anymore
|
||||||
|
m_Registry.emplace<DisconnectComponent>(entity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace server
|
||||||
|
} // namespace blitz
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
add_rules("mode.debug", "mode.release")
|
add_rules("mode.debug", "mode.release")
|
||||||
|
|
||||||
add_repositories("nazara-repo https://github.com/NazaraEngine/xmake-repo.git")
|
add_repositories("nazara-repo https://github.com/NazaraEngine/xmake-repo.git")
|
||||||
add_requires("nazaraengine", { debug = is_mode("debug") })
|
add_requires("nazaraengine", { debug = false })
|
||||||
|
|
||||||
set_languages("c++20")
|
set_languages("c++20")
|
||||||
set_warnings("all")
|
set_warnings("all")
|
||||||
@@ -12,7 +12,7 @@ end
|
|||||||
|
|
||||||
target("BlitzLib")
|
target("BlitzLib")
|
||||||
set_kind("static")
|
set_kind("static")
|
||||||
add_files("src/blitz/**.cpp")
|
add_files("src/blitz/**.cpp", "src/client/**.cpp", "src/server/**.cpp")
|
||||||
add_includedirs("include")
|
add_includedirs("include")
|
||||||
add_packages("nazaraengine")
|
add_packages("nazaraengine")
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user