9 Commits

Author SHA1 Message Date
5840ae1922 add BaseClient class
All checks were successful
Linux arm64 / Build (push) Successful in 5m8s
2024-06-03 16:03:05 +02:00
21b5a473d5 add PacketDerived static check
All checks were successful
Linux arm64 / Build (push) Successful in 4m42s
2024-06-01 19:21:11 +02:00
29a66ca7d1 use of more reference
All checks were successful
Linux arm64 / Build (push) Successful in 42m42s
2024-06-01 15:59:48 +02:00
814c944b16 use of std remove 2024-06-01 15:54:01 +02:00
5efbb7c15b move AudioBufferPtr declaration 2024-06-01 15:05:03 +02:00
3af3a4d221 remove \ 2024-06-01 14:54:35 +02:00
ca073d1062 const array 2024-06-01 14:54:25 +02:00
c2e0845999 pass packet and handler by reference 2024-06-01 14:20:26 +02:00
8b346754f1 use of template for packets 2024-06-01 12:34:42 +02:00
41 changed files with 425 additions and 373 deletions

View File

@@ -33,12 +33,7 @@ class ObjectNotifier {
* \brief Unbinds a listener (in case the listener is destroyed for example)
*/
void UnbindListener(Listener* listener) {
auto iter = std::find(m_Listeners.begin(), m_Listeners.end(), listener);
if (iter == m_Listeners.end())
return;
m_Listeners.erase(iter);
m_Listeners.erase(std::remove(m_Listeners.begin(), m_Listeners.end(), listener), m_Listeners.end());
}
/**

View File

@@ -27,12 +27,12 @@ class Connexion : public protocol::PacketHandler, private NonCopyable {
/**
* \brief Constructs with an empty socket
*/
Connexion(protocol::PacketDispatcher* dispatcher);
Connexion(protocol::PacketDispatcher& dispatcher);
/**
* \brief Constructs with an already connected socket
*/
Connexion(protocol::PacketDispatcher* dispatcher, TCPSocket& socket);
Connexion(protocol::PacketDispatcher& dispatcher, TCPSocket& socket);
/**
* \brief Move constructor

View File

@@ -33,25 +33,25 @@ class PacketDispatcher : private NonCopyable {
* \brief Dispatch a packet
* \param packet The packet to dispatch
*/
void Dispatch(const Packet* packet);
void Dispatch(const Packet& packet);
/**
* \brief Register a packet handler
* \param type The packet type
* \param handler The packet handler
*/
void RegisterHandler(PacketType type, PacketHandler* handler);
void RegisterHandler(PacketType type, PacketHandler& handler);
/**
* \brief Unregister a packet handler
* \param type The packet type
* \param handler The packet handler
*/
void UnregisterHandler(PacketType type, PacketHandler* handler);
void UnregisterHandler(PacketType type, PacketHandler& handler);
/**
* \brief Unregister a packet handler
* \param handler The packet handler
*/
void UnregisterHandler(PacketHandler* handler);
void UnregisterHandler(PacketHandler& handler);
};
} // namespace protocol

View File

@@ -19,40 +19,40 @@ class PacketDispatcher;
*/
class PacketHandler {
private:
PacketDispatcher* m_Dispatcher;
PacketDispatcher& m_Dispatcher;
public:
/**
* \brief Constructor
* \param dispatcher The packet dispatcher
*/
PacketHandler(PacketDispatcher* dispatcher) : m_Dispatcher(dispatcher) {}
PacketHandler(PacketDispatcher& dispatcher) : m_Dispatcher(dispatcher) {}
virtual ~PacketHandler() {}
/**
* \brief Get the packet dispatcher
* \return The packet dispatcher
*/
PacketDispatcher* GetDispatcher() {
PacketDispatcher& GetDispatcher() {
return m_Dispatcher;
}
virtual void HandlePacket(const ChatPacket* packet) {}
virtual void HandlePacket(const ConnexionInfoPacket* packet) {}
virtual void HandlePacket(const DisconnectPacket* packet) {}
virtual void HandlePacket(const KeepAlivePacket* packet) {}
virtual void HandlePacket(const PlayerDeathPacket* packet) {}
virtual void HandlePacket(const PlayerJoinPacket* packet) {}
virtual void HandlePacket(const PlayerLeavePacket* packet) {}
virtual void HandlePacket(const PlayerListPacket* packet) {}
virtual void HandlePacket(const PlayerLoginPacket* packet) {}
virtual void HandlePacket(const PlayerPositionAndRotationPacket* packet) {}
virtual void HandlePacket(const PlayerShootPacket* packet) {}
virtual void HandlePacket(const PlayerStatsPacket* packet) {}
virtual void HandlePacket(const ServerConfigPacket* packet) {}
virtual void HandlePacket(const ServerTpsPacket* packet) {}
virtual void HandlePacket(const UpdateGameStatePacket* packet) {}
virtual void HandlePacket(const UpdateHealthPacket* packet) {}
virtual void HandlePacket(const ChatPacket& packet) {}
virtual void HandlePacket(const ConnexionInfoPacket& packet) {}
virtual void HandlePacket(const DisconnectPacket& packet) {}
virtual void HandlePacket(const KeepAlivePacket& packet) {}
virtual void HandlePacket(const PlayerDeathPacket& packet) {}
virtual void HandlePacket(const PlayerJoinPacket& packet) {}
virtual void HandlePacket(const PlayerLeavePacket& packet) {}
virtual void HandlePacket(const PlayerListPacket& packet) {}
virtual void HandlePacket(const PlayerLoginPacket& packet) {}
virtual void HandlePacket(const PlayerPositionAndRotationPacket& packet) {}
virtual void HandlePacket(const PlayerShootPacket& packet) {}
virtual void HandlePacket(const PlayerStatsPacket& packet) {}
virtual void HandlePacket(const ServerConfigPacket& packet) {}
virtual void HandlePacket(const ServerTpsPacket& packet) {}
virtual void HandlePacket(const UpdateGameStatePacket& packet) {}
virtual void HandlePacket(const UpdateHealthPacket& packet) {}
};
} // namespace protocol

View File

@@ -100,5 +100,22 @@ class Packet {
}
};
/**
* \class ConcretePacket
* \brief A concrete instance of a Packet
*/
template <typename PacketDerived>
class ConcretePacket : public Packet {
public:
ConcretePacket() {}
virtual ~ConcretePacket() {}
virtual DataBuffer Serialize(bool packetID = true) const = 0;
virtual void Deserialize(DataBuffer& data) = 0;
virtual void Dispatch(PacketHandler* handler) const;
virtual PacketType GetType() const = 0;
};
} // namespace protocol
} // namespace blitz

View File

