implement server and client player join/leave notifications
This commit is contained in:
9
include/blitz/common/Types.h
Normal file
9
include/blitz/common/Types.h
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
namespace blitz {
|
||||||
|
|
||||||
|
using EntityID = std::uint32_t;
|
||||||
|
|
||||||
|
} // namespace blitz
|
||||||
13
include/blitz/components/PlayerInfo.h
Normal file
13
include/blitz/components/PlayerInfo.h
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <blitz/common/Types.h>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace blitz {
|
||||||
|
|
||||||
|
struct PlayerInfoComponent {
|
||||||
|
EntityID m_PlayerId;
|
||||||
|
std::string m_Pseudo;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace blitz
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <string>
|
#include <blitz/components/PlayerInfo.h>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
namespace blitz {
|
namespace blitz {
|
||||||
namespace protocol {
|
namespace protocol {
|
||||||
@@ -14,17 +15,25 @@ struct UpdateHealth {
|
|||||||
float m_NewHealth;
|
float m_NewHealth;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct LoggingSuccess {};
|
struct LoggingSuccess {
|
||||||
|
EntityID m_PlayerId;
|
||||||
|
};
|
||||||
|
|
||||||
struct PlayerDeath {};
|
struct PlayerDeath {};
|
||||||
|
|
||||||
struct PlayerJoin {};
|
struct PlayerJoin {
|
||||||
|
PlayerInfoComponent m_Player;
|
||||||
|
};
|
||||||
|
|
||||||
struct PlayerLeave {};
|
struct PlayerLeave {
|
||||||
|
EntityID m_PlayerId;
|
||||||
|
};
|
||||||
|
|
||||||
struct PlayerStats {};
|
struct PlayerStats {};
|
||||||
|
|
||||||
struct PlayerList {};
|
struct PlayerList {
|
||||||
|
std::vector<PlayerInfoComponent> m_Players;
|
||||||
|
};
|
||||||
|
|
||||||
struct ServerConfig {};
|
struct ServerConfig {};
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ namespace client {
|
|||||||
|
|
||||||
class Client : private NonCopyable {
|
class Client : private NonCopyable {
|
||||||
public:
|
public:
|
||||||
Client();
|
Client(std::shared_ptr<Nz::EnttWorld> a_World);
|
||||||
~Client();
|
~Client();
|
||||||
|
|
||||||
void Connect(const Nz::IpAddress& a_Ip);
|
void Connect(const Nz::IpAddress& a_Ip);
|
||||||
@@ -25,6 +25,7 @@ class Client : private NonCopyable {
|
|||||||
|
|
||||||
void BindHandlers();
|
void BindHandlers();
|
||||||
void UnbindHandlers();
|
void UnbindHandlers();
|
||||||
|
void Login();
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace client
|
} // namespace client
|
||||||
|
|||||||
13
include/client/components/LocalPlayer.h
Normal file
13
include/client/components/LocalPlayer.h
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <blitz/common/Types.h>
|
||||||
|
|
||||||
|
namespace blitz {
|
||||||
|
namespace client {
|
||||||
|
|
||||||
|
struct LocalPlayerComponent {
|
||||||
|
EntityID m_LocalPlayerId;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace client
|
||||||
|
} // namespace blitz
|
||||||
@@ -9,6 +9,9 @@ class KeepAliveHandler : public protocol::PacketHandler {
|
|||||||
~KeepAliveHandler();
|
~KeepAliveHandler();
|
||||||
|
|
||||||
NazaraSlot(network::EnetConnection, OnKeepAlive, m_Slot);
|
NazaraSlot(network::EnetConnection, OnKeepAlive, m_Slot);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void Handle(const protocol::data::KeepAlive&);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace client
|
} // namespace client
|
||||||
|
|||||||
18
include/client/handlers/LoggingSuccessHandler.h
Normal file
18
include/client/handlers/LoggingSuccessHandler.h
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
#include <blitz/protocol/PacketHandler.h>
|
||||||
|
|
||||||
|
namespace blitz {
|
||||||
|
namespace client {
|
||||||
|
|
||||||
|
class LoggingSuccessHandler : public protocol::PacketHandler {
|
||||||
|
public:
|
||||||
|
LoggingSuccessHandler(network::EnetConnection& a_Connection, EnttWorld& a_World);
|
||||||
|
~LoggingSuccessHandler();
|
||||||
|
|
||||||
|
NazaraSlot(network::EnetConnection, OnLoggingSuccess, m_Slot);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void Handle(const protocol::data::LoggingSuccess&);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace client
|
||||||
|
} // namespace blitz
|
||||||
18
include/client/handlers/PlayerJoinHandler.h
Normal file
18
include/client/handlers/PlayerJoinHandler.h
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
#include <blitz/protocol/PacketHandler.h>
|
||||||
|
|
||||||
|
namespace blitz {
|
||||||
|
namespace client {
|
||||||
|
|
||||||
|
class PlayerJoinHandler : public protocol::PacketHandler {
|
||||||
|
public:
|
||||||
|
PlayerJoinHandler(network::EnetConnection& a_Connection, EnttWorld& a_World);
|
||||||
|
~PlayerJoinHandler();
|
||||||
|
|
||||||
|
NazaraSlot(network::EnetConnection, OnPlayerJoin, m_Slot);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void Handle(const protocol::data::PlayerJoin&);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace client
|
||||||
|
} // namespace blitz
|
||||||
18
include/client/handlers/PlayerLeaveHandler.h
Normal file
18
include/client/handlers/PlayerLeaveHandler.h
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
#include <blitz/protocol/PacketHandler.h>
|
||||||
|
|
||||||
|
namespace blitz {
|
||||||
|
namespace client {
|
||||||
|
|
||||||
|
class PlayerLeaveHandler : public protocol::PacketHandler {
|
||||||
|
public:
|
||||||
|
PlayerLeaveHandler(network::EnetConnection& a_Connection, EnttWorld& a_World);
|
||||||
|
~PlayerLeaveHandler();
|
||||||
|
|
||||||
|
NazaraSlot(network::EnetConnection, OnPlayerLeave, m_Slot);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void Handle(const protocol::data::PlayerLeave&);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace client
|
||||||
|
} // namespace blitz
|
||||||
18
include/client/handlers/PlayerListHandler.h
Normal file
18
include/client/handlers/PlayerListHandler.h
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
#include <blitz/protocol/PacketHandler.h>
|
||||||
|
|
||||||
|
namespace blitz {
|
||||||
|
namespace client {
|
||||||
|
|
||||||
|
class PlayerListHandler : public protocol::PacketHandler {
|
||||||
|
public:
|
||||||
|
PlayerListHandler(network::EnetConnection& a_Connection, EnttWorld& a_World);
|
||||||
|
~PlayerListHandler();
|
||||||
|
|
||||||
|
NazaraSlot(network::EnetConnection, OnPlayerList, m_Slot);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void Handle(const protocol::data::PlayerList&);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace client
|
||||||
|
} // namespace blitz
|
||||||
@@ -8,6 +8,10 @@ namespace server {
|
|||||||
|
|
||||||
class Server {
|
class Server {
|
||||||
public:
|
public:
|
||||||
|
/**
|
||||||
|
* \brief Construct a server
|
||||||
|
* \pre Two instances of Server should not share the same world
|
||||||
|
*/
|
||||||
Server(std::uint16_t a_Port, std::shared_ptr<Nz::EnttWorld> a_World);
|
Server(std::uint16_t a_Port, std::shared_ptr<Nz::EnttWorld> a_World);
|
||||||
~Server();
|
~Server();
|
||||||
|
|
||||||
|
|||||||
13
include/server/components/ServerIdCounter.h
Normal file
13
include/server/components/ServerIdCounter.h
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <blitz/common/Types.h>
|
||||||
|
|
||||||
|
namespace blitz {
|
||||||
|
namespace server {
|
||||||
|
|
||||||
|
struct ServerIdCounterComponent {
|
||||||
|
EntityID m_NextEntityId;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace server
|
||||||
|
} // namespace blitz
|
||||||
20
include/server/handlers/PlayerLoginHandler.h
Normal file
20
include/server/handlers/PlayerLoginHandler.h
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <blitz/protocol/PacketHandler.h>
|
||||||
|
|
||||||
|
namespace blitz {
|
||||||
|
namespace server {
|
||||||
|
|
||||||
|
class PlayerLoginHandler : public protocol::PacketHandler {
|
||||||
|
public:
|
||||||
|
PlayerLoginHandler(network::EnetConnection& a_Connection, EnttWorld& a_World);
|
||||||
|
~PlayerLoginHandler();
|
||||||
|
|
||||||
|
NazaraSlot(network::EnetConnection, OnPlayerLogin, m_Slot);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void Handle(std::uint16_t, const protocol::data::PlayerLogin&);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace server
|
||||||
|
} // namespace blitz
|
||||||
@@ -152,10 +152,13 @@ void Deserializer::DeserializePacketData(data::UpdateHealth& a_Packet) {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void Serializer::SerializePacketData(const data::LoggingSuccess& a_Packet) {
|
||||||
|
m_Buffer << a_Packet.m_PlayerId;
|
||||||
|
}
|
||||||
|
|
||||||
void Serializer::SerializePacketData(const data::LoggingSuccess& a_Packet) {}
|
void Deserializer::DeserializePacketData(data::LoggingSuccess& a_Packet) {
|
||||||
|
m_Buffer >> a_Packet.m_PlayerId;
|
||||||
void Deserializer::DeserializePacketData(data::LoggingSuccess& a_Packet) {}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -167,23 +170,44 @@ void Deserializer::DeserializePacketData(data::PlayerDeath& a_Packet) {}
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void Serializer::SerializePacketData(const data::PlayerJoin& a_Packet) {}
|
void Serializer::SerializePacketData(const data::PlayerJoin& a_Packet) {
|
||||||
|
m_Buffer << a_Packet.m_Player.m_PlayerId << a_Packet.m_Player.m_Pseudo;
|
||||||
|
}
|
||||||
|
|
||||||
void Deserializer::DeserializePacketData(data::PlayerJoin& a_Packet) {}
|
void Deserializer::DeserializePacketData(data::PlayerJoin& a_Packet) {
|
||||||
|
m_Buffer >> a_Packet.m_Player.m_PlayerId >> a_Packet.m_Player.m_Pseudo;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void Serializer::SerializePacketData(const data::PlayerLeave& a_Packet) {}
|
void Serializer::SerializePacketData(const data::PlayerLeave& a_Packet) {
|
||||||
|
m_Buffer << a_Packet.m_PlayerId;
|
||||||
|
}
|
||||||
|
|
||||||
void Deserializer::DeserializePacketData(data::PlayerLeave& a_Packet) {}
|
void Deserializer::DeserializePacketData(data::PlayerLeave& a_Packet) {
|
||||||
|
m_Buffer >> a_Packet.m_PlayerId;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void Serializer::SerializePacketData(const data::PlayerList& a_Packet) {}
|
void Serializer::SerializePacketData(const data::PlayerList& a_Packet) {
|
||||||
|
m_Buffer << static_cast<std::uint8_t>(a_Packet.m_Players.size());
|
||||||
|
for (auto player : a_Packet.m_Players) {
|
||||||
|
m_Buffer << player.m_PlayerId << player.m_Pseudo;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Deserializer::DeserializePacketData(data::PlayerList& a_Packet) {}
|
void Deserializer::DeserializePacketData(data::PlayerList& a_Packet) {
|
||||||
|
std::uint8_t playerCount;
|
||||||
|
m_Buffer >> playerCount;
|
||||||
|
for (std::uint8_t i = 0; i < playerCount; i++) {
|
||||||
|
PlayerInfoComponent player;
|
||||||
|
m_Buffer >> player.m_PlayerId >> player.m_Pseudo;
|
||||||
|
a_Packet.m_Players.push_back(player);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,18 @@
|
|||||||
#include <client/Client.h>
|
#include <client/Client.h>
|
||||||
|
|
||||||
#include <client/handlers/KeepAliveHandler.h>
|
#include <client/handlers/KeepAliveHandler.h>
|
||||||
|
#include <client/handlers/LoggingSuccessHandler.h>
|
||||||
|
#include <client/handlers/PlayerJoinHandler.h>
|
||||||
|
#include <client/handlers/PlayerLeaveHandler.h>
|
||||||
|
#include <client/handlers/PlayerListHandler.h>
|
||||||
|
|
||||||
|
#define RegisterHandler(Handler) m_Handlers.push_back(std::make_unique<Handler>(m_NetworkClient->GetConnection(), m_World))
|
||||||
|
|
||||||
namespace blitz {
|
namespace blitz {
|
||||||
namespace client {
|
namespace client {
|
||||||
|
|
||||||
Client::Client() : m_World() {
|
Client::Client(std::shared_ptr<Nz::EnttWorld> a_World) {
|
||||||
m_World.store(std::make_shared<Nz::EnttWorld>());
|
m_World.store(a_World);
|
||||||
}
|
}
|
||||||
|
|
||||||
Client::~Client() {
|
Client::~Client() {
|
||||||
@@ -14,7 +20,11 @@ Client::~Client() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Client::BindHandlers() {
|
void Client::BindHandlers() {
|
||||||
m_Handlers.push_back(std::make_unique<KeepAliveHandler>(m_NetworkClient->GetConnection(), m_World));
|
RegisterHandler(KeepAliveHandler);
|
||||||
|
RegisterHandler(LoggingSuccessHandler);
|
||||||
|
RegisterHandler(PlayerJoinHandler);
|
||||||
|
RegisterHandler(PlayerLeaveHandler);
|
||||||
|
RegisterHandler(PlayerListHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::UnbindHandlers() {
|
void Client::UnbindHandlers() {
|
||||||
@@ -24,6 +34,7 @@ void Client::UnbindHandlers() {
|
|||||||
void Client::Connect(const Nz::IpAddress& a_Ip) {
|
void Client::Connect(const Nz::IpAddress& a_Ip) {
|
||||||
m_NetworkClient = std::make_unique<network::EnetClient>(a_Ip);
|
m_NetworkClient = std::make_unique<network::EnetClient>(a_Ip);
|
||||||
BindHandlers();
|
BindHandlers();
|
||||||
|
m_NetworkClient->OnConnect.Connect([this]() { Login(); });
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::Disconnect() {
|
void Client::Disconnect() {
|
||||||
@@ -41,5 +52,11 @@ bool Client::IsConnected() {
|
|||||||
return m_NetworkClient->GetConnection().IsConnected();
|
return m_NetworkClient->GetConnection().IsConnected();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Client::Login() {
|
||||||
|
if (!m_NetworkClient || !m_NetworkClient->GetConnection().IsConnected())
|
||||||
|
return;
|
||||||
|
m_NetworkClient->GetConnection().SendPlayerLogin({"Player_" + std::to_string(rand() % 100)});
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace client
|
} // namespace client
|
||||||
} // namespace blitz
|
} // namespace blitz
|
||||||
|
|||||||
@@ -5,8 +5,11 @@ namespace client {
|
|||||||
|
|
||||||
KeepAliveHandler::KeepAliveHandler(network::EnetConnection& a_Connection, EnttWorld& a_World) :
|
KeepAliveHandler::KeepAliveHandler(network::EnetConnection& a_Connection, EnttWorld& a_World) :
|
||||||
protocol::PacketHandler(a_Connection, a_World) {
|
protocol::PacketHandler(a_Connection, a_World) {
|
||||||
m_Slot.Connect(m_Connection.OnKeepAlive,
|
m_Slot.Connect(m_Connection.OnKeepAlive, this, &KeepAliveHandler::Handle);
|
||||||
[this](const blitz::protocol::data::KeepAlive& a_KeepAlive) { m_Connection.SendKeepAlive(a_KeepAlive); });
|
}
|
||||||
|
|
||||||
|
void KeepAliveHandler::Handle(const blitz::protocol::data::KeepAlive& a_KeepAlive) {
|
||||||
|
m_Connection.SendKeepAlive(a_KeepAlive);
|
||||||
}
|
}
|
||||||
|
|
||||||
KeepAliveHandler::~KeepAliveHandler() {}
|
KeepAliveHandler::~KeepAliveHandler() {}
|
||||||
|
|||||||
22
src/client/handlers/LoggingSuccessHandler.cpp
Normal file
22
src/client/handlers/LoggingSuccessHandler.cpp
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
#include <client/handlers/LoggingSuccessHandler.h>
|
||||||
|
|
||||||
|
#include <client/components/LocalPlayer.h>
|
||||||
|
|
||||||
|
namespace blitz {
|
||||||
|
namespace client {
|
||||||
|
|
||||||
|
LoggingSuccessHandler::LoggingSuccessHandler(network::EnetConnection& a_Connection, EnttWorld& a_World) :
|
||||||
|
protocol::PacketHandler(a_Connection, a_World) {
|
||||||
|
m_Slot.Connect(m_Connection.OnLoggingSuccess, this, &LoggingSuccessHandler::Handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LoggingSuccessHandler::Handle(const blitz::protocol::data::LoggingSuccess& a_LoggingSuccess) {
|
||||||
|
auto world = m_World.load();
|
||||||
|
auto player = world->CreateEntity();
|
||||||
|
player.emplace<LocalPlayerComponent>(a_LoggingSuccess.m_PlayerId);
|
||||||
|
}
|
||||||
|
|
||||||
|
LoggingSuccessHandler::~LoggingSuccessHandler() {}
|
||||||
|
|
||||||
|
} // namespace client
|
||||||
|
} // namespace blitz
|
||||||
35
src/client/handlers/PlayerJoinHandler.cpp
Normal file
35
src/client/handlers/PlayerJoinHandler.cpp
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
#include <client/handlers/PlayerJoinHandler.h>
|
||||||
|
|
||||||
|
#include <client/components/LocalPlayer.h>
|
||||||
|
|
||||||
|
namespace blitz {
|
||||||
|
namespace client {
|
||||||
|
|
||||||
|
PlayerJoinHandler::PlayerJoinHandler(network::EnetConnection& a_Connection, EnttWorld& a_World) :
|
||||||
|
protocol::PacketHandler(a_Connection, a_World) {
|
||||||
|
m_Slot.Connect(m_Connection.OnPlayerJoin, this, &PlayerJoinHandler::Handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PlayerJoinHandler::Handle(const protocol::data::PlayerJoin& a_PlayerJoin) {
|
||||||
|
auto world = m_World.load();
|
||||||
|
assert(world->GetRegistry().view<LocalPlayerComponent>().size() == 1 && "There should be only one local player !");
|
||||||
|
|
||||||
|
auto localPlayer = world->GetRegistry().view<LocalPlayerComponent>().front();
|
||||||
|
auto localPlayerId = world->GetRegistry().get<LocalPlayerComponent>(localPlayer).m_LocalPlayerId;
|
||||||
|
|
||||||
|
if (a_PlayerJoin.m_Player.m_PlayerId != localPlayerId) {
|
||||||
|
auto newPlayer = world->CreateEntity();
|
||||||
|
|
||||||
|
newPlayer.emplace<PlayerInfoComponent>(a_PlayerJoin.m_Player);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
world->GetRegistry().emplace<PlayerInfoComponent>(localPlayer, a_PlayerJoin.m_Player);
|
||||||
|
|
||||||
|
// we are now into the game so we can begin to load the world for example
|
||||||
|
}
|
||||||
|
|
||||||
|
PlayerJoinHandler::~PlayerJoinHandler() {}
|
||||||
|
|
||||||
|
} // namespace client
|
||||||
|
} // namespace blitz
|
||||||
29
src/client/handlers/PlayerLeaveHandler.cpp
Normal file
29
src/client/handlers/PlayerLeaveHandler.cpp
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
#include <client/handlers/PlayerLeaveHandler.h>
|
||||||
|
|
||||||
|
namespace blitz {
|
||||||
|
namespace client {
|
||||||
|
|
||||||
|
PlayerLeaveHandler::PlayerLeaveHandler(network::EnetConnection& a_Connection, EnttWorld& a_World) :
|
||||||
|
protocol::PacketHandler(a_Connection, a_World) {
|
||||||
|
m_Slot.Connect(m_Connection.OnPlayerLeave, this, &PlayerLeaveHandler::Handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PlayerLeaveHandler::Handle(const protocol::data::PlayerLeave& a_PlayerLeave) {
|
||||||
|
auto world = m_World.load();
|
||||||
|
|
||||||
|
entt::entity playerLeft;
|
||||||
|
|
||||||
|
for (auto [player, playerInfo] : world->GetRegistry().view<PlayerInfoComponent>().each()) {
|
||||||
|
if (playerInfo.m_PlayerId == a_PlayerLeave.m_PlayerId) {
|
||||||
|
playerLeft = player;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
world->GetRegistry().destroy(playerLeft);
|
||||||
|
}
|
||||||
|
|
||||||
|
PlayerLeaveHandler::~PlayerLeaveHandler() {}
|
||||||
|
|
||||||
|
} // namespace client
|
||||||
|
} // namespace blitz
|
||||||
22
src/client/handlers/PlayerListHandler.cpp
Normal file
22
src/client/handlers/PlayerListHandler.cpp
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
#include <client/handlers/PlayerListHandler.h>
|
||||||
|
|
||||||
|
namespace blitz {
|
||||||
|
namespace client {
|
||||||
|
|
||||||
|
PlayerListHandler::PlayerListHandler(network::EnetConnection& a_Connection, EnttWorld& a_World) :
|
||||||
|
protocol::PacketHandler(a_Connection, a_World) {
|
||||||
|
m_Slot.Connect(m_Connection.OnPlayerList, this, &PlayerListHandler::Handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PlayerListHandler::Handle(const protocol::data::PlayerList& a_PlayerList) {
|
||||||
|
auto world = m_World.load();
|
||||||
|
for (auto playerInfo : a_PlayerList.m_Players) {
|
||||||
|
auto player = world->CreateEntity();
|
||||||
|
player.emplace<PlayerInfoComponent>(playerInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PlayerListHandler::~PlayerListHandler() {}
|
||||||
|
|
||||||
|
} // namespace client
|
||||||
|
} // namespace blitz
|
||||||
@@ -1,14 +1,19 @@
|
|||||||
#include <server/Server.h>
|
#include <server/Server.h>
|
||||||
|
|
||||||
#include <server/components/EnetConnection.h>
|
#include <server/components/EnetConnection.h>
|
||||||
#include <server/components/KeepAliveSession.h>
|
#include <server/components/ServerIdCounter.h>
|
||||||
|
|
||||||
#include <server/handlers/KeepAliveHandler.h>
|
#include <server/handlers/KeepAliveHandler.h>
|
||||||
|
#include <server/handlers/PlayerLoginHandler.h>
|
||||||
|
|
||||||
#include <server/systems/DisconnectSystem.h>
|
#include <server/systems/DisconnectSystem.h>
|
||||||
#include <server/systems/KeepAliveSystem.h>
|
#include <server/systems/KeepAliveSystem.h>
|
||||||
|
|
||||||
namespace blitz {
|
namespace blitz {
|
||||||
namespace server {
|
namespace server {
|
||||||
|
|
||||||
|
#define RegisterHandler(Handler) session.m_Handlers.push_back(std::make_unique<Handler>(*session.m_Connection, m_World))
|
||||||
|
|
||||||
Server::Server(std::uint16_t a_Port, std::shared_ptr<Nz::EnttWorld> a_World) : m_NetworkServer(a_Port) {
|
Server::Server(std::uint16_t a_Port, std::shared_ptr<Nz::EnttWorld> a_World) : m_NetworkServer(a_Port) {
|
||||||
m_World.store(a_World);
|
m_World.store(a_World);
|
||||||
RegisterSystems();
|
RegisterSystems();
|
||||||
@@ -39,7 +44,6 @@ void Server::CreateEntity(network::EnetConnection& a_Connection) {
|
|||||||
|
|
||||||
auto entity = world->CreateEntity();
|
auto entity = world->CreateEntity();
|
||||||
|
|
||||||
entity.emplace<KeepAliveSessionComponent>(a_Connection.GetPeerId(), 69, Nz::GetElapsedMilliseconds(), true);
|
|
||||||
entity.emplace<EnetConnectionComponent>(&a_Connection);
|
entity.emplace<EnetConnectionComponent>(&a_Connection);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -47,10 +51,14 @@ void Server::RegisterSystems() {
|
|||||||
auto world = m_World.load();
|
auto world = m_World.load();
|
||||||
world->AddSystem<KeepAliveSystem>();
|
world->AddSystem<KeepAliveSystem>();
|
||||||
world->AddSystem<DisconectSystem>(*this);
|
world->AddSystem<DisconectSystem>(*this);
|
||||||
|
|
||||||
|
auto counter = world->CreateEntity();
|
||||||
|
counter.emplace<ServerIdCounterComponent>(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server::RegisterHandlers(Session& session) {
|
void Server::RegisterHandlers(Session& session) {
|
||||||
session.m_Handlers.push_back(std::make_unique<KeepAliveHandler>(*session.m_Connection, m_World));
|
RegisterHandler(KeepAliveHandler);
|
||||||
|
RegisterHandler(PlayerLoginHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
network::EnetConnection* Server::GetConnection(std::uint16_t a_PeerId) {
|
network::EnetConnection* Server::GetConnection(std::uint16_t a_PeerId) {
|
||||||
|
|||||||
68
src/server/handlers/PlayerLoginHandler.cpp
Normal file
68
src/server/handlers/PlayerLoginHandler.cpp
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
#include <server/handlers/PlayerLoginHandler.h>
|
||||||
|
|
||||||
|
#include <Nazara/Core/Time.hpp>
|
||||||
|
#include <blitz/components/PlayerInfo.h>
|
||||||
|
#include <server/components/EnetConnection.h>
|
||||||
|
#include <server/components/KeepAliveSession.h>
|
||||||
|
#include <server/components/ServerIdCounter.h>
|
||||||
|
|
||||||
|
namespace blitz {
|
||||||
|
namespace server {
|
||||||
|
|
||||||
|
PlayerLoginHandler::PlayerLoginHandler(network::EnetConnection& a_Connection, EnttWorld& a_World) :
|
||||||
|
protocol::PacketHandler(a_Connection, a_World) {
|
||||||
|
m_Slot.Connect(a_Connection.OnPlayerLogin,
|
||||||
|
[this](const protocol::data::PlayerLogin& a_PlayerLogin) { Handle(m_Connection.GetPeerId(), a_PlayerLogin); });
|
||||||
|
}
|
||||||
|
|
||||||
|
PlayerLoginHandler::~PlayerLoginHandler() {}
|
||||||
|
|
||||||
|
void PlayerLoginHandler::Handle(std::uint16_t a_PeerId, const protocol::data::PlayerLogin& a_PlayerLogin) {
|
||||||
|
auto world = m_World.load();
|
||||||
|
|
||||||
|
std::vector<PlayerInfoComponent> players;
|
||||||
|
|
||||||
|
for (auto [entity, playerInfo] : world->GetRegistry().view<PlayerInfoComponent>().each()) {
|
||||||
|
players.push_back(playerInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(world->GetRegistry().view<ServerIdCounterComponent>().size() == 1 && "There should be only one counter !");
|
||||||
|
|
||||||
|
auto& serverCounter =
|
||||||
|
world->GetRegistry().get<ServerIdCounterComponent>(world->GetRegistry().view<ServerIdCounterComponent>().front());
|
||||||
|
|
||||||
|
EntityID newEntityId = serverCounter.m_NextEntityId++;
|
||||||
|
|
||||||
|
PlayerInfoComponent newPlayer;
|
||||||
|
|
||||||
|
for (auto [entity, connection] : world->GetRegistry().view<EnetConnectionComponent>().each()) {
|
||||||
|
if (connection.m_Connection->GetPeerId() == m_Connection.GetPeerId()) {
|
||||||
|
// players should not try to log in twice
|
||||||
|
auto previousPlayerInfo = world->GetRegistry().try_get<PlayerInfoComponent>(entity);
|
||||||
|
if (previousPlayerInfo)
|
||||||
|
return;
|
||||||
|
|
||||||
|
newPlayer = world->GetRegistry().emplace<PlayerInfoComponent>(entity, newEntityId, a_PlayerLogin.m_PlayerName);
|
||||||
|
|
||||||
|
world->GetRegistry().emplace<KeepAliveSessionComponent>(
|
||||||
|
entity, m_Connection.GetPeerId(), 69, Nz::GetElapsedMilliseconds(), true);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// send logging success
|
||||||
|
m_Connection.SendLoggingSuccess({newEntityId});
|
||||||
|
|
||||||
|
// send player list
|
||||||
|
if (!players.empty())
|
||||||
|
m_Connection.SendPlayerList({players});
|
||||||
|
|
||||||
|
// broadcast player join
|
||||||
|
for (auto [entity, connection] : world->GetRegistry().view<EnetConnectionComponent>().each()) {
|
||||||
|
connection.m_Connection->SendPlayerJoin({newPlayer});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace server
|
||||||
|
} // namespace blitz
|
||||||
@@ -11,14 +11,26 @@ namespace server {
|
|||||||
DisconectSystem::DisconectSystem(entt::registry& a_Registry, Server& a_Server) : m_Registry(a_Registry), m_Server(a_Server) {}
|
DisconectSystem::DisconectSystem(entt::registry& a_Registry, Server& a_Server) : m_Registry(a_Registry), m_Server(a_Server) {}
|
||||||
|
|
||||||
void DisconectSystem::Update(Nz::Time elapsedTime) {
|
void DisconectSystem::Update(Nz::Time elapsedTime) {
|
||||||
|
auto disconnects = m_Registry.view<DisconnectComponent>();
|
||||||
|
|
||||||
|
// broadcast player leave
|
||||||
|
for (auto entity : disconnects) {
|
||||||
|
auto* player = m_Registry.try_get<PlayerInfoComponent>(entity);
|
||||||
|
if (player) {
|
||||||
|
for (auto [entity, connection] : m_Registry.view<EnetConnectionComponent>().each()) {
|
||||||
|
connection.m_Connection->SendPlayerLeave({player->m_PlayerId});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// close connections
|
||||||
m_Registry.view<EnetConnectionComponent, DisconnectComponent>().each(
|
m_Registry.view<EnetConnectionComponent, DisconnectComponent>().each(
|
||||||
[this](auto entity, EnetConnectionComponent& connection, DisconnectComponent disconnect) {
|
[this](auto entity, EnetConnectionComponent& connection, DisconnectComponent disconnect) {
|
||||||
m_Server.CloseConnection(connection.m_Connection->GetPeerId());
|
m_Server.CloseConnection(connection.m_Connection->GetPeerId());
|
||||||
});
|
});
|
||||||
|
|
||||||
// remove the entities
|
// remove the entities
|
||||||
auto it = m_Registry.view<DisconnectComponent>();
|
m_Registry.destroy(disconnects.begin(), disconnects.end());
|
||||||
m_Registry.destroy(it.begin(), it.end());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace server
|
} // namespace server
|
||||||
|
|||||||
Reference in New Issue
Block a user