implement server and client player join/leave notifications

This commit is contained in:
2024-07-22 12:58:40 +02:00
parent cbb2f5005e
commit 392eaeab83
23 changed files with 422 additions and 25 deletions

View File

@@ -1,12 +1,18 @@
#include <client/Client.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 client {
Client::Client() : m_World() {
m_World.store(std::make_shared<Nz::EnttWorld>());
Client::Client(std::shared_ptr<Nz::EnttWorld> a_World) {
m_World.store(a_World);
}
Client::~Client() {
@@ -14,7 +20,11 @@ Client::~Client() {
}
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() {
@@ -24,6 +34,7 @@ void Client::UnbindHandlers() {
void Client::Connect(const Nz::IpAddress& a_Ip) {
m_NetworkClient = std::make_unique<network::EnetClient>(a_Ip);
BindHandlers();
m_NetworkClient->OnConnect.Connect([this]() { Login(); });
}
void Client::Disconnect() {
@@ -41,5 +52,11 @@ bool Client::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 blitz

View File

@@ -5,8 +5,11 @@ 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); });
m_Slot.Connect(m_Connection.OnKeepAlive, this, &KeepAliveHandler::Handle);
}
void KeepAliveHandler::Handle(const blitz::protocol::data::KeepAlive& a_KeepAlive) {
m_Connection.SendKeepAlive(a_KeepAlive);
}
KeepAliveHandler::~KeepAliveHandler() {}

View 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

View 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

View 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

View 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