@@ -41,7 +41,7 @@ typedef std::vector<ColoredPart> ColoredText;
* |--------------------|-------------------|-------------------------------|
* | m_Message | ColoredText | The message sent in the chat |
*/
class ChatPacket : public Packet {
class ChatPacket : public ConcretePacket<ChatPacket> {
private:
ColoredText m_Message;
@@ -64,7 +64,6 @@ class ChatPacket : public Packet {
virtual DataBuffer Serialize(bool packetID = true) const;
virtual void Deserialize(DataBuffer& data);
virtual void Dispatch(PacketHandler* handler) const;
/**
* \brief Get the message.

View File

@@ -22,7 +22,7 @@ namespace protocol {
* |--------------------|-------------------|-------------------------------|
* | m_ConnectionID | std::uint8_t | The connection ID |
*/
class ConnexionInfoPacket : public Packet {
class ConnexionInfoPacket : public ConcretePacket<ConnexionInfoPacket> {
private:
std::uint8_t m_ConnectionID;
@@ -40,7 +40,6 @@ class ConnexionInfoPacket : public Packet {
virtual DataBuffer Serialize(bool packetID = true) const;
virtual void Deserialize(DataBuffer& data);
virtual void Dispatch(PacketHandler* handler) const;
/**
* \brief Get the connection ID.

View File

@@ -22,7 +22,7 @@ namespace protocol {
* |--------------------|-------------------|-------------------------------|
* | m_Reason | std::string | The reason for disconnection |
*/
class DisconnectPacket : public Packet {
class DisconnectPacket : public ConcretePacket<DisconnectPacket> {
private:
std::string m_Reason; // only when sent from server
public:
@@ -39,7 +39,6 @@ class DisconnectPacket : public Packet {
virtual DataBuffer Serialize(bool packetID = true) const;
virtual void Deserialize(DataBuffer& data);
virtual void Dispatch(PacketHandler* handler) const;
/**
* \brief Get the reason for disconnection.

View File

@@ -25,7 +25,7 @@ namespace protocol {
* | Keep Alive ID | VarInt | The server generates a random ID, the client must respond with the same |
*
*/
class KeepAlivePacket : public Packet {
class KeepAlivePacket : public ConcretePacket<KeepAlivePacket> {
private:
VarInt m_AliveID;
@@ -36,7 +36,6 @@ class KeepAlivePacket : public Packet {
virtual DataBuffer Serialize(bool packetID = true) const;
virtual void Deserialize(DataBuffer& data);
virtual void Dispatch(PacketHandler* handler) const;
/**
* \brief Getter of the alive ID

View File

@@ -23,7 +23,7 @@ namespace protocol {
* |--------------------|-------------------|-------------------------------|
* | m_PlayerID | PlayerID |The ID of the player that died |
*/
class PlayerDeathPacket : public Packet {
class PlayerDeathPacket : public ConcretePacket<PlayerDeathPacket> {
private:
game::PlayerID m_PlayerID;
@@ -41,7 +41,6 @@ class PlayerDeathPacket : public Packet {
virtual DataBuffer Serialize(bool packetID = true) const;
virtual void Deserialize(DataBuffer& data);
virtual void Dispatch(PacketHandler* handler) const;
/**
* \brief Get the ID of the player that died.

View File

@@ -25,7 +25,7 @@ namespace protocol {
* | Player Name | std::string | Name of the player who joined |
*
*/
class PlayerJoinPacket : public Packet {
class PlayerJoinPacket : public ConcretePacket<PlayerJoinPacket> {
private:
game::PlayerID m_PlayerID;
std::string m_PlayerName;
@@ -37,7 +37,6 @@ class PlayerJoinPacket : public Packet {
virtual DataBuffer Serialize(bool packetID = true) const;
virtual void Deserialize(DataBuffer& data);
virtual void Dispatch(PacketHandler* handler) const;
/**
* \brief Getter of the player id

View File

@@ -23,7 +23,7 @@ namespace protocol {
* |--------------------|-------------------|-------------------------------|
* | m_PlayerID | PlayerID |The ID of the player that left |
*/
class PlayerLeavePacket : public Packet {
class PlayerLeavePacket : public ConcretePacket<PlayerLeavePacket> {
private:
game::PlayerID m_PlayerID;
@@ -41,7 +41,6 @@ class PlayerLeavePacket : public Packet {
virtual DataBuffer Serialize(bool packetID = true) const;
virtual void Deserialize(DataBuffer& data);
virtual void Dispatch(PacketHandler* handler) const;
/**
* \brief Get the ID of the player that left.

View File

@@ -27,7 +27,7 @@ typedef std::map<std::uint8_t, PlayerInfo> PlayerList;
* \brief Packet for sending the list of players.
* \todo PACKET STRUCTURE
*/
class PlayerListPacket : public Packet {
class PlayerListPacket : public ConcretePacket<PlayerListPacket> {
private:
PlayerList m_Players;
@@ -45,8 +45,6 @@ class PlayerListPacket : public Packet {
virtual DataBuffer Serialize(bool packetID = true) const;
virtual void Deserialize(DataBuffer& data);
virtual void Dispatch(PacketHandler* handler) const;
/**
* \brief Get the list of players.

View File

@@ -22,7 +22,7 @@ namespace protocol {
* |--------------------|-------------------|----------------------------------|
* | Player Name | std::string | Name of the player that logged in|
*/
class PlayerLoginPacket : public Packet {
class PlayerLoginPacket : public ConcretePacket<PlayerLoginPacket> {
private:
std::string m_PlayerName;
@@ -40,7 +40,6 @@ class PlayerLoginPacket : public Packet {
virtual DataBuffer Serialize(bool packetID = true) const;
virtual void Deserialize(DataBuffer& data);
virtual void Dispatch(PacketHandler* handler) const;
/**
* \brief Get the name of the player that logged in.

View File

@@ -27,7 +27,7 @@ namespace protocol {
* | Yaw | float | Yaw of the player |
* | Pitch | float | Pitch of the player |
*/
class PlayerPositionAndRotationPacket : public Packet {
class PlayerPositionAndRotationPacket : public ConcretePacket<PlayerPositionAndRotationPacket> {
private:
game::PlayerID m_Player; // only used when sent to client
Vec3f m_Position;
@@ -51,7 +51,6 @@ class PlayerPositionAndRotationPacket : public Packet {
virtual DataBuffer Serialize(bool packetID = true) const;
virtual void Deserialize(DataBuffer& data);
virtual void Dispatch(PacketHandler* handler) const;
/**
* \brief Get the position of the player.

View File

@@ -26,7 +26,7 @@ namespace protocol {
* | Yaw | float | Yaw of the player |
* | Pitch | float | Pitch of the player |
*/
class PlayerShootPacket : public Packet {
class PlayerShootPacket : public ConcretePacket<PlayerShootPacket> {
private:
game::PlayerID m_Player; // only used when sent to client
Vec3f m_Position;
@@ -50,7 +50,6 @@ class PlayerShootPacket : public Packet {
virtual DataBuffer Serialize(bool packetID = true) const;
virtual void Deserialize(DataBuffer& data);
virtual void Dispatch(PacketHandler* handler) const;
/**
* \brief Get the position of the player.

View File

@@ -25,7 +25,7 @@ namespace protocol {
* | Player ID | PlayerID | Id of the player |
* | Player Stats | PlayerStats | Stats of the player |
*/
class PlayerStatsPacket : public Packet {
class PlayerStatsPacket : public ConcretePacket<PlayerStatsPacket> {
private:
game::PlayerID m_PlayerID;
game::PlayerStats m_PlayerStats;
@@ -45,7 +45,6 @@ class PlayerStatsPacket : public Packet {
virtual DataBuffer Serialize(bool packetID = true) const;
virtual void Deserialize(DataBuffer& data);
virtual void Dispatch(PacketHandler* handler) const;
/**
* \brief Getter of the player id

View File

@@ -23,7 +23,7 @@ namespace protocol {
* |--------------------|-------------------|-------------------------------|
* | Game Config | GameConfig | The game configuration |
*/
class ServerConfigPacket : public Packet {
class ServerConfigPacket : public ConcretePacket<ServerConfigPacket> {
private:
game::GameConfig m_GameConfig;
@@ -41,7 +41,6 @@ class ServerConfigPacket : public Packet {
virtual DataBuffer Serialize(bool packetID = true) const;
virtual void Deserialize(DataBuffer& data);
virtual void Dispatch(PacketHandler* handler) const;
/**
* \brief Getter of the game configuration

View File

@@ -24,7 +24,7 @@ namespace protocol {
* | Mspt | float | Server MSPT |
* | PacketSendTime | uint64_t | Time the packet was sent |
*/
class ServerTpsPacket : public Packet {
class ServerTpsPacket : public ConcretePacket<ServerTpsPacket> {
private:
float m_TPS;
float m_MSPT;
@@ -45,7 +45,6 @@ class ServerTpsPacket : public Packet {
virtual DataBuffer Serialize(bool packetID = true) const;
virtual void Deserialize(DataBuffer& data);
virtual void Dispatch(PacketHandler* handler) const;
/**
* \brief Get the server TPS.

View File

@@ -24,7 +24,7 @@ namespace protocol {
* | Game State | GameState | The new game state |
* | Time Remaining | std::uint64_t | The time remaining in the current game state |
*/
class UpdateGameStatePacket : public Packet {
class UpdateGameStatePacket : public ConcretePacket<UpdateGameStatePacket> {
private:
game::GameState m_GameState;
std::uint64_t m_TimeRemaining;
@@ -45,7 +45,6 @@ class UpdateGameStatePacket : public Packet {
virtual DataBuffer Serialize(bool packetID = true) const;
virtual void Deserialize(DataBuffer& data);
virtual void Dispatch(PacketHandler* handler) const;
/**
* \brief Get the new game state.

View File

@@ -22,7 +22,7 @@ namespace protocol {
* |--------------------|-------------------|-------------------------------|
* | m_NewHealth | float | The new health value |
*/
class UpdateHealthPacket : public Packet {
class UpdateHealthPacket : public ConcretePacket<UpdateHealthPacket> {
private:
float m_NewHealth;
@@ -40,7 +40,6 @@ class UpdateHealthPacket : public Packet {
virtual DataBuffer Serialize(bool packetID = true) const;
virtual void Deserialize(DataBuffer& data);
virtual void Dispatch(PacketHandler* handler) const;
/**
* \brief Get the new health value.

View File

@@ -0,0 +1,81 @@
#pragma once
#include "blitz/misc/ObjectNotifier.h"
#include "blitz/misc/Time.h"
#include "blitz/protocol/packets/ChatPacket.h"
#include "client/Listeners.h"
#include <memory>
namespace blitz {
namespace game {
class Player;
} // namespace game
namespace client {
class ClientConnexion;
class ClientGame;
static const int PlayerUpdatePosRate = 50;
/**
* \class BaseClient
* \brief Minimal client which connects to a server
*/
class BaseClient : public utils::ObjectNotifier<ClientListener> {
private:
utils::Timer m_UpdatePosTimer{PlayerUpdatePosRate};
std::unique_ptr<ClientConnexion> m_Connexion;
std::unique_ptr<ClientGame> m_Game;
public:
BaseClient();
virtual ~BaseClient();
/**
* \brief Should be called every frame
*/
virtual void Update();
bool JoinGame(const std::string& pseudo, const std::string& address, std::uint16_t port);
void Disconnect();
void SendChatText(const std::string& text);
void SendPlayerPosAndLook(const Vec3f& position, float yaw, float pitch);
/**
* \brief Sends the protocol::Packet over the network to the remote
* \param packet The protocol::Packet to send
*/
void SendPacket(const protocol::Packet* packet);
bool IsConnected();
game::PlayerID GetPlayerID() const;
client::ClientGame* GetGame() {
return m_Game.get();
}
/**
* \brief Get a player by its identifier
* \param id The identifier of the player
* \return The player if found, nullptr otherwise
*/
game::Player* GetPlayerById(game::PlayerID id);
/**
* \brief Get a player by its identifier (const version)
* \param id The identifier of the player
* \return The player if found, nullptr otherwise
*/
const game::Player* GetPlayerById(game::PlayerID id) const;
private:
void UpdatePosition(std::uint64_t delta);
};
} // namespace client
} // namespace blitz

View File

@@ -1,9 +1,6 @@
#pragma once
#include "blitz/common/Defines.h"
#include "blitz/misc/ObjectNotifier.h"
#include "blitz/misc/Time.h"
#include "blitz/protocol/packets/ChatPacket.h"
#include "client/BaseClient.h"
#include "client/Listeners.h"
#include "client/config/BlitzConfig.h"
#include <cstdint>
@@ -12,51 +9,29 @@
namespace blitz {
static const int PlayerUpdatePosRate = 50;
namespace server {
class Server;
} // namespace server
namespace client {
class ClientConnexion;
class ClientGame;
// Singleton
class Client : public utils::ObjectNotifier<client::ClientListener>, public client::PlayerInputListener {
class Client : public BaseClient, public PlayerInputListener, public ClientListener {
private:
std::unique_ptr<server::Server> m_Server;
std::unique_ptr<client::ClientConnexion> m_Connexion;
std::unique_ptr<client::ClientGame> m_Game;
utils::Timer m_UpdatePosTimer{PlayerUpdatePosRate};
BlitzConfig m_Config;
public:
Client();
virtual ~Client();
void Update();
virtual void Update() override;
bool IsConnected();
bool JoinGame(const std::string& pseudo, const std::string& address, std::uint16_t port);
bool CreateGame(std::uint16_t port, const std::string& pseudo);
void Disconnect();
void SendChatText(const std::string& text);
void ChatTextReceived(const protocol::ColoredText& text);
void SendPlayerPosAndLook(const Vec3f& position, float yaw, float pitch);
virtual void OnLocalPlayerShoot(const Vec3f& position, float yaw, float pitch) override;
game::PlayerID GetPlayerID() const;
client::ClientGame* GetGame() {
return m_Game.get();
}
virtual void OnGameLeave() override;
BlitzConfig* GetConfig() {
return &m_Config;
@@ -69,11 +44,6 @@ class Client : public utils::ObjectNotifier<client::ClientListener>, public clie
}
void UpdateServerConfig();
private:
void Reset();
void UpdatePosition(std::uint64_t delta);
};
} // namespace client

View File

@@ -6,22 +6,22 @@
namespace blitz {
namespace client {
class Client;
class BaseClient;
class ClientConnexion : public network::Connexion {
private:
Client* m_Client;
BaseClient& m_Client;
std::string m_PlayerName;
game::PlayerID m_PlayerID;
public:
ClientConnexion(Client* client);
ClientConnexion(BaseClient& client);
virtual ~ClientConnexion();
virtual void HandlePacket(const protocol::DisconnectPacket* packet) override;
virtual void HandlePacket(const protocol::KeepAlivePacket* packet) override;
virtual void HandlePacket(const protocol::ChatPacket* packet) override;
virtual void HandlePacket(const protocol::ConnexionInfoPacket* packet) override;
virtual void HandlePacket(const protocol::DisconnectPacket& packet) override;
virtual void HandlePacket(const protocol::KeepAlivePacket& packet) override;
virtual void HandlePacket(const protocol::ChatPacket& packet) override;
virtual void HandlePacket(const protocol::ConnexionInfoPacket& packet) override;
bool Connect(const std::string& pseudo, const std::string& address, std::uint16_t port);

View File

@@ -1,5 +1,6 @@
#pragma once
#include <memory>
#include "blitz/common/DataBuffer.h"
#include "blitz/common/NonCopyable.h"
#include "blitz/maths/Vector.h"
@@ -21,5 +22,7 @@ class AudioBuffer : private NonCopyable {
}
};
typedef std::shared_ptr<AudioBuffer> AudioBufferPtr;
} // namespace audio
} // namespace blitz

View File

@@ -3,13 +3,10 @@
#include "blitz/common/NonCopyable.h"
#include "blitz/maths/Vector.h"
#include "client/audio/AudioBuffer.h"
#include <memory>
namespace blitz {
namespace audio {
typedef std::shared_ptr<AudioBuffer> AudioBufferPtr;
class AudioSource : NonCopyable {
private:
unsigned int m_ID;

View File

@@ -8,29 +8,29 @@
namespace blitz {
namespace client {
class Client;
class BaseClient;
class ClientGame : public game::Game, public protocol::PacketHandler {
private:
Client* m_Client;
BaseClient& m_Client;
game::LeaderBoard m_LeaderBoard;
public:
ClientGame(Client* client, protocol::PacketDispatcher* dispatcher);
ClientGame(BaseClient& client, protocol::PacketDispatcher& dispatcher);
virtual ~ClientGame();
void Tick(std::uint64_t delta) override;
virtual void HandlePacket(const protocol::PlayerDeathPacket* packet) override;
virtual void HandlePacket(const protocol::PlayerJoinPacket* packet) override;
virtual void HandlePacket(const protocol::PlayerLeavePacket* packet) override;
virtual void HandlePacket(const protocol::PlayerListPacket* packet) override;
virtual void HandlePacket(const protocol::PlayerPositionAndRotationPacket* packet) override;
virtual void HandlePacket(const protocol::PlayerShootPacket* packet) override;
virtual void HandlePacket(const protocol::UpdateHealthPacket* packet) override;
virtual void HandlePacket(const protocol::PlayerStatsPacket* packet) override;
virtual void HandlePacket(const protocol::UpdateGameStatePacket* packet) override;
virtual void HandlePacket(const protocol::ServerConfigPacket* packet) override;
virtual void HandlePacket(const protocol::PlayerDeathPacket& packet) override;
virtual void HandlePacket(const protocol::PlayerJoinPacket& packet) override;
virtual void HandlePacket(const protocol::PlayerLeavePacket& packet) override;
virtual void HandlePacket(const protocol::PlayerListPacket& packet) override;
virtual void HandlePacket(const protocol::PlayerPositionAndRotationPacket& packet) override;
virtual void HandlePacket(const protocol::PlayerShootPacket& packet) override;
virtual void HandlePacket(const protocol::UpdateHealthPacket& packet) override;
virtual void HandlePacket(const protocol::PlayerStatsPacket& packet) override;
virtual void HandlePacket(const protocol::UpdateGameStatePacket& packet) override;
virtual void HandlePacket(const protocol::ServerConfigPacket& packet) override;
virtual void AddPlayer(game::PlayerID player, const std::string& name) override;
virtual void RemovePlayer(game::PlayerID player) override;

View File

@@ -39,7 +39,7 @@ struct KeepAlive {
*/
class ServerConnexion : public network::Connexion {
private:
Server* m_Server;
Server& m_Server;
std::uint8_t m_ID;
KeepAlive m_KeepAlive;
game::Player* m_Player;
@@ -52,7 +52,7 @@ class ServerConnexion : public network::Connexion {
* \param socket The socket
* \param id The ID of the connexion
*/
ServerConnexion(Server* server, network::TCPSocket& socket, std::uint8_t id);
ServerConnexion(Server& server, network::TCPSocket& socket, std::uint8_t id);
/**
* \brief Move constructor
*/
@@ -72,12 +72,12 @@ class ServerConnexion : public network::Connexion {
return m_ID;
}
virtual void HandlePacket(const protocol::PlayerLoginPacket* packet) override;
virtual void HandlePacket(const protocol::KeepAlivePacket* packet) override;
virtual void HandlePacket(const protocol::DisconnectPacket* packet) override;
virtual void HandlePacket(const protocol::ChatPacket* packet) override;
virtual void HandlePacket(const protocol::PlayerPositionAndRotationPacket* packet) override;
virtual void HandlePacket(const protocol::PlayerShootPacket* packet) override;
virtual void HandlePacket(const protocol::PlayerLoginPacket& packet) override;
virtual void HandlePacket(const protocol::KeepAlivePacket& packet) override;
virtual void HandlePacket(const protocol::DisconnectPacket& packet) override;
virtual void HandlePacket(const protocol::ChatPacket& packet) override;
virtual void HandlePacket(const protocol::PlayerPositionAndRotationPacket& packet) override;
virtual void HandlePacket(const protocol::PlayerShootPacket& packet) override;
virtual bool UpdateSocket() override;

View File

@@ -31,7 +31,7 @@ class Server;
*/
class ServerGame : public game::Game {
private:
Server* m_Server;
Server& m_Server;
utils::Timer m_PositionTimer;
ServerDuration m_ServerDuration;
@@ -40,7 +40,7 @@ class ServerGame : public game::Game {
* \brief Constructor
* \param server The server
*/
ServerGame(Server* server);
ServerGame(Server& server);
virtual ~ServerGame();
/**

View File

@@ -9,9 +9,8 @@ void LeaderBoard::AddPlayer(Player* player) {
}
void LeaderBoard::RemovePlayer(PlayerID player) {
auto it = std::find_if(m_Players.begin(), m_Players.end(), [player](game::Player* p) { return p->GetID() == player; });
if (it != m_Players.end())
m_Players.erase(it);
m_Players.erase(std::remove_if(m_Players.begin(), m_Players.end(), [player](game::Player* p) { return p->GetID() == player; }),
m_Players.end());
}
void LeaderBoard::Update() {

View File

@@ -10,11 +10,11 @@
namespace blitz {
namespace network {
Connexion::Connexion(Connexion&& move) : protocol::PacketHandler(&m_Dispatcher), m_Socket(std::move(move.m_Socket)) {}
Connexion::Connexion(Connexion&& move) : protocol::PacketHandler(m_Dispatcher), m_Socket(std::move(move.m_Socket)) {}
Connexion::Connexion(protocol::PacketDispatcher* dispatcher) : protocol::PacketHandler(dispatcher) {}
Connexion::Connexion(protocol::PacketDispatcher& dispatcher) : protocol::PacketHandler(dispatcher) {}
Connexion::Connexion(protocol::PacketDispatcher* dispatcher, TCPSocket& socket) :
Connexion::Connexion(protocol::PacketDispatcher& dispatcher, TCPSocket& socket) :
protocol::PacketHandler(dispatcher), m_Socket(std::move(socket)) {}
bool Connexion::UpdateSocket() {
@@ -39,7 +39,7 @@ bool Connexion::UpdateSocket() {
decompressed >> packetType;
const protocol::PacketPtr packet = protocol::PacketFactory::CreatePacket(packetType, decompressed);
GetDispatcher()->Dispatch(packet.get());
GetDispatcher().Dispatch(*packet.get());
}
return true;
}

View File

@@ -3,36 +3,31 @@
namespace blitz {
namespace protocol {
void PacketDispatcher::RegisterHandler(PacketType type, PacketHandler* handler) {
auto found = std::find(m_Handlers[type].begin(), m_Handlers[type].end(), handler);
void PacketDispatcher::RegisterHandler(PacketType type, PacketHandler& handler) {
auto found = std::find(m_Handlers[type].begin(), m_Handlers[type].end(), &handler);
if (found == m_Handlers[type].end())
m_Handlers[type].push_back(handler);
m_Handlers[type].push_back(&handler);
}
void PacketDispatcher::UnregisterHandler(PacketType type, PacketHandler* handler) {
auto found = std::find(m_Handlers[type].begin(), m_Handlers[type].end(), handler);
if (found != m_Handlers[type].end())
m_Handlers[type].erase(found);
void PacketDispatcher::UnregisterHandler(PacketType type, PacketHandler& handler) {
m_Handlers[type].erase(std::remove(m_Handlers[type].begin(), m_Handlers[type].end(), &handler), m_Handlers[type].end());
}
void PacketDispatcher::UnregisterHandler(PacketHandler* handler) {
void PacketDispatcher::UnregisterHandler(PacketHandler& handler) {
for (auto& pair : m_Handlers) {
if (pair.second.empty())
continue;
PacketType type = pair.first;
m_Handlers[type].erase(std::remove(m_Handlers[type].begin(), m_Handlers[type].end(), handler), m_Handlers[type].end());
m_Handlers[type].erase(std::remove(m_Handlers[type].begin(), m_Handlers[type].end(), &handler), m_Handlers[type].end());
}
}
void PacketDispatcher::Dispatch(const Packet* packet) {
if (!packet)
return;
PacketType type = packet->GetType();
void PacketDispatcher::Dispatch(const Packet& packet) {
PacketType type = packet.GetType();
for (PacketHandler* handler : m_Handlers[type])
packet->Dispatch(handler);
packet.Dispatch(handler);
}
} // namespace protocol

View File

@@ -11,7 +11,7 @@ namespace PacketFactory {
typedef std::function<PacketPtr()> PacketCreator;
static std::array<PacketCreator, static_cast<std::size_t>(PacketType::PACKET_COUNT)> Packets = {
static const std::array<PacketCreator, static_cast<std::size_t>(PacketType::PACKET_COUNT)> Packets = {
[]() -> PacketPtr { return std::make_unique<PlayerLoginPacket>(); },
[]() -> PacketPtr { return std::make_unique<UpdateHealthPacket>(); },
[]() -> PacketPtr { return std::make_unique<ConnexionInfoPacket>(); },

View File

@@ -1,11 +1,6 @@
#include "blitz/protocol/PacketHandler.h"
#include "blitz/protocol/Packets.h"
#define REGISTER_DISPATCH_CLASS(className) \
void className::Dispatch(PacketHandler* handler) const { \
handler->HandlePacket(this); \
}
namespace blitz {
namespace protocol {
@@ -14,22 +9,28 @@ void Packet::WritePacketID(DataBuffer& data, bool packetID) const {
data << GetID();
}
REGISTER_DISPATCH_CLASS(PlayerLoginPacket)
REGISTER_DISPATCH_CLASS(KeepAlivePacket)
REGISTER_DISPATCH_CLASS(PlayerListPacket)
REGISTER_DISPATCH_CLASS(PlayerDeathPacket);
REGISTER_DISPATCH_CLASS(PlayerJoinPacket)
REGISTER_DISPATCH_CLASS(PlayerLeavePacket)
REGISTER_DISPATCH_CLASS(ConnexionInfoPacket)
REGISTER_DISPATCH_CLASS(DisconnectPacket)
REGISTER_DISPATCH_CLASS(ServerTpsPacket)
REGISTER_DISPATCH_CLASS(ChatPacket)
REGISTER_DISPATCH_CLASS(PlayerPositionAndRotationPacket)
REGISTER_DISPATCH_CLASS(PlayerShootPacket);
REGISTER_DISPATCH_CLASS(UpdateHealthPacket);
REGISTER_DISPATCH_CLASS(PlayerStatsPacket);
REGISTER_DISPATCH_CLASS(UpdateGameStatePacket);
REGISTER_DISPATCH_CLASS(ServerConfigPacket);
template <typename PacketDerived>
void ConcretePacket<PacketDerived>::Dispatch(PacketHandler* handler) const {
static_assert(std::is_base_of<ConcretePacket, PacketDerived>::value, "PacketDerived must be derived from the ConcretePacket class");
handler->HandlePacket(dynamic_cast<const PacketDerived&>(*this));
}
template class ConcretePacket<ChatPacket>;
template class ConcretePacket<ConnexionInfoPacket>;
template class ConcretePacket<DisconnectPacket>;
template class ConcretePacket<KeepAlivePacket>;
template class ConcretePacket<PlayerDeathPacket>;
template class ConcretePacket<PlayerJoinPacket>;
template class ConcretePacket<PlayerLeavePacket>;
template class ConcretePacket<PlayerListPacket>;
template class ConcretePacket<PlayerLoginPacket>;
template class ConcretePacket<PlayerPositionAndRotationPacket>;
template class ConcretePacket<PlayerShootPacket>;
template class ConcretePacket<PlayerStatsPacket>;
template class ConcretePacket<ServerConfigPacket>;
template class ConcretePacket<ServerTpsPacket>;
template class ConcretePacket<UpdateGameStatePacket>;
template class ConcretePacket<UpdateHealthPacket>;
} // namespace protocol
} // namespace blitz

91
src/client/BaseClient.cpp Normal file
View File

@@ -0,0 +1,91 @@
#include "client/BaseClient.h"
#include "blitz/misc/Log.h"
#include "blitz/protocol/packets/DisconnectPacket.h"
#include "blitz/protocol/packets/PlayerPositionAndRotationPacket.h"
#include "client/ClientConnexion.h"
#include "client/game/ClientGame.h"
namespace blitz {
namespace client {
BaseClient::BaseClient() :
m_Connexion(std::make_unique<ClientConnexion>(*this)), m_Game(std::make_unique<ClientGame>(*this, m_Connexion->GetDispatcher())) {}
BaseClient::~BaseClient() {
Disconnect();
}
void BaseClient::Update() {
if (m_Connexion->GetSocketStatus() == network::TCPSocket::Status::Disconnected)
return;
if (m_Connexion->UpdateSocket()) {
static std::uint64_t lastTime = utils::GetTime();
UpdatePosition(utils::GetTime() - lastTime);
m_Game->Tick(utils::GetTime() - lastTime);
lastTime = utils::GetTime();
} else {
Disconnect();
}
}
bool BaseClient::JoinGame(const std::string& pseudo, const std::string& address, std::uint16_t port) {
return m_Connexion->Connect(pseudo, address, port);
}
void BaseClient::Disconnect() {
if (m_Connexion->GetSocketStatus() == network::TCPSocket::Status::Disconnected)
return;
protocol::DisconnectPacket packet("Client wants to leave !");
m_Connexion->SendPacket(&packet);
utils::LOGD("[BaseClient] Disconnected !");
m_Connexion->CloseConnection();
// Clear previous game
m_Game.reset(nullptr);
m_Game = std::make_unique<client::ClientGame>(*this, m_Connexion->GetDispatcher());
NotifyListeners(&ClientListener::OnGameLeave);
}
void BaseClient::SendChatText(const std::string& text) {
protocol::ChatPacket packet(text);
m_Connexion->SendPacket(&packet);
}
void BaseClient::SendPlayerPosAndLook(const Vec3f& position, float yaw, float pitch) {
protocol::PlayerPositionAndRotationPacket packet(position, yaw, pitch);
m_Connexion->SendPacket(&packet);
}
game::PlayerID BaseClient::GetPlayerID() const {
return m_Connexion->GetPlayerID();
}
bool BaseClient::IsConnected() {
return m_Connexion->GetSocketStatus() == network::TCPSocket::Status::Connected;
}
void BaseClient::UpdatePosition(std::uint64_t delta) {
// send position every tick (50 ms)
if (m_UpdatePosTimer.Update(delta)) {
game::Player* player = m_Game->GetPlayerById(m_Connexion->GetPlayerID());
if (player)
SendPlayerPosAndLook(player->GetPosition(), player->GetYaw(), player->GetPitch());
}
}
void BaseClient::SendPacket(const protocol::Packet* packet) {
m_Connexion->SendPacket(packet);
}
} // namespace client
} // namespace blitz

View File

@@ -13,33 +13,16 @@
namespace blitz {
namespace client {
Client::Client() :
m_Server(std::make_unique<server::Server>()),
m_Connexion(std::make_unique<ClientConnexion>(this)),
m_Game(std::make_unique<ClientGame>(this, m_Connexion->GetDispatcher())) {}
Client::Client() : BaseClient(), m_Server(std::make_unique<server::Server>()) {
BindListener(this);
}
Client::~Client() {
Disconnect();
}
void Client::Update() {
if (m_Connexion->GetSocketStatus() == network::TCPSocket::Status::Disconnected)
return;
if (m_Connexion->UpdateSocket()) {
static std::uint64_t lastTime = utils::GetTime();
UpdatePosition(utils::GetTime() - lastTime);
m_Game->Tick(utils::GetTime() - lastTime);
lastTime = utils::GetTime();
} else {
Disconnect();
}
}
bool Client::JoinGame(const std::string& pseudo, const std::string& address, std::uint16_t port) {
return m_Connexion->Connect(pseudo, address, port);
BaseClient::Update();
}
void Client::UpdateServerConfig() {
@@ -62,78 +45,20 @@ bool Client::CreateGame(std::uint16_t port, const std::string& pseudo) {
return true;
}
void Client::Disconnect() {
if (m_Connexion->GetSocketStatus() == network::TCPSocket::Status::Disconnected)
return;
protocol::DisconnectPacket packet("Client wants to leave !");
m_Connexion->SendPacket(&packet);
utils::LOGD("[Client] Disconnected !");
if (m_Server) {
m_Server->Stop();
}
m_Connexion->CloseConnection();
NotifyListeners(&client::ClientListener::OnGameLeave);
Reset();
}
void Client::Reset() {
utils::LOGD("[Client] Reset !");
// Reset server
void Client::OnGameLeave() {
// Clear previous server
m_Server.reset(nullptr);
m_Server = std::make_unique<server::Server>();
// Reset game
m_Game.reset(nullptr);
m_Game = std::make_unique<client::ClientGame>(this, m_Connexion->GetDispatcher());
}
void Client::SendChatText(const std::string& text) {
protocol::ChatPacket packet(text);
m_Connexion->SendPacket(&packet);
}
void Client::ChatTextReceived(const protocol::ColoredText& text) {
NotifyListeners(&client::ClientListener::OnTextChatReceived, text);
}
void Client::SendPlayerPosAndLook(const Vec3f& position, float yaw, float pitch) {
protocol::PlayerPositionAndRotationPacket packet(position, yaw, pitch);
m_Connexion->SendPacket(&packet);
}
void Client::OnLocalPlayerShoot(const Vec3f& position, float yaw, float pitch) {
protocol::PlayerShootPacket packet(position, yaw, pitch);
m_Connexion->SendPacket(&packet);
}
game::PlayerID Client::GetPlayerID() const {
return m_Connexion->GetPlayerID();
}
bool Client::IsConnected() {
return m_Connexion->GetSocketStatus() == network::TCPSocket::Status::Connected;
SendPacket(&packet);
}
bool Client::IsAdmin() const {
return m_Server->IsRunning();
}
void Client::UpdatePosition(std::uint64_t delta) {
// send position every tick (50 ms)
if (m_UpdatePosTimer.Update(delta)) {
game::Player* player = m_Game->GetPlayerById(m_Connexion->GetPlayerID());
if (player)
SendPlayerPosAndLook(player->GetPosition(), player->GetYaw(), player->GetPitch());
}
}
} // namespace client
} // namespace blitz

View File

@@ -8,7 +8,7 @@
#include "blitz/protocol/packets/DisconnectPacket.h"
#include "blitz/protocol/packets/KeepAlivePacket.h"
#include "blitz/protocol/packets/PlayerLoginPacket.h"
#include "client/Client.h"
#include "client/BaseClient.h"
namespace blitz {
namespace client {
@@ -24,19 +24,19 @@ static std::string PrintColoredText(const protocol::ColoredText& coloredText) {
return text;
}
ClientConnexion::ClientConnexion(Client* client) : network::Connexion(&m_Dispatcher), m_Client(client) {
ClientConnexion::ClientConnexion(BaseClient& client) : network::Connexion(m_Dispatcher), m_Client(client) {
RegisterHandlers();
}
ClientConnexion::~ClientConnexion() {
GetDispatcher()->UnregisterHandler(this);
GetDispatcher().UnregisterHandler(*this);
}
void ClientConnexion::RegisterHandlers() {
GetDispatcher()->RegisterHandler(protocol::PacketType::KeepAlive, this);
GetDispatcher()->RegisterHandler(protocol::PacketType::Disconnect, this);
GetDispatcher()->RegisterHandler(protocol::PacketType::Chat, this);
GetDispatcher()->RegisterHandler(protocol::PacketType::ConnexionInfo, this);
GetDispatcher().RegisterHandler(protocol::PacketType::KeepAlive, *this);
GetDispatcher().RegisterHandler(protocol::PacketType::Disconnect, *this);
GetDispatcher().RegisterHandler(protocol::PacketType::Chat, *this);
GetDispatcher().RegisterHandler(protocol::PacketType::ConnexionInfo, *this);
}
bool ClientConnexion::Connect(const std::string& pseudo, const std::string& address, std::uint16_t port) {
@@ -47,24 +47,24 @@ bool ClientConnexion::Connect(const std::string& pseudo, const std::string& addr
return true;
}
void ClientConnexion::HandlePacket(const protocol::ChatPacket* packet) {
utils::LOG("[Chat] " + PrintColoredText(packet->GetMessage()));
m_Client->ChatTextReceived(packet->GetMessage());
void ClientConnexion::HandlePacket(const protocol::ChatPacket& packet) {
utils::LOG("[Chat] " + PrintColoredText(packet.GetMessage()));
m_Client.NotifyListeners(&ClientListener::OnTextChatReceived, packet.GetMessage());
}
void ClientConnexion::HandlePacket(const protocol::DisconnectPacket* packet) {
utils::LOG("[ClientConnexion] Disconnected ! Reason : " + packet->GetReason());
m_Client->NotifyListeners(&client::ClientListener::OnGameLeave);
m_Client->Disconnect();
void ClientConnexion::HandlePacket(const protocol::DisconnectPacket& packet) {
utils::LOG("[ClientConnexion] Disconnected ! Reason : " + packet.GetReason());
m_Client.NotifyListeners(&ClientListener::OnGameLeave);
m_Client.Disconnect();
}
void ClientConnexion::HandlePacket(const protocol::KeepAlivePacket* packet) {
protocol::KeepAlivePacket response(packet->GetAliveID());
void ClientConnexion::HandlePacket(const protocol::KeepAlivePacket& packet) {
protocol::KeepAlivePacket response(packet.GetAliveID());
SendPacket(&response);
}
void ClientConnexion::HandlePacket(const protocol::ConnexionInfoPacket* packet) {
m_PlayerID = packet->GetConnectionID();
void ClientConnexion::HandlePacket(const protocol::ConnexionInfoPacket& packet) {
m_PlayerID = packet.GetConnectionID();
utils::LOGD("[ClientConnexion] Logging in with pseudo " + m_PlayerName + " ...");
Login(m_PlayerName);
}

View File

@@ -13,18 +13,18 @@
#include "blitz/protocol/packets/ServerConfigPacket.h"
#include "blitz/protocol/packets/UpdateGameStatePacket.h"
#include "blitz/protocol/packets/UpdateHealthPacket.h"
#include "client/Client.h"
#include "client/BaseClient.h"
namespace blitz {
namespace client {
ClientGame::ClientGame(Client* client, protocol::PacketDispatcher* dispatcher) :
ClientGame::ClientGame(BaseClient& client, protocol::PacketDispatcher& dispatcher) :
protocol::PacketHandler(dispatcher), m_Client(client) {
RegisterHandlers();
}
ClientGame::~ClientGame() {
GetDispatcher()->UnregisterHandler(this);
GetDispatcher().UnregisterHandler(*this);
}
void ClientGame::AddPlayer(game::PlayerID player, const std::string& name) {
@@ -37,59 +37,59 @@ void ClientGame::RemovePlayer(game::PlayerID player) {
}
void ClientGame::RegisterHandlers() {
GetDispatcher()->RegisterHandler(protocol::PacketType::PlayerDeath, this);
GetDispatcher()->RegisterHandler(protocol::PacketType::PlayerJoin, this);
GetDispatcher()->RegisterHandler(protocol::PacketType::PlayerLeave, this);
GetDispatcher()->RegisterHandler(protocol::PacketType::PlayerList, this);
GetDispatcher()->RegisterHandler(protocol::PacketType::PlayerPositionAndRotation, this);
GetDispatcher()->RegisterHandler(protocol::PacketType::PlayerShoot, this);
GetDispatcher()->RegisterHandler(protocol::PacketType::PlayerStats, this);
GetDispatcher()->RegisterHandler(protocol::PacketType::UpdateGameState, this);
GetDispatcher()->RegisterHandler(protocol::PacketType::UpdateHealth, this);
GetDispatcher()->RegisterHandler(protocol::PacketType::ServerConfig, this);
GetDispatcher().RegisterHandler(protocol::PacketType::PlayerDeath, *this);
GetDispatcher().RegisterHandler(protocol::PacketType::PlayerJoin, *this);
GetDispatcher().RegisterHandler(protocol::PacketType::PlayerLeave, *this);
GetDispatcher().RegisterHandler(protocol::PacketType::PlayerList, *this);
GetDispatcher().RegisterHandler(protocol::PacketType::PlayerPositionAndRotation, *this);
GetDispatcher().RegisterHandler(protocol::PacketType::PlayerShoot, *this);
GetDispatcher().RegisterHandler(protocol::PacketType::PlayerStats, *this);
GetDispatcher().RegisterHandler(protocol::PacketType::UpdateGameState, *this);
GetDispatcher().RegisterHandler(protocol::PacketType::UpdateHealth, *this);
GetDispatcher().RegisterHandler(protocol::PacketType::ServerConfig, *this);
}
void ClientGame::HandlePacket(const protocol::PlayerDeathPacket* packet) {
NotifyListeners(&game::GameListener::OnPlayerDeath, packet->GetPlayerID());
void ClientGame::HandlePacket(const protocol::PlayerDeathPacket& packet) {
NotifyListeners(&game::GameListener::OnPlayerDeath, packet.GetPlayerID());
}
void ClientGame::HandlePacket(const protocol::PlayerJoinPacket* packet) {
void ClientGame::HandlePacket(const protocol::PlayerJoinPacket& packet) {
if (packet->GetPlayerID() == m_Client->GetPlayerID()) {
m_Client->NotifyListeners(&client::ClientListener::OnGameJoin);
if (packet.GetPlayerID() == m_Client.GetPlayerID()) {
m_Client.NotifyListeners(&client::ClientListener::OnGameJoin);
}
AddPlayer(packet->GetPlayerID(), packet->GetPlayerName());
AddPlayer(packet.GetPlayerID(), packet.GetPlayerName());
// Initialize camera
if (packet->GetPlayerID() == m_Client->GetPlayerID()) {
m_Client->NotifyListeners(&client::ClientListener::OnSpectatorChange, packet->GetPlayerID());
m_Client->NotifyListeners(&client::ClientListener::OnClientPlayerJoin);
if (packet.GetPlayerID() == m_Client.GetPlayerID()) {
m_Client.NotifyListeners(&client::ClientListener::OnSpectatorChange, packet.GetPlayerID());
m_Client.NotifyListeners(&client::ClientListener::OnClientPlayerJoin);
}
}
void ClientGame::HandlePacket(const protocol::PlayerLeavePacket* packet) {
RemovePlayer(packet->GetPlayerID());
void ClientGame::HandlePacket(const protocol::PlayerLeavePacket& packet) {
RemovePlayer(packet.GetPlayerID());
}
void ClientGame::HandlePacket(const protocol::PlayerListPacket* packet) {
for (const auto& [playerID, playerInfo] : packet->GetPlayers()) {
void ClientGame::HandlePacket(const protocol::PlayerListPacket& packet) {
for (const auto& [playerID, playerInfo] : packet.GetPlayers()) {
AddPlayer(playerID, playerInfo.m_Name);
}
}
void ClientGame::HandlePacket(const protocol::PlayerStatsPacket* packet) {
game::Player* player = m_Client->GetGame()->GetPlayerById(packet->GetPlayerID());
void ClientGame::HandlePacket(const protocol::PlayerStatsPacket& packet) {
game::Player* player = m_Client.GetGame()->GetPlayerById(packet.GetPlayerID());
if (!player)
return;
player->GetStats() = packet->GetPlayerStats();
player->GetStats() = packet.GetPlayerStats();
m_LeaderBoard.Update();
}
void ClientGame::HandlePacket(const protocol::UpdateHealthPacket* packet) {
game::Player* player = m_Client->GetGame()->GetPlayerById(m_Client->GetPlayerID());
player->SetHP(packet->GetNewHealth());
void ClientGame::HandlePacket(const protocol::UpdateHealthPacket& packet) {
game::Player* player = m_Client.GetGame()->GetPlayerById(m_Client.GetPlayerID());
player->SetHP(packet.GetNewHealth());
// we are dead
if (player->GetHP() <= 0.0f) {
@@ -98,38 +98,38 @@ void ClientGame::HandlePacket(const protocol::UpdateHealthPacket* packet) {
}
}
void ClientGame::HandlePacket(const protocol::UpdateGameStatePacket* packet) {
Game::UpdateGameState(packet->GetGameState(), packet->GetTimeRemaining());
void ClientGame::HandlePacket(const protocol::UpdateGameStatePacket& packet) {
Game::UpdateGameState(packet.GetGameState(), packet.GetTimeRemaining());
}
void ClientGame::HandlePacket(const protocol::ServerConfigPacket* packet) {
m_Config = packet->GetGameConfig();
m_Client->NotifyListeners(&client::ClientListener::OnGameConfigUpdate);
void ClientGame::HandlePacket(const protocol::ServerConfigPacket& packet) {
m_Config = packet.GetGameConfig();
m_Client.NotifyListeners(&client::ClientListener::OnGameConfigUpdate);
}
void ClientGame::HandlePacket(const protocol::PlayerShootPacket* packet) {
m_Client->NotifyListeners(
&client::ClientListener::OnPlayerShoot, packet->GetPlayer(), packet->GetPosition(), packet->GetYaw(), packet->GetPitch());
void ClientGame::HandlePacket(const protocol::PlayerShootPacket& packet) {
m_Client.NotifyListeners(
&client::ClientListener::OnPlayerShoot, packet.GetPlayer(), packet.GetPosition(), packet.GetYaw(), packet.GetPitch());
}
void ClientGame::HandlePacket(const protocol::PlayerPositionAndRotationPacket* packet) {
if (packet->GetPlayer() == m_Client->GetPlayerID())
void ClientGame::HandlePacket(const protocol::PlayerPositionAndRotationPacket& packet) {
if (packet.GetPlayer() == m_Client.GetPlayerID())
return;
game::Player* player = GetPlayerById(packet->GetPlayer());
game::Player* player = GetPlayerById(packet.GetPlayer());
if (!player)
return;
player->SetVelocity(packet->GetPosition() - player->GetPosition());
player->SetYaw(packet->GetYaw());
player->SetPitch(packet->GetPitch());
player->SetVelocity(packet.GetPosition() - player->GetPosition());
player->SetYaw(packet.GetYaw());
player->SetPitch(packet.GetPitch());
}
void ClientGame::Tick(std::uint64_t delta) {
for (auto& [playerId, player] : GetPlayers()) {
// already handled by PlayerController
if (playerId == m_Client->GetPlayerID())
if (playerId == m_Client.GetPlayerID())
continue;
player.SetPosition(player.GetPosition() + player.GetVelocity() * (static_cast<float>(delta) / 100.0f));
}

View File

@@ -14,7 +14,7 @@
namespace blitz {
namespace server {
Server::Server() : m_TickCounter(SERVER_TPS), m_Game(this), m_ServerRunning(false), m_FreePlayerID(0) {}
Server::Server() : m_TickCounter(SERVER_TPS), m_Game(*this), m_ServerRunning(false), m_FreePlayerID(0) {}
Server::~Server() {
Stop();
@@ -104,7 +104,7 @@ void Server::Accept() {
network::TCPSocket newSocket;
if (m_Listener.Accept(newSocket)) {
game::PlayerID newPlayerID = GetNewPlayerID();
auto con = std::make_unique<ServerConnexion>(this, newSocket, newPlayerID);
auto con = std::make_unique<ServerConnexion>(*this, newSocket, newPlayerID);
m_Connections.insert(ConnexionMap::value_type{newPlayerID, std::move(con)});
m_Connections[newPlayerID]->Init();
newPlayerID++;

View File

@@ -28,8 +28,8 @@ namespace blitz {
namespace server {
ServerConnexion::ServerConnexion(Server* server, network::TCPSocket& socket, std::uint8_t id) :
Connexion::Connexion(&m_Dispatcher, socket), m_Server(server), m_ID(id), m_Player(nullptr) {
ServerConnexion::ServerConnexion(Server& server, network::TCPSocket& socket, std::uint8_t id) :
Connexion::Connexion(m_Dispatcher, socket), m_Server(server), m_ID(id), m_Player(nullptr) {
RegisterHandlers();
}
@@ -39,18 +39,16 @@ ServerConnexion::ServerConnexion(ServerConnexion&& move) :
m_ID(move.m_ID),
m_KeepAlive(move.m_KeepAlive),
m_Player(move.m_Player) {
move.m_Server = nullptr;
RegisterHandlers();
}
void ServerConnexion::RegisterHandlers() {
GetDispatcher()->RegisterHandler(protocol::PacketType::Disconnect, this);
GetDispatcher()->RegisterHandler(protocol::PacketType::KeepAlive, this);
GetDispatcher()->RegisterHandler(protocol::PacketType::PlayerLogin, this);
GetDispatcher()->RegisterHandler(protocol::PacketType::Chat, this);
GetDispatcher()->RegisterHandler(protocol::PacketType::PlayerShoot, this);
GetDispatcher()->RegisterHandler(protocol::PacketType::PlayerPositionAndRotation, this);
GetDispatcher().RegisterHandler(protocol::PacketType::Disconnect, *this);
GetDispatcher().RegisterHandler(protocol::PacketType::KeepAlive, *this);
GetDispatcher().RegisterHandler(protocol::PacketType::PlayerLogin, *this);
GetDispatcher().RegisterHandler(protocol::PacketType::Chat, *this);
GetDispatcher().RegisterHandler(protocol::PacketType::PlayerShoot, *this);
GetDispatcher().RegisterHandler(protocol::PacketType::PlayerPositionAndRotation, *this);
}
bool ServerConnexion::UpdateSocket() {
@@ -93,10 +91,10 @@ void ServerConnexion::InitPlayerChatColor() {
m_ChatColor = protocol::ChatPacket::GetTextColor({red, green, blue});
}
void ServerConnexion::HandlePacket(const protocol::PlayerLoginPacket* packet) {
m_Server->GetGame().AddPlayer(m_ID, packet->GetPlayerName());
void ServerConnexion::HandlePacket(const protocol::PlayerLoginPacket& packet) {
m_Server.GetGame().AddPlayer(m_ID, packet.GetPlayerName());
m_Player = m_Server->GetGame().GetPlayerById(m_ID);
m_Player = m_Server.GetGame().GetPlayerById(m_ID);
SendPlayers();
SendGameState();
@@ -105,40 +103,40 @@ void ServerConnexion::HandlePacket(const protocol::PlayerLoginPacket* packet) {
InitPlayerChatColor();
}
void ServerConnexion::HandlePacket(const protocol::KeepAlivePacket* packet) {
if (packet->GetAliveID() != m_KeepAlive.KeepAliveID)
void ServerConnexion::HandlePacket(const protocol::KeepAlivePacket& packet) {
if (packet.GetAliveID() != m_KeepAlive.KeepAliveID)
return;
m_KeepAlive.RecievedResponse = true;
}
void ServerConnexion::HandlePacket(const protocol::DisconnectPacket* packet) {
void ServerConnexion::HandlePacket(const protocol::DisconnectPacket& packet) {
CloseConnection();
}
void ServerConnexion::HandlePacket(const protocol::ChatPacket* packet) {
void ServerConnexion::HandlePacket(const protocol::ChatPacket& packet) {
if (!m_Player)
return;
m_Server->BroadcastChatMessage(utils::Format("<%s%s%s> %s", m_ChatColor.c_str(), m_Player->GetName().c_str(),
m_Server.BroadcastChatMessage(utils::Format("<%s%s%s> %s", m_ChatColor.c_str(), m_Player->GetName().c_str(),
protocol::ChatPacket::GetTextColor(protocol::WHITE).c_str(),
protocol::ChatPacket::GetColoredTextString(packet->GetMessage()).c_str()));
protocol::ChatPacket::GetColoredTextString(packet.GetMessage()).c_str()));
}
void ServerConnexion::HandlePacket(const protocol::PlayerPositionAndRotationPacket* packet) {
void ServerConnexion::HandlePacket(const protocol::PlayerPositionAndRotationPacket& packet) {
if (!m_Player)
return;
m_Player->SetPosition(packet->GetPosition());
m_Player->SetYaw(packet->GetYaw());
m_Player->SetPitch(packet->GetPitch());
m_Player->SetPosition(packet.GetPosition());
m_Player->SetYaw(packet.GetYaw());
m_Player->SetPitch(packet.GetPitch());
}
void ServerConnexion::HandlePacket(const protocol::PlayerShootPacket* packet) {
protocol::PlayerShootPacket broadcastShoot(packet->GetPosition(), packet->GetYaw(), packet->GetPitch(), m_Player->GetID());
m_Server->BroadcastPacket(&broadcastShoot);
void ServerConnexion::HandlePacket(const protocol::PlayerShootPacket& packet) {
protocol::PlayerShootPacket broadcastShoot(packet.GetPosition(), packet.GetYaw(), packet.GetPitch(), m_Player->GetID());
m_Server.BroadcastPacket(&broadcastShoot);
m_Server->GetGame().ProcessShoot(m_Player->GetID(), packet->GetPosition(), packet->GetYaw(), packet->GetPitch());
m_Server.GetGame().ProcessShoot(m_Player->GetID(), packet.GetPosition(), packet.GetYaw(), packet.GetPitch());
}
void ServerConnexion::Init() {
@@ -147,14 +145,14 @@ void ServerConnexion::Init() {
}
void ServerConnexion::SendGameState() {
protocol::UpdateGameStatePacket packet(m_Server->GetGame().GetGameState(), m_Server->GetGame().GetGameStateRemainingTime());
protocol::UpdateGameStatePacket packet(m_Server.GetGame().GetGameState(), m_Server.GetGame().GetGameStateRemainingTime());
SendPacket(&packet);
}
void ServerConnexion::SendPlayers() {
protocol::PlayerList list;
for (const auto& [playerID, player] : m_Server->GetGame().GetPlayers()) {
for (const auto& [playerID, player] : m_Server.GetGame().GetPlayers()) {
if (playerID == m_ID)
continue;
list.insert({playerID, {player.GetName()}});
@@ -165,7 +163,7 @@ void ServerConnexion::SendPlayers() {
}
void ServerConnexion::SendServerConfig() {
protocol::ServerConfigPacket packet(m_Server->GetGame().GetGameConfig());
protocol::ServerConfigPacket packet(m_Server.GetGame().GetGameConfig());
SendPacket(&packet);
}
@@ -175,12 +173,9 @@ void ServerConnexion::InitConnection() {
}
ServerConnexion::~ServerConnexion() {
if (GetDispatcher() == nullptr)
return;
GetDispatcher().UnregisterHandler(*this);
GetDispatcher()->UnregisterHandler(this);
m_Server->GetGame().RemovePlayer(m_ID);
m_Server.GetGame().RemovePlayer(m_ID);
}
} // namespace server

View File

@@ -19,7 +19,7 @@
namespace blitz {
namespace server {
ServerGame::ServerGame(Server* server) : m_Server(server), m_PositionTimer(SERVER_TPS) {
ServerGame::ServerGame(Server& server) : m_Server(server), m_PositionTimer(SERVER_TPS) {
CancelGame();
InitGameConfig();
}
@@ -28,7 +28,7 @@ ServerGame::~ServerGame() {}
void ServerGame::StartGame() {
UpdateGameState(game::gsPreparing, m_ServerDuration.m_PrepDuration);
m_Server->BroadcastChatMessage(protocol::ChatPacket::GetTextColor(protocol::AQUA) + "La partie commence dans 10s !");
m_Server.BroadcastChatMessage(protocol::ChatPacket::GetTextColor(protocol::AQUA) + "La partie commence dans 10s !");
}
void ServerGame::CancelGame() {
@@ -73,7 +73,7 @@ void ServerGame::Tick(std::uint64_t delta) {
void ServerGame::SendPlayerPositions() {
for (const auto& [playerID, player] : GetPlayers()) {
protocol::PlayerPositionAndRotationPacket packet(player.GetPosition(), player.GetYaw(), player.GetPitch(), playerID);
m_Server->BroadcastPacket(&packet);
m_Server.BroadcastPacket(&packet);
}
}
@@ -109,12 +109,12 @@ void ServerGame::AddPlayer(game::PlayerID player, const std::string& name) {
Game::AddPlayer(player, name);
protocol::PlayerJoinPacket joinPacket(player, name);
m_Server->BroadcastPacket(&joinPacket);
m_Server.BroadcastPacket(&joinPacket);
std::string joinMessage = utils::Format("%s a rejoint la partie !", name.c_str());
utils::LOG("[Server] " + joinMessage);
m_Server->BroadcastChatMessage(protocol::ChatPacket::GetTextColor(protocol::YELLOW) + joinMessage);
m_Server.BroadcastChatMessage(protocol::ChatPacket::GetTextColor(protocol::YELLOW) + joinMessage);
if (m_GameState == game::gsWaiting && m_Players.size() > 1) {
StartGame();
@@ -123,7 +123,7 @@ void ServerGame::AddPlayer(game::PlayerID player, const std::string& name) {
void ServerGame::RemovePlayer(game::PlayerID playerID) {
// we are closing the server, no need to broadcast any packets
if (!m_Server->IsRunning())
if (!m_Server.IsRunning())
return;
game::Player* player = GetPlayerById(playerID);
@@ -132,12 +132,12 @@ void ServerGame::RemovePlayer(game::PlayerID playerID) {
return;
protocol::PlayerLeavePacket packet(playerID);
m_Server->BroadcastPacket(&packet);
m_Server.BroadcastPacket(&packet);
std::string leaveMessage = utils::Format("%s a quitte la partie !", player->GetName().c_str());
utils::LOG("[Server] " + leaveMessage);
m_Server->BroadcastChatMessage(protocol::ChatPacket::GetTextColor(protocol::YELLOW) + leaveMessage);
m_Server.BroadcastChatMessage(protocol::ChatPacket::GetTextColor(protocol::YELLOW) + leaveMessage);
Game::RemovePlayer(playerID);
@@ -164,7 +164,7 @@ void ServerGame::DamagePlayer(game::Player& player, game::Player& shooter) {
NotifyListeners(&game::GameListener::OnPlayerDeath, player.GetID());
protocol::PlayerDeathPacket packet(player.GetID());
m_Server->BroadcastPacket(&packet);
m_Server.BroadcastPacket(&packet);
}
}
@@ -176,15 +176,15 @@ void ServerGame::UpdateHP(game::Player& player, float newHP) {
protocol::UpdateHealthPacket packet(player.GetHP());
auto it = m_Server->GetConnexions().find(player.GetID());
if (it != m_Server->GetConnexions().end())
auto it = m_Server.GetConnexions().find(player.GetID());
if (it != m_Server.GetConnexions().end())
it->second->SendPacket(&packet);
}
void ServerGame::UpdatePlayerStats() {
for (auto& [playerId, player] : GetPlayers()) {
protocol::PlayerStatsPacket packet(playerId, player.GetStats());
m_Server->BroadcastPacket(&packet);
m_Server.BroadcastPacket(&packet);
}
}
@@ -203,12 +203,12 @@ void ServerGame::UpdateGameState(game::GameState gameState, std::uint64_t durati
}
protocol::UpdateGameStatePacket packet(gameState, duration);
m_Server->BroadcastPacket(&packet);
m_Server.BroadcastPacket(&packet);
}
void ServerGame::SendServerConfig() {
protocol::ServerConfigPacket packet(m_Config);
m_Server->BroadcastPacket(&packet);
m_Server.BroadcastPacket(&packet);
}