13 Commits

Author SHA1 Message Date
26c08059be update splib version
Some checks failed
Linux arm64 / Build (push) Failing after 9s
2025-03-04 23:16:17 +01:00
87b4bf20b7 remove unused include 2025-03-04 12:29:58 +01:00
06c17abd40 complete splib migration
Some checks failed
Linux arm64 / Build (push) Failing after 58s
2025-03-03 11:27:42 +01:00
000970dcb9 fix colored text serialize issues
Some checks failed
Linux arm64 / Build (push) Failing after 9s
2025-02-23 22:43:48 +01:00
df15e5efd5 remove unused code 2025-02-23 22:36:42 +01:00
a34e217e98 migrate to splib 2025-02-23 22:33:50 +01:00
74aac7a03a begin splib migration
Some checks failed
Linux arm64 / Build (push) Failing after 1m58s
2025-02-23 13:26:33 +01:00
63536535f6 use splib VarInt 2025-02-23 11:19:04 +01:00
67cb368297 change libsdl to libsdl2 2025-02-23 11:13:52 +01:00
5fc9125c67 imgui include 2025-02-23 11:13:31 +01:00
e80c6a3c60 action: cache only packages
All checks were successful
Linux arm64 / Build (push) Successful in 3m15s
2024-06-03 22:25:23 +02:00
680c180b4b action: update xmake cache name
Some checks failed
Linux arm64 / Build (push) Has been cancelled
2024-06-03 20:03:29 +02:00
a4e90b455d updated runner
Some checks failed
Linux arm64 / Build (push) Has been cancelled
2024-06-03 20:02:19 +02:00
84 changed files with 891 additions and 2639 deletions

View File

@@ -6,12 +6,7 @@ on: [push]
jobs:
Build:
runs-on: ubuntu-latest
steps:
- name: Install deps
run : |
apt update
apt install -y libsdl2-dev libassimp-dev libglew-dev
steps:
- name: Check out repository code
uses: actions/checkout@v3
@@ -20,7 +15,7 @@ jobs:
with:
xmake-version: latest
actions-cache-folder: '.xmake-cache'
actions-cache-key: 'ubuntu'
actions-cache-key: 'xmake-ubuntu'
- name: Calc deps hash
uses: seepine/hash-files@v1
@@ -33,14 +28,14 @@ jobs:
- name: Packages cache
uses: actions/cache@v4
with:
path: ~/.xmake
path: ~/.xmake/packages
key: ${{ runner.os }}-${{ steps.get-hash.outputs.hash }}
- name: XMake config
run: xmake f -p linux -y --root
run: xmake f -p linux -y
- name: Build
run: xmake --root
run: xmake
- name: Test
run: xmake test --root
run: xmake test

View File

@@ -1,286 +1,9 @@
#pragma once
/**
* \file DataBuffer.h
* \brief File containing the blitz::DataBuffer class
*/
#include <algorithm>
#include <cassert>
#include <cstdint>
#include <cstring>
#include <string>
#include <vector>
#include <sp/common/DataBuffer.h>
namespace blitz {
/**
* \class DataBuffer
* \brief Class used to manipulate memory
*/
class DataBuffer {
private:
typedef std::vector<std::uint8_t> Data;
Data m_Buffer;
std::size_t m_ReadOffset;
public:
typedef Data::iterator iterator;
typedef Data::const_iterator const_iterator;
typedef Data::reference reference;
typedef Data::const_reference const_reference;
typedef Data::difference_type difference_type;
DataBuffer();
DataBuffer(const DataBuffer& other);
DataBuffer(const DataBuffer& other, difference_type offset);
DataBuffer(DataBuffer&& other);
DataBuffer(const std::string& str);
DataBuffer& operator=(const DataBuffer& other);
DataBuffer& operator=(DataBuffer&& other);
/**
* \brief Append data to the buffer
*/
template <typename T>
void Append(const T& data) {
std::size_t size = sizeof(data);
std::size_t end_pos = m_Buffer.size();
m_Buffer.resize(m_Buffer.size() + size);
std::memcpy(&m_Buffer[end_pos], &data, size);
}
/**
* \brief Append data to the buffer
*/
template <typename T>
DataBuffer& operator<<(const T& data) {
Append(data);
return *this;
}
/**
* \brief Append a string to the buffer
* \warning Don't use it for binary data !
* \param str The string to append
*/
DataBuffer& operator<<(const std::string& str) {
std::size_t strlen = str.length() + 1; // including null character
Resize(GetSize() + strlen);
std::memcpy(m_Buffer.data() + GetSize() - strlen, str.data(), strlen);
return *this;
}
/**
* \brief Append data to the buffer from another const buffer
* \param data The buffer to append
*/
DataBuffer& operator<<(const DataBuffer& data) {
m_Buffer.insert(m_Buffer.end(), data.begin(), data.end());
return *this;
}
/**
* \brief Read some data from the buffer and assign to desired variable
*/
template <typename T>
DataBuffer& operator>>(T& data) {
assert(m_ReadOffset + sizeof(T) <= GetSize());
data = *(reinterpret_cast<T*>(&m_Buffer[m_ReadOffset]));
m_ReadOffset += sizeof(T);
return *this;
}
/**
* \brief Read some data from the buffer and assign to the new buffer
* \param data The buffer to assign
*/
DataBuffer& operator>>(DataBuffer& data) {
data.Resize(GetSize() - m_ReadOffset);
std::copy(m_Buffer.begin() + static_cast<difference_type>(m_ReadOffset), m_Buffer.end(), data.begin());
m_ReadOffset = m_Buffer.size();
return *this;
}
/**
* \brief Read a string from the buffer
* \param str The string to assign in the new buffer
* \warning Don't use it for binary data !
*/
DataBuffer& operator>>(std::string& str) {
std::size_t stringSize =
strlen(reinterpret_cast<const char*>(m_Buffer.data()) + m_ReadOffset) + 1; // including null character
str.resize(stringSize);
std::copy(m_Buffer.begin() + static_cast<difference_type>(m_ReadOffset),
m_Buffer.begin() + static_cast<difference_type>(m_ReadOffset + stringSize), str.begin());
m_ReadOffset += stringSize;
return *this;
}
/**
* \brief Write some data to the buffer
* \param buffer The buffer to write
* \param amount The amount of data to write
*/
void WriteSome(const char* buffer, std::size_t amount) {
std::size_t end_pos = m_Buffer.size();
m_Buffer.resize(m_Buffer.size() + amount);
std::memcpy(m_Buffer.data() + end_pos, buffer, amount);
}
/**
* \brief Write some data to the buffer
* \param buffer The buffer to write
* \param amount The amount of data to write
*/
void WriteSome(const std::uint8_t* buffer, std::size_t amount) {
std::size_t end_pos = m_Buffer.size();
m_Buffer.resize(m_Buffer.size() + amount);
std::memcpy(m_Buffer.data() + end_pos, buffer, amount);
}
/**
* \brief Read some data from the buffer
* \param buffer The buffer to Read
* \param amount The amount of data from the buffer
*/
void ReadSome(char* buffer, std::size_t amount) {
assert(m_ReadOffset + amount <= GetSize());
std::copy_n(m_Buffer.begin() + static_cast<difference_type>(m_ReadOffset), amount, buffer);
m_ReadOffset += amount;
}
/**
* \brief Read some data from the buffer
* \param buffer The buffer to Read
* \param amount The amount of data from the buffer
*/
void ReadSome(std::uint8_t* buffer, std::size_t amount) {
assert(m_ReadOffset + amount <= GetSize());
std::copy_n(m_Buffer.begin() + static_cast<difference_type>(m_ReadOffset), amount, buffer);
m_ReadOffset += amount;
}
/**
* \brief Read some data from the buffer
* \param buffer The buffer to Read
* \param amount The amount of data from the buffer
*/
void ReadSome(DataBuffer& buffer, std::size_t amount) {
assert(m_ReadOffset + amount <= GetSize());
buffer.Resize(amount);
std::copy_n(m_Buffer.begin() + static_cast<difference_type>(m_ReadOffset), amount, buffer.begin());
m_ReadOffset += amount;
}
/**
* \brief Resize the buffer
* \param size The new size of the buffer
*/
void Resize(std::size_t size) {
m_Buffer.resize(size);
}
/**
* \brief Reserve some space in the buffer
* \param amount The amount of space to reserve
*/
void Reserve(std::size_t amount) {
m_Buffer.reserve(amount);
}
/**
* \brief Clear the buffer
*/
void Clear() {
m_Buffer.clear();
m_ReadOffset = 0;
}
/**
* \brief When the buffer has been read entirely
*/
bool IsFinished() const {
return m_ReadOffset >= m_Buffer.size();
}
/**
* \brief Get the buffer data
*/
std::uint8_t* data() {
return m_Buffer.data();
}
/**
* \brief Get the buffer data
*/
const std::uint8_t* data() const {
return m_Buffer.data();
}
/**
* \brief Get the read offset
*/
std::size_t GetReadOffset() const {
return m_ReadOffset;
}
/**
* \brief Set the read offset
* \param pos The new read offset
*/
void SetReadOffset(std::size_t pos);
/**
* \brief Get the size of the buffer
*/
std::size_t GetSize() const;
/**
* \brief Get the remaining size of the buffer
*/
std::size_t GetRemaining() const;
/**
* \brief Read a file into the buffer
* \param fileName The name of the file to read
*/
bool ReadFile(const std::string& fileName);
/**
* \brief Write a file into the buffer
* \param fileName The name of the file to write to
*/
bool WriteFile(const std::string& fileName) const;
/**
* \brief Allocate the buffer on the heap
* \warning Don't forget to free the data !
*/
std::uint8_t* HeapAllocatedData() const {
std::uint8_t* newBuffer = new std::uint8_t[GetSize()];
std::memcpy(newBuffer, data(), GetSize());
return newBuffer;
}
/**
* \brief Operator == to compare two DataBuffer
*/
bool operator==(const DataBuffer& other) const {
return m_Buffer == other.m_Buffer;
}
iterator begin();
iterator end();
const_iterator begin() const;
const_iterator end() const;
};
/**
* \brief Operator << to write a DataBuffer to an ostream
*/
std::ostream& operator<<(std::ostream& os, const DataBuffer& buffer);
using DataBuffer = sp::DataBuffer;
} // namespace blitz

View File

@@ -6,6 +6,7 @@
*/
#include <cstdint>
#include <sp/protocol/MessagePrinter.h>
namespace blitz {
namespace game {
@@ -30,3 +31,10 @@ enum GameState : std::uint8_t {
} // namespace game
} // namespace blitz
namespace sp {
template <>
inline std::string PrintData(const blitz::game::GameState& a_State) {
return PrintData(static_cast<unsigned>(a_State));
}
} // namespace sp

View File

@@ -1,25 +0,0 @@
#pragma once
/**
* \file NonCopyable.h
* \brief File containing the blitz::NonCopyable class
*/
namespace blitz {
/**
* \class NonCopyable
* \brief Class used to make a class non copyable
* \note Inherit from this class privately to make a class non copyable
*/
class NonCopyable {
public:
NonCopyable(const NonCopyable&) = delete;
NonCopyable& operator=(const NonCopyable&) = delete;
protected:
NonCopyable() {}
~NonCopyable() {}
};
} // namespace blitz

View File

@@ -10,6 +10,7 @@
#include "blitz/misc/ObjectNotifier.h"
#include "blitz/misc/Time.h"
#include <map>
#include <sp/protocol/MessagePrinter.h>
namespace blitz {
namespace game {
@@ -140,3 +141,10 @@ class Game : public utils::ObjectNotifier<GameListener> {
} // namespace game
} // namespace blitz
namespace sp {
template <>
inline std::string PrintData(const blitz::game::GameConfig& a_Config) {
return "{Gravity=" + PrintData(a_Config.Gravity) + ", FiringRate=" + PrintData(a_Config.FiringRate) + "}";
}
} // namespace sp

View File

@@ -8,6 +8,7 @@
#include "blitz/common/Defines.h"
#include "blitz/maths/Vector.h"
#include <cstdint>
#include <sp/protocol/MessagePrinter.h>
#include <string>
namespace blitz {
@@ -222,3 +223,12 @@ class Player {
} // namespace game
} // namespace blitz
namespace sp {
template <>
inline std::string PrintData(const blitz::game::PlayerStats& a_Stats) {
return "{m_Deaths=" + PrintData(a_Stats.m_Deaths) + ", m_Kills=" + PrintData(a_Stats.m_Kills) +
", m_ShootCount=" + PrintData(a_Stats.m_ShootCount) + ", m_ShootSuccessCount=" + PrintData(a_Stats.m_ShootSuccessCount) +
"}";
}
} // namespace sp

View File

@@ -8,6 +8,7 @@
#include <algorithm>
#include <cmath>
#include <cstddef>
#include <sp/protocol/MessagePrinter.h>
namespace blitz {
@@ -325,3 +326,14 @@ bool operator==(const Mat4<T>& mat, const Mat4<T>& other) {
mat.w3 == other.w3;
}
} // namespace blitz
namespace sp {
template <>
inline std::string PrintData(const blitz::Vec3f& a_Vec) {
return "{" + PrintData(a_Vec.x) + ", " + PrintData(a_Vec.y) + ", " + PrintData(a_Vec.z) + "}";
}
template <>
inline std::string PrintData(const blitz::Vec4f& a_Vec) {
return "{" + PrintData(a_Vec.x) + ", " + PrintData(a_Vec.y) + ", " + PrintData(a_Vec.z) + ", " + PrintData(a_Vec.w) + "}";
}
} // namespace sp

View File

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

View File

@@ -8,70 +8,59 @@
#include "TCPSocket.h"
#include "blitz/protocol/PacketDispatcher.h"
#include "blitz/protocol/PacketHandler.h"
#include "blitz/protocol/PacketFactory.h"
namespace blitz {
namespace network {
using TCPStream = sp::io::Stream<sp::io::TcpTag, protocol::PacketDispatcher, protocol::PacketFactory, sp::option::ZlibCompress>;
/**
* \class Connexion
* \brief Represents a network connexion
*/
class Connexion : public protocol::PacketHandler, private NonCopyable {
protected:
protocol::PacketDispatcher m_Dispatcher;
private:
TCPSocket m_Socket;
class Connexion : public protocol::PacketHandler, public TCPStream {
public:
/**
/**
* \brief Constructs with an empty socket
*/
Connexion(protocol::PacketDispatcher& dispatcher);
Connexion() {}
/**
* \brief Constructs with an already connected socket
*/
Connexion(protocol::PacketDispatcher& dispatcher, TCPSocket& socket);
Connexion(TCPSocket&& socket);
/**
* \brief Move constructor
*/
Connexion(Connexion&& move);
/**
* \brief Default destructor
*/
virtual ~Connexion();
/**
* \brief Reads socket and process a Packet, if any
*/
virtual bool UpdateSocket();
/**
* \brief Closes the connexion
*/
void CloseConnection();
/**
* \brief Returns the TCPSocket::Status of the internal socket
*/
TCPSocket::Status GetSocketStatus() const {
return m_Interface.GetStatus();
}
virtual bool UpdateSocket();
/**
* \brief Tries to connect the socket at the specified address and port
* \return Whether this action was succesfull
*/
bool Connect(const std::string& address, std::uint16_t port);
/**
* \brief Returns the TCPSocket::Status of the internal socket
*/
TCPSocket::Status GetSocketStatus() const {
return m_Socket.GetStatus();
}
/**
* \brief Sends the protocol::Packet over the network to the remote
* \param packet The protocol::Packet to send
*/
void SendPacket(const protocol::Packet* packet);
void SendPacket(const protocol::Packet& packet);
};
} // namespace network

View File

@@ -21,7 +21,7 @@ namespace network {
* \note This class is meant to be created only once in your program. \n
* The easiest thing to do is to create an instance of this class at the top of your **main.cpp**.
*/
class NetworkInitializer : private NonCopyable {
class NetworkInitializer : private sp::NonCopyable {
public:
/**
* \brief Creates the networking context

View File

@@ -10,76 +10,7 @@
namespace blitz {
namespace network {
/**
* \class TCPListener
* \brief Cross platform abstraction of a TCP socket server
*/
class TCPListener : private NonCopyable {
private:
SocketHandle m_Handle;
std::uint16_t m_Port;
int m_MaxConnections;
public:
/**
* \brief Default constructor
*/
TCPListener();
/**
* \brief Default destructor
*/
~TCPListener();
/**
* \brief Starts listening for guests to connect
* \param port The port to listen to
* \param maxConnexions The maximum amount of connexion that can happen at the same time. \n
* Every other guests will be kicked if this amount is reached.
* \return Whether this action was succesfull
*/
bool Listen(std::uint16_t port, int maxConnexions);
/**
* \brief Tries to accept an incoming request to connect
* \param newSocket the empty socket to put the result to
* \return true if a new connexion was accepted
*/
bool Accept(TCPSocket& newSocket);
/**
* \brief Destroys the socket
*/
void Destroy();
/**
* \brief Closes transmissions
* \return true if this action was succesfull
*/
bool Close();
/**
* \brief Allows to set the socket in non blocking/blocking mode
* \param block If set to true, every call to Read will wait until the socket receives something
* \return true if the operation was successful
*/
bool SetBlocking(bool blocking);
/**
* \brief Getter of the m_Port member
* \return The port which the socket listen to
*/
std::uint16_t GetListeningPort() const {
return m_Port;
}
/**
* \brief Getter of the m_MaxConnections member
* \return The maximum amount of connexions that can happen at the same time.
*/
int GetMaximumConnections() const {
return m_MaxConnections;
}
};
using TCPListener = sp::io::TcpListener;
} // namespace network
} // namespace blitz

View File

@@ -1,26 +1,6 @@
#pragma once
#include "blitz/common/DataBuffer.h"
#include "blitz/common/NonCopyable.h"
#ifdef _WIN32
#include <winsock2.h>
#include <ws2tcpip.h>
#else
#include <arpa/inet.h>
#include <netdb.h>
#include <netinet/in.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
#define closesocket close
#endif
#ifndef INVALID_SOCKET
#define INVALID_SOCKET -1
#endif
#include <sp/extensions/Tcp.h>
/**
* \file TCPSocket.h
@@ -30,138 +10,7 @@
namespace blitz {
namespace network {
/**
* \typedef SocketHandle
* \brief Represents a native socket
*/
typedef int SocketHandle;
/**
* \class TCPSocket
* \brief Cross platform abstraction of a TCP socket
*/
class TCPSocket : private NonCopyable {
public:
/**
* \enum Status
* \brief Describes the state of a socket
*/
enum class Status {
/** The socket is connected */
Connected,
/** The socket is not connected */
Disconnected,
/** Something bad happened */
Error,
};
private:
bool m_Blocking;
Status m_Status;
SocketHandle m_Handle;
std::uint16_t m_Port;
sockaddr m_RemoteAddr;
public:
/**
* \brief Default constructor
*/
TCPSocket();
/**
* \brief Default destructor
*/
virtual ~TCPSocket();
/**
* \brief Move constructor
*/
TCPSocket(TCPSocket&&);
/**
* \brief Sets the TCPSocket::Status of the socket
* \param status The TCPSocket::Status to apply
*/
void SetStatus(Status status);
/**
* \brief Allows to set the socket in non blocking/blocking mode
* \param block If set to true, every call to Read will wait until the socket receives something
* \return true if the operation was successful
*/
bool SetBlocking(bool block);
/**
* \brief Checks if the socket is in blocking mode
* \return Whether the socket is in blocking mode
*/
bool IsBlocking() const;
/**
* \brief Getter of the m_Status member
* \return The TCPSocket::Status of this socket
*/
Status GetStatus() const;
/**
* \brief Tries to connect to the host at the given port
* \param host The host to connect to. Can be a hostname or an ip address.
* \param port The port to connect to.
* \return Whether this action was successfull
*/
bool Connect(const std::string& host, std::uint16_t port);
/**
* \brief Disconnects the socket from the remote
* \note Does nothing if the socket is not connected. \n
* This function is also called by the destructor.
*/
void Disconnect();
/**
* \brief Sends some data
* \param buffer The data to send
* \note Simply returns 0 if the socket is not connected
* \return The amount of data sent. It should be the size of the buffer in theory.
*/
std::size_t Send(DataBuffer& buffer);
/**
* \brief Sends some data
* \param data The data to send
* \param size The amount of data to send
* \note Simply returns 0 if the socket is not connected
* \return The amount of data sent. It should be equal to the size param in theory
*/
std::size_t Send(const std::uint8_t* data, std::size_t size);
/**
* \brief Reads some data
* \param amount The amount of data to read
* \return The buffer containing the data that have been received
* \note If no data is available, an empty DataBuffer is returned
*/
DataBuffer Receive(std::size_t amount);
/**
* \brief Reads some data
* \param buffer The buffer to write into
* \param amount The amount of data to read
* \return The amount of data read
* \note If no data is available, 0 is returned
*/
std::size_t Receive(DataBuffer& buffer, std::size_t amount);
friend class TCPListener;
};
/**
* \brief Compress the data and send it to the socket
* \param data The data to send
* \param socket The socket to send to
*/
void SendPacket(const DataBuffer& data, network::TCPSocket& socket);
using TCPSocket = sp::io::TcpSocket;
} // namespace network
} // namespace blitz

View File

@@ -0,0 +1,74 @@
#pragma once
#include "blitz/common/DataBuffer.h"
#include "blitz/maths/Vector.h"
#include <string>
#include <vector>
namespace blitz {
namespace protocol {
/**
* \struct ColoredPart
* \brief Represents a part of a chat message with a specific color.
*/
struct ColoredPart {
/**
* \brief The color of the part.
*/
Vec4f m_Color;
/**
* \brief The text of the part.
*/
std::string m_Text;
};
using ColoredText = std::vector<ColoredPart>;
const static Vec3uc AQUA = {0, 255, 255};
const static Vec3uc BLUE = {0, 0, 255};
const static Vec3uc GREEN = {0, 255, 0};
const static Vec3uc PURPLE = {255, 0, 255};
const static Vec3uc RED = {255, 0, 0};
const static Vec3uc WHITE = {255, 255, 255};
const static Vec3uc YELLOW = {255, 255, 0};
/**
* \brief Get the text color.
*/
std::string GetTextColor(Vec3uc color);
/**
* \brief Colorize a text.
*/
ColoredText ColorizeText(const std::string& text);
/**
* \brief Get the colored text string.
*/
std::string GetColoredTextString(const ColoredText& text);
/**
* \brief Serialize the colored part
* \param out The buffer to write the serialized colored part to
* \param var The colored part to serialize
*/
DataBuffer& operator<<(DataBuffer& out, const ColoredPart& var);
/**
* \brief Deserialize the colored part
* \param in The buffer to read the serialized colored part from
* \param var The colored part to deserialize
*/
DataBuffer& operator>>(DataBuffer& in, ColoredPart& var);
} // namespace protocol
} // namespace blitz
namespace sp {
template <>
inline std::string PrintData(const blitz::protocol::ColoredPart& a_Part) {
return "{m_Color=" + PrintData(a_Part.m_Color) + ", m_Text=" + PrintData(a_Part.m_Text) + "}";
}
} // namespace sp

View File

@@ -5,54 +5,17 @@
* \brief File containing the blitz::protocol::PacketDispatcher class
*/
#include "blitz/common/NonCopyable.h"
#include "blitz/protocol/Protocol.h"
#include <map>
#include "blitz/protocol/Packets.h"
#include <sp/default/DefaultPacketDispatcher.h>
namespace blitz {
namespace protocol {
class PacketHandler;
/**
* \class PacketDispatcher
* \brief Class used to dispatch packets
*/
class PacketDispatcher : private NonCopyable {
private:
std::map<PacketType, std::vector<PacketHandler*>> m_Handlers;
public:
/**
* \brief Constructor
*/
PacketDispatcher() {}
/**
* \brief Dispatch a packet
* \param packet The packet to dispatch
*/
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);
/**
* \brief Unregister a packet handler
* \param type The packet type
* \param handler The packet handler
*/
void UnregisterHandler(PacketType type, PacketHandler& handler);
/**
* \brief Unregister a packet handler
* \param handler The packet handler
*/
void UnregisterHandler(PacketHandler& handler);
};
using PacketDispatcher = sp::PacketDispatcher;
} // namespace protocol
} // namespace blitz

View File

@@ -4,23 +4,13 @@
* \file PacketFactory.h
*/
#include "blitz/protocol/Protocol.h"
#include <memory>
#include "blitz/protocol/Packets.h"
namespace blitz {
namespace protocol {
typedef std::unique_ptr<Packet> PacketPtr;
using PacketPtr = std::unique_ptr<Packet>;
using PacketFactory = sp::PacketFactory;
namespace PacketFactory {
/**
* \brief Creates a packet from a buffer.
* \param buffer The buffer containing the packet data.
* \return The created packet.
*/
const PacketPtr CreatePacket(PacketType type, DataBuffer& buffer);
} // namespace PacketFactory
} // namespace protocol
} // namespace blitz

View File

@@ -5,55 +5,12 @@
* \brief File containing the blitz::protocol::PacketHandler class
*/
#include "blitz/protocol/PacketsForward.h"
#include "blitz/protocol/Protocol.h"
#include "blitz/protocol/Packets.h"
namespace blitz {
namespace protocol {
class PacketDispatcher;
/**
* \class PacketHandler
* \brief Class used to handle packets
*/
class PacketHandler {
private:
PacketDispatcher& m_Dispatcher;
public:
/**
* \brief Constructor
* \param dispatcher The packet dispatcher
*/
PacketHandler(PacketDispatcher& dispatcher) : m_Dispatcher(dispatcher) {}
virtual ~PacketHandler() {}
/**
* \brief Get the packet dispatcher
* \return The packet dispatcher
*/
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) {}
};
using PacketHandler = sp::PacketHandler;
} // namespace protocol
} // namespace blitz

View File

@@ -1,3 +1,34 @@
#pragma once
namespace blitz {
namespace protocol {
/**
* \enum PacketType
* \brief Map the packets name to their ID
*/
enum PacketType {
Chat = 0, /**< Corresponds to ChatPacket */
ConnexionInfo, /**< Corresponds to ConnexionInfoPacket */
Disconnect, /**< Corresponds to DisconnectPacket */
KeepAlive, /**< Corresponds to KeepAlivePacket */
PlayerDeath, /**< Corresponds to PlayerDeathPacket */
PlayerJoin, /**< Corresponds to PlayerJoinPacket */
PlayerLeave, /**< Corresponds to PlayerLeavePacket */
PlayerList, /**< Corresponds to PlayerListPacket */
PlayerLogin, /**< Corresponds to PlayerLoginPacket */
PlayerPositionAndRotation, /**< Corresponds to PlayerPositionAndRotationPacket */
PlayerShoot, /**< Corresponds to PlayerShootPacket */
PlayerStats, /**< Corresponds to PlayerStatsPacket */
ServerConfig, /**< Corresponds to ServerConfigPacket*/
ServerTps, /**< Corresponds to ServerTpsPacket */
UpdateGameState, /**< Corresponds to UpdateGameStatePacket */
UpdateHealth, /**< Corresponds to UpdateHealthPacket */
};
} // namespace protocol
} // namespace blitz
#include "packets/ChatPacket.h"
#include "packets/ConnexionInfoPacket.h"
#include "packets/DisconnectPacket.h"
@@ -14,3 +45,34 @@
#include "packets/ServerTpsPacket.h"
#include "packets/UpdateGameStatePacket.h"
#include "packets/UpdateHealthPacket.h"
// they must be in the same order as in the enum !
using AllPackets = std::tuple<
blitz::protocol::ChatPacket,
blitz::protocol::ConnexionInfoPacket,
blitz::protocol::DisconnectPacket,
blitz::protocol::KeepAlivePacket,
blitz::protocol::PlayerDeathPacket,
blitz::protocol::PlayerJoinPacket,
blitz::protocol::PlayerLeavePacket,
blitz::protocol::PlayerListPacket,
blitz::protocol::PlayerLoginPacket,
blitz::protocol::PlayerPositionAndRotationPacket,
blitz::protocol::PlayerShootPacket,
blitz::protocol::PlayerStatsPacket,
blitz::protocol::ServerConfigPacket,
blitz::protocol::ServerTpsPacket,
blitz::protocol::UpdateGameStatePacket,
blitz::protocol::UpdateHealthPacket
>;
#include <sp/default/DefaultPacketFactory.h>
#include <sp/default/DefaultPacketHandler.h>
namespace blitz {
namespace protocol {
using Packet = sp::PacketMessage;
} // namespace protocol
} // namespace blitz

View File

@@ -1,121 +0,0 @@
#pragma once
/**
* \file Protocol.h
* \brief File containing the blitz::protocol::Protocol class
*/
#include "blitz/common/DataBuffer.h"
namespace blitz {
namespace protocol {
class PacketHandler;
/**
* \enum PacketType
* \brief Map the packets name to their ID
*/
enum class PacketType : std::uint8_t {
// client --> server
PlayerLogin = 0, /**< Corresponds to PlayerLoginPacket */
UpdateHealth, /**< Corresponds to UpdateHealthPacket */
// client <-- server
ConnexionInfo, /**< Corresponds to ConnexionInfoPacket */
PlayerDeath, /**< Corresponds to PlayerDeathPacket */
PlayerJoin, /**< Corresponds to PlayerJoinPacket */
PlayerLeave, /**< Corresponds to PlayerLeavePacket */
PlayerList, /**< Corresponds to PlayerListPacket */
PlayerStats, /**< Corresponds to PlayerStatsPacket */
ServerConfig, /**< Corresponds to ServerConfigPacket*/
ServerTps, /**< Corresponds to ServerTpsPacket */
UpdateGameState, /**< Corresponds to UpdateGameStatePacket */
// client <--> server
KeepAlive, /**< Corresponds to KeepAlivePacket */
Disconnect, /**< Corresponds to DisconnectPacket */
Chat, /**< Corresponds to ChatPacket */
PlayerPositionAndRotation, /**< Corresponds to PlayerPositionAndRotationPacket */
PlayerShoot, /**< Corresponds to PlayerShootPacket */
PACKET_COUNT
};
/**
* \class Packet
* \brief Represents a network packet <br/>
* %Packet data structure :
*| Field Name | Field Type | Notes |
*|---------------------|---------------|-------------------------------|
*| Length | Long | Length of whole Packet |
*| Uncompressed Length | VarInt | Length of Packet ID + Data |
*| Packet ID | Byte | Represents the #PacketType |
*| Data | Byte Array | Depends on the packet ID |
*/
class Packet {
public:
Packet() {}
virtual ~Packet() {}
/**
* \brief Serialize the Packet into a DataBuffer to be sent over the network
* \param packetID Set to false if you don't want to write the Packet ID for some reason
* \returns A DataBuffer filled with the serialized Packet
*/
virtual DataBuffer Serialize(bool packetID = true) const = 0;
/**
* \brief Deserialize the DataBuffer into a Packet to be read by the client/server
* \param data The DataBuffer containing the data from the network
*/
virtual void Deserialize(DataBuffer& data) = 0;
/**
* \brief Dispatches the Packet
* \param handler The class to dispatch the Packet to
*/
virtual void Dispatch(PacketHandler* handler) const = 0;
/**
* \brief Writes the Packet ID into a buffer
* \param data The DataBuffer to write to
* \param packetID If set to false, this function does nothing
*/
void WritePacketID(DataBuffer& data, bool packetID) const;
/**
* \returns The type of the Packet
*/
virtual PacketType GetType() const = 0;
/**
* \returns The Packet ID corresponding to the PacketType of this Packet
*/
std::uint8_t GetID() const {
return static_cast<std::uint8_t>(GetType());
}
};
/**
* \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

@@ -1,61 +0,0 @@
#pragma once
/**
* \file VarInt.h
* \brief File containing the blitz::VarInt class
*/
#include <cstddef>
#include <cstdint>
namespace blitz {
class DataBuffer;
namespace protocol {
/**
* \class VarInt
* \brief Variable-length format such that smaller numbers use fewer bytes.
*/
class VarInt {
private:
std::uint64_t m_Value;
public:
VarInt() : m_Value(0) {}
/**
* \brief Construct a variable integer from a value
* \param value The value of the variable integer
*/
VarInt(std::uint64_t value) : m_Value(value) {}
/**
* \brief Get the value of the variable integer
*/
std::uint64_t GetValue() const {
return m_Value;
}
/**
* \brief Get the length of the serialized variable integer
*/
std::size_t GetSerializedLength() const;
/**
* \brief Serialize the variable integer
* \param out The buffer to write the serialized variable integer to
* \param var The variable integer to serialize
*/
friend DataBuffer& operator<<(DataBuffer& out, const VarInt& var);
/**
* \brief Deserialize the variable integer
* \param in The buffer to read the serialized variable integer from
* \param var The variable integer to deserialize
*/
friend DataBuffer& operator>>(DataBuffer& in, VarInt& var);
};
} // namespace protocol
} // namespace blitz

View File

@@ -5,29 +5,22 @@
* \brief File containing the blitz::protocol::ChatPacket class
*/
#include "blitz/maths/Vector.h"
#include "blitz/protocol/Protocol.h"
#include <vector>
#include "blitz/protocol/Color.h"
#include <sp/default/DefaultPacket.h>
#include <sp/protocol/Field.h>
#include <sp/protocol/MessageBase.h>
namespace blitz {
namespace protocol {
/**
* \struct ColoredPart
* \brief Represents a part of a chat message with a specific color.
*/
struct ColoredPart {
/**
* \brief The color of the part.
*/
Vec4f m_Color;
/**
* \brief The text of the part.
*/
std::string m_Text;
enum class ChatFieldsE {
m_Message = 0,
};
typedef std::vector<ColoredPart> ColoredText;
using ChatFields = std::tuple<
ColoredText //<- m_Message
>;
/**
* \class ChatPacket
@@ -41,63 +34,21 @@ typedef std::vector<ColoredPart> ColoredText;
* |--------------------|-------------------|-------------------------------|
* | m_Message | ColoredText | The message sent in the chat |
*/
class ChatPacket : public ConcretePacket<ChatPacket> {
private:
ColoredText m_Message;
DeclarePacket(Chat){
public:
PacketConstructor(Chat)
public:
/**
* \brief Default constructor.
*/
ChatPacket() {}
/**
* \brief Constructor.
* \param msg The message to send.
*/
ChatPacket(const std::string& msg) : m_Message(ColorizeText(msg)) {}
/**
* \brief Constructor.
* \param msg The message to send.
*/
ChatPacket(const ColoredText& msg) : m_Message(msg) {}
virtual ~ChatPacket() {}
virtual DataBuffer Serialize(bool packetID = true) const;
virtual void Deserialize(DataBuffer& data);
ChatPacket(const std::string& msg) : ChatPacket(ColorizeText(msg)) {}
/**
* \brief Get the message.
* \return The message.
*/
const ColoredText& GetMessage() const {
return m_Message;
return GetField<ChatFieldsE, ChatFieldsE::m_Message>();
}
virtual PacketType GetType() const {
return PacketType::Chat;
}
/**
* \brief Get the text color.
*/
static std::string GetTextColor(Vec3uc color);
/**
* \brief Colorize a text.
*/
static ColoredText ColorizeText(const std::string& text);
/**
* \brief Get the colored text string.
*/
static std::string GetColoredTextString(const ColoredText& text);
};
const static Vec3uc AQUA = {0, 255, 255};
const static Vec3uc BLUE = {0, 0, 255};
const static Vec3uc GREEN = {0, 255, 0};
const static Vec3uc PURPLE = {255, 0, 255};
const static Vec3uc RED = {255, 0, 0};
const static Vec3uc WHITE = {255, 255, 255};
const static Vec3uc YELLOW = {255, 255, 0};
} // namespace protocol
} // namespace blitz

View File

@@ -5,11 +5,21 @@
* \brief File containing the blitz::protocol::ConnexionInfoPacket class
*/
#include "blitz/protocol/Protocol.h"
#include <sp/default/DefaultPacket.h>
#include <sp/protocol/Field.h>
#include <sp/protocol/MessageBase.h>
namespace blitz {
namespace protocol {
enum class ConnexionInfoFieldsE {
m_ConnectionID = 0,
};
using ConnexionInfoFields = std::tuple<
std::uint8_t //<- m_ConnectionID
>;
/**
* \class ConnexionInfoPacket
* \brief Packet for sending connection information.
@@ -22,35 +32,16 @@ namespace protocol {
* |--------------------|-------------------|-------------------------------|
* | m_ConnectionID | std::uint8_t | The connection ID |
*/
class ConnexionInfoPacket : public ConcretePacket<ConnexionInfoPacket> {
private:
std::uint8_t m_ConnectionID;
public:
/**
* \brief Default constructor.
*/
ConnexionInfoPacket() {}
/**
* \brief Constructor.
* \param connectionID The ID of the connection.
*/
ConnexionInfoPacket(std::uint8_t connectionID) : m_ConnectionID(connectionID) {}
virtual ~ConnexionInfoPacket() {}
virtual DataBuffer Serialize(bool packetID = true) const;
virtual void Deserialize(DataBuffer& data);
DeclarePacket(ConnexionInfo){
public:
PacketConstructor(ConnexionInfo)
/**
* \brief Get the connection ID.
* \return The connection ID.
*/
std::uint8_t GetConnectionID() const {
return m_ConnectionID;
}
virtual PacketType GetType() const {
return PacketType::ConnexionInfo;
return GetField<ConnexionInfoFieldsE, ConnexionInfoFieldsE::m_ConnectionID>();
}
};

View File

@@ -5,11 +5,21 @@
* \brief File containing the blitz::protocol::DisconnectPacket class
*/
#include "blitz/protocol/Protocol.h"
#include <sp/default/DefaultPacket.h>
#include <sp/protocol/Field.h>
#include <sp/protocol/MessageBase.h>
namespace blitz {
namespace protocol {
enum class DisconnectFieldsE {
m_Reason = 0,
};
using DisconnectFields = std::tuple<
std::string //<- m_Reason
>;
/**
* \class DisconnectPacket
* \brief Packet for disconnecting from the server.
@@ -22,34 +32,16 @@ namespace protocol {
* |--------------------|-------------------|-------------------------------|
* | m_Reason | std::string | The reason for disconnection |
*/
class DisconnectPacket : public ConcretePacket<DisconnectPacket> {
private:
std::string m_Reason; // only when sent from server
public:
/**
* \brief Default constructor.
*/
DisconnectPacket() {}
/**
* \brief Constructor.
* \param reason The reason for disconnection.
*/
DisconnectPacket(std::string reason) : m_Reason(reason) {}
virtual ~DisconnectPacket() {}
virtual DataBuffer Serialize(bool packetID = true) const;
virtual void Deserialize(DataBuffer& data);
DeclarePacket(Disconnect){
public:
PacketConstructor(Disconnect)
/**
* \brief Get the reason for disconnection.
* \return The reason for disconnection.
*/
const std::string& GetReason() const {
return m_Reason;
}
virtual PacketType GetType() const {
return PacketType::Disconnect;
return GetField<DisconnectFieldsE, DisconnectFieldsE::m_Reason>();
}
};

View File

@@ -5,12 +5,21 @@
* \brief File containing the blitz::protocol::KeepAlivePacket class
*/
#include "blitz/protocol/VarInt.h"
#include "blitz/protocol/Protocol.h"
#include <sp/default/DefaultPacket.h>
#include <sp/protocol/Field.h>
#include <sp/protocol/MessageBase.h>
namespace blitz {
namespace protocol {
enum class KeepAliveFieldsE {
KeepAliveId = 0,
};
using KeepAliveFields = std::tuple<
sp::VarInt //<- KeepAliveId
>;
/**
* \class KeepAlivePacket
* \brief Packet sent to measure the health of a connexion. \n
@@ -25,30 +34,18 @@ namespace protocol {
* | Keep Alive ID | VarInt | The server generates a random ID, the client must respond with the same |
*
*/
class KeepAlivePacket : public ConcretePacket<KeepAlivePacket> {
private:
VarInt m_AliveID;
public:
KeepAlivePacket() {}
KeepAlivePacket(std::uint64_t aliveID) : m_AliveID(aliveID) {}
virtual ~KeepAlivePacket() {}
virtual DataBuffer Serialize(bool packetID = true) const;
virtual void Deserialize(DataBuffer& data);
DeclarePacket(KeepAlive){
public:
PacketConstructor(KeepAlive)
/**
* \brief Getter of the alive ID
* \return The alive ID
*/
std::uint64_t GetAliveID() const {
return m_AliveID.GetValue();
}
virtual PacketType GetType() const {
return PacketType::KeepAlive;
std::uint64_t GetAliveId() const {
return GetField<KeepAliveFieldsE, KeepAliveFieldsE::KeepAliveId>().GetValue();
}
};
} // namespace protocol
} // namespace blitz
} // namespace protocol
} // namespace blitz

View File

@@ -6,11 +6,21 @@
*/
#include "blitz/common/Defines.h"
#include "blitz/protocol/Protocol.h"
#include <sp/default/DefaultPacket.h>
#include <sp/protocol/Field.h>
#include <sp/protocol/MessageBase.h>
namespace blitz {
namespace protocol {
enum class PlayerDeathFieldsE {
m_PlayerID = 0,
};
using PlayerDeathFields = std::tuple<
game::PlayerID //<- m_PlayerID
>;
/**
* \class PlayerDeathPacket
* \brief Packet for when a player leaves the game.
@@ -23,35 +33,16 @@ namespace protocol {
* |--------------------|-------------------|-------------------------------|
* | m_PlayerID | PlayerID |The ID of the player that died |
*/
class PlayerDeathPacket : public ConcretePacket<PlayerDeathPacket> {
private:
game::PlayerID m_PlayerID;
public:
/**
* \brief Default constructor.
*/
PlayerDeathPacket() {}
/**
* \brief Constructor.
* \param playerID The ID of the player that died.
*/
PlayerDeathPacket(game::PlayerID playerID) : m_PlayerID(playerID) {}
virtual ~PlayerDeathPacket() {}
virtual DataBuffer Serialize(bool packetID = true) const;
virtual void Deserialize(DataBuffer& data);
DeclarePacket(PlayerDeath){
public:
PacketConstructor(PlayerDeath)
/**
* \brief Get the ID of the player that died.
* \return The ID of the player that died.
*/
game::PlayerID GetPlayerID() const {
return m_PlayerID;
}
virtual PacketType GetType() const {
return PacketType::PlayerDeath;
return GetField<PlayerDeathFieldsE, PlayerDeathFieldsE::m_PlayerID>();
}
};

View File

@@ -6,11 +6,23 @@
*/
#include "blitz/common/Defines.h"
#include "blitz/protocol/Protocol.h"
#include <sp/default/DefaultPacket.h>
#include <sp/protocol/Field.h>
#include <sp/protocol/MessageBase.h>
namespace blitz {
namespace protocol {
enum class PlayerJoinFieldsE {
m_PlayerID = 0,
m_PlayerName,
};
using PlayerJoinFields = std::tuple<
game::PlayerID, //<- m_PlayerID
std::string //<- m_PlayerName
>;
/**
* \class PlayerJoinPacket
* \brief Packet sent when a new player joins the game
@@ -25,25 +37,16 @@ namespace protocol {
* | Player Name | std::string | Name of the player who joined |
*
*/
class PlayerJoinPacket : public ConcretePacket<PlayerJoinPacket> {
private:
game::PlayerID m_PlayerID;
std::string m_PlayerName;
public:
PlayerJoinPacket() {}
PlayerJoinPacket(game::PlayerID playerID, const std::string& playerName) : m_PlayerID(playerID), m_PlayerName(playerName) {}
virtual ~PlayerJoinPacket() {}
virtual DataBuffer Serialize(bool packetID = true) const;
virtual void Deserialize(DataBuffer& data);
DeclarePacket(PlayerJoin){
public:
PacketConstructor(PlayerJoin)
/**
* \brief Getter of the player id
* \return The ID of the player
*/
* \brief Get the ID of the player that died.
* \return The ID of the player that died.
*/
game::PlayerID GetPlayerID() const {
return m_PlayerID;
return GetField<PlayerJoinFieldsE, PlayerJoinFieldsE::m_PlayerID>();
}
/**
@@ -51,11 +54,7 @@ class PlayerJoinPacket : public ConcretePacket<PlayerJoinPacket> {
* \return The name of the player
*/
const std::string& GetPlayerName() const {
return m_PlayerName;
}
virtual PacketType GetType() const {
return PacketType::PlayerJoin;
return GetField<PlayerJoinFieldsE, PlayerJoinFieldsE::m_PlayerName>();
}
};

View File

@@ -6,11 +6,22 @@
*/
#include "blitz/common/Defines.h"
#include "blitz/protocol/Protocol.h"
#include <sp/default/DefaultPacket.h>
#include <sp/protocol/Field.h>
#include <sp/protocol/MessageBase.h>
namespace blitz {
namespace protocol {
enum class PlayerLeaveFieldsE {
m_PlayerID = 0,
};
using PlayerLeaveFields = std::tuple<
game::PlayerID //<- m_PlayerID
>;
/**
* \class PlayerLeavePacket
* \brief Packet for when a player leaves the game.
@@ -23,35 +34,16 @@ namespace protocol {
* |--------------------|-------------------|-------------------------------|
* | m_PlayerID | PlayerID |The ID of the player that left |
*/
class PlayerLeavePacket : public ConcretePacket<PlayerLeavePacket> {
private:
game::PlayerID m_PlayerID;
public:
DeclarePacket(PlayerLeave){
public:
PacketConstructor(PlayerLeave)
/**
* \brief Default constructor.
*/
PlayerLeavePacket() {}
/**
* \brief Constructor.
* \param playerID The ID of the player that left.
*/
PlayerLeavePacket(game::PlayerID playerID) : m_PlayerID(playerID) {}
virtual ~PlayerLeavePacket() {}
virtual DataBuffer Serialize(bool packetID = true) const;
virtual void Deserialize(DataBuffer& data);
/**
* \brief Get the ID of the player that left.
* \return The ID of the player that left.
*/
* \brief Get the ID of the player that left.
* \return The ID of the player that left.
*/
game::PlayerID GetPlayerID() const {
return m_PlayerID;
}
virtual PacketType GetType() const {
return PacketType::PlayerLeave;
return GetField<PlayerLeaveFieldsE, PlayerLeaveFieldsE::m_PlayerID>();
}
};

View File

@@ -7,7 +7,10 @@
#include <map>
#include "blitz/protocol/Protocol.h"
#include <sp/default/DefaultPacket.h>
#include <sp/protocol/Field.h>
#include <sp/protocol/MessageBase.h>
#include <sp/protocol/MessagePrinter.h>
namespace blitz {
namespace protocol {
@@ -20,44 +23,35 @@ struct PlayerInfo {
std::string m_Name;
};
typedef std::map<std::uint8_t, PlayerInfo> PlayerList;
using PlayerMap = std::map<std::uint8_t, PlayerInfo>;
/**
* \class PlayerListPacket
* \brief Packet for sending the list of players.
* \todo PACKET STRUCTURE
*/
class PlayerListPacket : public ConcretePacket<PlayerListPacket> {
private:
PlayerList m_Players;
public:
/**
* \brief Default constructor.
*/
PlayerListPacket() {}
/**
* \brief Constructor.
* \param players The list of players.
*/
PlayerListPacket(const PlayerList& players) : m_Players(players) {}
virtual ~PlayerListPacket() {}
virtual DataBuffer Serialize(bool packetID = true) const;
virtual void Deserialize(DataBuffer& data);
enum class PlayerListFieldsE {
m_PlayerList = 0,
};
using PlayerListFields = std::tuple<
PlayerMap //<- m_PlayerList
>;
DeclarePacket(PlayerList){
public:
PacketConstructor(PlayerList)
/**
* \brief Get the list of players.
* \return The list of players.
*/
const PlayerList& GetPlayers() const {
return m_Players;
}
virtual PacketType GetType() const {
return PacketType::PlayerList;
const PlayerMap& GetPlayers() const {
return GetField<PlayerListFieldsE, PlayerListFieldsE::m_PlayerList>();
}
};
} // namespace protocol
} // namespace blitz
namespace sp {
template <>
inline std::string PrintData(const blitz::protocol::PlayerInfo& a_Config) {
return "{m_Name=" + PrintData(a_Config.m_Name) + "}";
}
} // namespace sp

View File

@@ -5,11 +5,21 @@
* \brief File containing the blitz::protocol::PlayerLoginPacket class
*/
#include "blitz/protocol/Protocol.h"
#include <sp/default/DefaultPacket.h>
#include <sp/protocol/Field.h>
#include <sp/protocol/MessageBase.h>
namespace blitz {
namespace protocol {
enum class PlayerLoginFieldsE {
m_PlayerName = 0,
};
using PlayerLoginFields = std::tuple<
std::string //<- m_PlayerName
>;
/**
* \class PlayerLoginPacket
* \brief Packet for when a player logs in.
@@ -22,35 +32,16 @@ namespace protocol {
* |--------------------|-------------------|----------------------------------|
* | Player Name | std::string | Name of the player that logged in|
*/
class PlayerLoginPacket : public ConcretePacket<PlayerLoginPacket> {
private:
std::string m_PlayerName;
public:
/**
* \brief Default constructor.
*/
PlayerLoginPacket() {}
/**
* \brief Constructor.
* \param playerName The name of the player that logged in.
*/
PlayerLoginPacket(std::string playerName) : m_PlayerName(playerName) {}
virtual ~PlayerLoginPacket() {}
virtual DataBuffer Serialize(bool packetID = true) const;
virtual void Deserialize(DataBuffer& data);
DeclarePacket(PlayerLogin){
public:
PacketConstructor(PlayerLogin)
/**
* \brief Get the name of the player that logged in.
* \return The name of the player that logged in.
*/
const std::string& GetPlayerName() const {
return m_PlayerName;
}
virtual PacketType GetType() const {
return PacketType::PlayerLogin;
return GetField<PlayerLoginFieldsE, PlayerLoginFieldsE::m_PlayerName>();
}
};

View File

@@ -7,11 +7,27 @@
#include "blitz/common/Defines.h"
#include "blitz/maths/Vector.h"
#include "blitz/protocol/Protocol.h"
#include <sp/default/DefaultPacket.h>
#include <sp/protocol/Field.h>
#include <sp/protocol/MessageBase.h>
namespace blitz {
namespace protocol {
enum class PlayerPositionAndRotationFieldsE {
m_PlayerID = 0,
m_Position,
m_Yaw,
m_Pitch,
};
using PlayerPositionAndRotationFields = std::tuple<
game::PlayerID, //<- m_PlayerID
Vec3f, //<- m_Position
float, //<- m_Yaw
float //<- m_Pitch
>;
/**
* \class PlayerPositionAndRotationPacket
* \brief Packet for sending a player's position and rotation.
@@ -27,37 +43,16 @@ namespace protocol {
* | Yaw | float | Yaw of the player |
* | Pitch | float | Pitch of the player |
*/
class PlayerPositionAndRotationPacket : public ConcretePacket<PlayerPositionAndRotationPacket> {
private:
game::PlayerID m_Player; // only used when sent to client
Vec3f m_Position;
float m_Yaw, m_Pitch;
public:
/**
* \brief Default constructor.
*/
PlayerPositionAndRotationPacket() {}
/**
* \brief Constructor.
* \param position The position of the player.
* \param yaw The yaw of the player.
* \param pitch The pitch of the player.
* \param player The ID of the player.
*/
PlayerPositionAndRotationPacket(const Vec3f& position, float yaw, float pitch, game::PlayerID player = 0) :
m_Player(player), m_Position(position), m_Yaw(yaw), m_Pitch(pitch) {}
virtual ~PlayerPositionAndRotationPacket() {}
virtual DataBuffer Serialize(bool packetID = true) const;
virtual void Deserialize(DataBuffer& data);
DeclarePacket(PlayerPositionAndRotation){
public:
PacketConstructor(PlayerPositionAndRotation)
/**
* \brief Get the position of the player.
* \return The position of the player.
*/
const Vec3f& GetPosition() const {
return m_Position;
return GetField<PlayerPositionAndRotationFieldsE, PlayerPositionAndRotationFieldsE::m_Position>();
}
/**
@@ -65,7 +60,7 @@ class PlayerPositionAndRotationPacket : public ConcretePacket<PlayerPositionAndR
* \return The yaw of the player.
*/
float GetYaw() const {
return m_Yaw;
return GetField<PlayerPositionAndRotationFieldsE, PlayerPositionAndRotationFieldsE::m_Yaw>();
}
/**
@@ -73,7 +68,7 @@ class PlayerPositionAndRotationPacket : public ConcretePacket<PlayerPositionAndR
* \return The pitch of the player.
*/
float GetPitch() const {
return m_Pitch;
return GetField<PlayerPositionAndRotationFieldsE, PlayerPositionAndRotationFieldsE::m_Pitch>();
}
/**
@@ -81,11 +76,7 @@ class PlayerPositionAndRotationPacket : public ConcretePacket<PlayerPositionAndR
* \return The ID of the player.
*/
game::PlayerID GetPlayer() const {
return m_Player;
}
virtual PacketType GetType() const {
return PacketType::PlayerPositionAndRotation;
return GetField<PlayerPositionAndRotationFieldsE, PlayerPositionAndRotationFieldsE::m_PlayerID>();
}
};

View File

@@ -6,11 +6,27 @@
*/
#include "blitz/game/Player.h"
#include "blitz/protocol/Protocol.h"
#include <sp/default/DefaultPacket.h>
#include <sp/protocol/Field.h>
#include <sp/protocol/MessageBase.h>
namespace blitz {
namespace protocol {
enum class PlayerShootFieldsE {
m_PlayerID = 0,
m_Position,
m_Yaw,
m_Pitch,
};
using PlayerShootFields = std::tuple<
game::PlayerID, //<- m_PlayerID
Vec3f, //<- m_Position
float, //<- m_Yaw
float //<- m_Pitch
>;
/**
* \class PlayerShootPacket
* \brief Packet for when a player shoots.
@@ -26,37 +42,16 @@ namespace protocol {
* | Yaw | float | Yaw of the player |
* | Pitch | float | Pitch of the player |
*/
class PlayerShootPacket : public ConcretePacket<PlayerShootPacket> {
private:
game::PlayerID m_Player; // only used when sent to client
Vec3f m_Position;
float m_Yaw, m_Pitch;
public:
/**
* \brief Default constructor.
*/
PlayerShootPacket() {}
/**
* \brief Constructor.
* \param position The position of the player.
* \param yaw The yaw of the player.
* \param pitch The pitch of the player.
* \param player The ID of the player.
*/
PlayerShootPacket(Vec3f position, float yaw, float pitch, game::PlayerID player = 0) :
m_Player(player), m_Position(position), m_Yaw(yaw), m_Pitch(pitch) {}
virtual ~PlayerShootPacket() {}
virtual DataBuffer Serialize(bool packetID = true) const;
virtual void Deserialize(DataBuffer& data);
DeclarePacket(PlayerShoot){
public:
PacketConstructor(PlayerShoot)
/**
* \brief Get the position of the player.
* \return The position of the player.
*/
const Vec3f& GetPosition() const {
return m_Position;
return GetField<PlayerShootFieldsE, PlayerShootFieldsE::m_Position>();
}
/**
@@ -64,7 +59,7 @@ class PlayerShootPacket : public ConcretePacket<PlayerShootPacket> {
* \return The yaw of the player.
*/
float GetYaw() const {
return m_Yaw;
return GetField<PlayerShootFieldsE, PlayerShootFieldsE::m_Yaw>();
}
/**
@@ -72,7 +67,7 @@ class PlayerShootPacket : public ConcretePacket<PlayerShootPacket> {
* \return The pitch of the player.
*/
float GetPitch() const {
return m_Pitch;
return GetField<PlayerShootFieldsE, PlayerShootFieldsE::m_Pitch>();
}
/**
@@ -80,11 +75,7 @@ class PlayerShootPacket : public ConcretePacket<PlayerShootPacket> {
* \return The ID of the player.
*/
game::PlayerID GetPlayer() const {
return m_Player;
}
virtual PacketType GetType() const {
return PacketType::PlayerShoot;
return GetField<PlayerShootFieldsE, PlayerShootFieldsE::m_PlayerID>();
}
};

View File

@@ -7,11 +7,23 @@
#include "blitz/common/Defines.h"
#include "blitz/game/Player.h"
#include "blitz/protocol/Protocol.h"
#include <sp/default/DefaultPacket.h>
#include <sp/protocol/Field.h>
#include <sp/protocol/MessageBase.h>
namespace blitz {
namespace protocol {
enum class PlayerStatsFieldsE {
m_PlayerID = 0,
m_PlayerStats,
};
using PlayerStatsFields = std::tuple<
game::PlayerID, //<- m_PlayerID
game::PlayerStats //<- m_PlayerStats
>;
/**
* \class PlayerStatsPacket
* \brief Packet for sending player stats.
@@ -25,33 +37,16 @@ namespace protocol {
* | Player ID | PlayerID | Id of the player |
* | Player Stats | PlayerStats | Stats of the player |
*/
class PlayerStatsPacket : public ConcretePacket<PlayerStatsPacket> {
private:
game::PlayerID m_PlayerID;
game::PlayerStats m_PlayerStats;
public:
/**
* \brief Default constructor.
*/
PlayerStatsPacket() {}
/**
* \brief Constructor.
* \param playerID The ID of the player.
* \param stats The stats of the player.
*/
PlayerStatsPacket(game::PlayerID playerID, const game::PlayerStats& stats) : m_PlayerID(playerID), m_PlayerStats(stats) {}
virtual ~PlayerStatsPacket() {}
virtual DataBuffer Serialize(bool packetID = true) const;
virtual void Deserialize(DataBuffer& data);
DeclarePacket(PlayerStats){
public:
PacketConstructor(PlayerStats)
/**
* \brief Getter of the player id
* \return The ID of the player
*/
game::PlayerID GetPlayerID() const {
return m_PlayerID;
return GetField<PlayerStatsFieldsE, PlayerStatsFieldsE::m_PlayerID>();
}
/**
@@ -59,11 +54,7 @@ class PlayerStatsPacket : public ConcretePacket<PlayerStatsPacket> {
* \return The stats of the player
*/
const game::PlayerStats& GetPlayerStats() const {
return m_PlayerStats;
}
virtual PacketType GetType() const {
return PacketType::PlayerStats;
return GetField<PlayerStatsFieldsE, PlayerStatsFieldsE::m_PlayerStats>();
}
};

View File

@@ -6,11 +6,21 @@
*/
#include "blitz/game/Game.h"
#include "blitz/protocol/Protocol.h"
#include <sp/default/DefaultPacket.h>
#include <sp/protocol/Field.h>
#include <sp/protocol/MessageBase.h>
namespace blitz {
namespace protocol {
enum class ServerConfigFieldsE {
m_GameConfig = 0,
};
using ServerConfigFields = std::tuple<
game::GameConfig //<- m_GameConfig
>;
/**
* \class ServerConfigPacket
* \brief Packet for sending the server configuration.
@@ -23,35 +33,16 @@ namespace protocol {
* |--------------------|-------------------|-------------------------------|
* | Game Config | GameConfig | The game configuration |
*/
class ServerConfigPacket : public ConcretePacket<ServerConfigPacket> {
private:
game::GameConfig m_GameConfig;
public:
/**
* \brief Default constructor.
*/
ServerConfigPacket() {}
/**
* \brief Constructor.
* \param GameConfig The game configuration.
*/
ServerConfigPacket(const game::GameConfig& GameConfig) : m_GameConfig(GameConfig) {}
virtual ~ServerConfigPacket() {}
virtual DataBuffer Serialize(bool packetID = true) const;
virtual void Deserialize(DataBuffer& data);
DeclarePacket(ServerConfig){
public:
PacketConstructor(ServerConfig)
/**
* \brief Getter of the game configuration
* \return The game configuration
*/
game::GameConfig GetGameConfig() const {
return m_GameConfig;
}
virtual PacketType GetType() const {
return PacketType::ServerConfig;
return GetField<ServerConfigFieldsE, ServerConfigFieldsE::m_GameConfig>();
}
};

View File

@@ -5,11 +5,25 @@
* \brief File containing the blitz::protocol::ServerTpsPacket class
*/
#include "blitz/protocol/Protocol.h"
#include <sp/default/DefaultPacket.h>
#include <sp/protocol/Field.h>
#include <sp/protocol/MessageBase.h>
namespace blitz {
namespace protocol {
enum class ServerTpsFieldsE {
m_TPS = 0,
m_MSPT,
m_PacketSendTime,
};
using ServerTpsFields = std::tuple<
float, //<- m_TPS
float, //<- m_MSPT
std::uint64_t //<- m_PacketSendTime
>;
/**
* \class ServerTpsPacket
* \brief Packet for sending server TPS (Tick per second) and MSPT (Milliseconds per tick).
@@ -24,34 +38,16 @@ namespace protocol {
* | Mspt | float | Server MSPT |
* | PacketSendTime | uint64_t | Time the packet was sent |
*/
class ServerTpsPacket : public ConcretePacket<ServerTpsPacket> {
private:
float m_TPS;
float m_MSPT;
std::uint64_t m_PacketSendTime; // used to calculate ping
public:
/**
* \brief Default constructor.
*/
ServerTpsPacket() {}
/**
* \brief Constructor.
* \param tps The server TPS.
* \param mspt The server MSPT.
* \param sendTime The time the packet was sent.
*/
ServerTpsPacket(float tps, float mspt, std::uint64_t sendTime) : m_TPS(tps), m_MSPT(mspt), m_PacketSendTime(sendTime) {}
virtual ~ServerTpsPacket() {}
virtual DataBuffer Serialize(bool packetID = true) const;
virtual void Deserialize(DataBuffer& data);
DeclarePacket(ServerTps){
public:
PacketConstructor(ServerTps)
/**
* \brief Get the server TPS.
* \return The server TPS.
*/
float GetTPS() const {
return m_TPS;
return GetField<ServerTpsFieldsE, ServerTpsFieldsE::m_TPS>();
}
/**
@@ -59,7 +55,7 @@ class ServerTpsPacket : public ConcretePacket<ServerTpsPacket> {
* \return The server MSPT.
*/
float GetMSPT() const {
return m_MSPT;
return GetField<ServerTpsFieldsE, ServerTpsFieldsE::m_MSPT>();
}
/**
@@ -68,11 +64,7 @@ class ServerTpsPacket : public ConcretePacket<ServerTpsPacket> {
* \todo Calculate ping.
*/
std::uint64_t GetPacketSendTime() const {
return m_PacketSendTime;
}
virtual PacketType GetType() const {
return PacketType::ServerTps;
return GetField<ServerTpsFieldsE, ServerTpsFieldsE::m_PacketSendTime>();
}
};

View File

@@ -6,11 +6,23 @@
*/
#include "blitz/game/Game.h"
#include "blitz/protocol/Protocol.h"
#include <sp/default/DefaultPacket.h>
#include <sp/protocol/Field.h>
#include <sp/protocol/MessageBase.h>
namespace blitz {
namespace protocol {
enum class UpdateGameStateFieldsE {
m_GameState = 0,
m_TimeRemaining,
};
using UpdateGameStateFields = std::tuple<
game::GameState, //<- m_GameState
std::uint64_t //<- m_TimeRemaining
>;
/**
* \class UpdateGameStatePacket
* \brief Packet for updating the game state.
@@ -24,34 +36,16 @@ 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 ConcretePacket<UpdateGameStatePacket> {
private:
game::GameState m_GameState;
std::uint64_t m_TimeRemaining;
public:
/**
* \brief Default constructor.
*/
UpdateGameStatePacket() {}
/**
* \brief Constructor.
* \param a_GameState The new game state.
* \param a_TimeRemaining The time remaining in the current game state.
*/
UpdateGameStatePacket(game::GameState a_GameState, std::uint64_t a_TimeRemaining = 0) :
m_GameState(a_GameState), m_TimeRemaining(a_TimeRemaining) {}
virtual ~UpdateGameStatePacket() {}
virtual DataBuffer Serialize(bool packetID = true) const;
virtual void Deserialize(DataBuffer& data);
DeclarePacket(UpdateGameState){
public:
PacketConstructor(UpdateGameState)
/**
* \brief Get the new game state.
* \return The new game state.
*/
game::GameState GetGameState() const {
return m_GameState;
return GetField<UpdateGameStateFieldsE, UpdateGameStateFieldsE::m_GameState>();
}
/**
@@ -59,11 +53,7 @@ class UpdateGameStatePacket : public ConcretePacket<UpdateGameStatePacket> {
* \return The time remaining in the current game state.
*/
std::uint64_t GetTimeRemaining() const {
return m_TimeRemaining;
}
virtual PacketType GetType() const {
return PacketType::UpdateGameState;
return GetField<UpdateGameStateFieldsE, UpdateGameStateFieldsE::m_TimeRemaining>();
}
};

View File

@@ -5,11 +5,21 @@
* \brief File containing the blitz::protocol::UpdateHealthPacket class
*/
#include "blitz/protocol/Protocol.h"
#include <sp/default/DefaultPacket.h>
#include <sp/protocol/Field.h>
#include <sp/protocol/MessageBase.h>
namespace blitz {
namespace protocol {
enum class UpdateHealthFieldsE {
m_NewHealth = 0,
};
using UpdateHealthFields = std::tuple<
float //<- m_NewHealth
>;
/**
* \class UpdateHealthPacket
* \brief Packet for updating the health of a player.
@@ -22,35 +32,16 @@ namespace protocol {
* |--------------------|-------------------|-------------------------------|
* | m_NewHealth | float | The new health value |
*/
class UpdateHealthPacket : public ConcretePacket<UpdateHealthPacket> {
private:
float m_NewHealth;
public:
DeclarePacket(UpdateHealth){
public:
PacketConstructor(UpdateHealth)
/**
* \brief Default constructor.
* \brief Get the ID of the player that left.
* \return The ID of the player that left.
*/
UpdateHealthPacket() {}
/**
* \brief Constructor.
* \param newHealth The new health value.
*/
UpdateHealthPacket(float newHealth) : m_NewHealth(newHealth) {}
virtual ~UpdateHealthPacket() {}
virtual DataBuffer Serialize(bool packetID = true) const;
virtual void Deserialize(DataBuffer& data);
/**
* \brief Get the new health value.
* \return The new health value.
*/
float GetNewHealth() const {
return m_NewHealth;
}
virtual PacketType GetType() const {
return PacketType::UpdateHealth;
game::PlayerID GetNewHealth() const {
return GetField<UpdateHealthFieldsE, UpdateHealthFieldsE::m_NewHealth>();
}
};

View File

@@ -1,81 +0,0 @@
#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,6 +1,8 @@
#pragma once
#include "client/BaseClient.h"
#include "blitz/common/Defines.h"
#include "blitz/misc/ObjectNotifier.h"
#include "blitz/misc/Time.h"
#include "client/Listeners.h"
#include "client/config/BlitzConfig.h"
#include <cstdint>
@@ -9,29 +11,51 @@
namespace blitz {
static const int PlayerUpdatePosRate = 50;
namespace server {
class Server;
} // namespace server
namespace client {
class ClientConnexion;
class ClientGame;
// Singleton
class Client : public BaseClient, public PlayerInputListener, public ClientListener {
class Client : public utils::ObjectNotifier<client::ClientListener>, public client::PlayerInputListener {
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();
virtual void Update() override;
void Update();
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;
virtual void OnGameLeave() override;
game::PlayerID GetPlayerID() const;
client::ClientGame* GetGame() {
return m_Game.get();
}
BlitzConfig* GetConfig() {
return &m_Config;
@@ -44,6 +68,11 @@ class Client : public BaseClient, public PlayerInputListener, public ClientListe
}
void UpdateServerConfig();
private:
void Reset();
void UpdatePosition(std::uint64_t delta);
};
} // namespace client

View File

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

View File

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

View File

@@ -1,12 +1,12 @@
#pragma once
#include "blitz/common/NonCopyable.h"
#include <sp/common/NonCopyable.h>
#include "blitz/maths/Vector.h"
namespace blitz {
namespace audio {
class AudioListener : private NonCopyable {
class AudioListener : private sp::NonCopyable {
public:
AudioListener();
~AudioListener();

View File

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

View File

@@ -3,34 +3,36 @@
#include "blitz/game/Game.h"
#include "blitz/game/LeaderBoard.h"
#include "blitz/protocol/PacketHandler.h"
#include "blitz/protocol/PacketDispatcher.h"
#include <vector>
namespace blitz {
namespace client {
class BaseClient;
class Client;
class ClientGame : public game::Game, public protocol::PacketHandler {
private:
BaseClient& m_Client;
Client* m_Client;
game::LeaderBoard m_LeaderBoard;
protocol::PacketDispatcher& m_Dispatcher;
public:
ClientGame(BaseClient& client, protocol::PacketDispatcher& dispatcher);
ClientGame(Client* 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 Handle(const protocol::PlayerDeathPacket& packet) override;
virtual void Handle(const protocol::PlayerJoinPacket& packet) override;
virtual void Handle(const protocol::PlayerLeavePacket& packet) override;
virtual void Handle(const protocol::PlayerListPacket& packet) override;
virtual void Handle(const protocol::PlayerPositionAndRotationPacket& packet) override;
virtual void Handle(const protocol::PlayerShootPacket& packet) override;
virtual void Handle(const protocol::UpdateHealthPacket& packet) override;
virtual void Handle(const protocol::PlayerStatsPacket& packet) override;
virtual void Handle(const protocol::UpdateGameStatePacket& packet) override;
virtual void Handle(const protocol::ServerConfigPacket& packet) override;
virtual void AddPlayer(game::PlayerID player, const std::string& name) override;
virtual void RemovePlayer(game::PlayerID player) override;
@@ -41,6 +43,10 @@ class ClientGame : public game::Game, public protocol::PacketHandler {
private:
void RegisterHandlers();
protocol::PacketDispatcher& GetDispatcher() {
return m_Dispatcher;
}
};
} // namespace client

View File

@@ -1,6 +1,6 @@
#pragma once
#include "blitz/protocol/packets/ChatPacket.h"
#include "blitz/protocol/Color.h"
#include <string>
namespace blitz {

View File

@@ -1,6 +1,6 @@
#pragma once
#include "blitz/common/NonCopyable.h"
#include <sp/common/NonCopyable.h>
#include <vector>
@@ -13,7 +13,7 @@ struct VertexAttribPointer {
unsigned int m_Offset;
};
class ElementBuffer : private NonCopyable {
class ElementBuffer : private sp::NonCopyable {
private:
unsigned int m_ID = 0;
std::size_t m_TriangleCount;
@@ -35,7 +35,7 @@ class ElementBuffer : private NonCopyable {
}
};
class VertexBuffer : private NonCopyable {
class VertexBuffer : private sp::NonCopyable {
private:
unsigned int m_ID = 0, m_DataStride;
std::vector<VertexAttribPointer> m_VertexAttribs;
@@ -56,7 +56,7 @@ class VertexBuffer : private NonCopyable {
void BindVertexAttribs() const;
};
class VertexArray : private NonCopyable {
class VertexArray : private sp::NonCopyable {
private:
unsigned int m_ID = 0;
ElementBuffer m_ElementBuffer;

View File

@@ -35,7 +35,7 @@ typedef std::map<std::uint8_t, std::unique_ptr<ServerConnexion>> ConnexionMap;
*/
class Server {
private:
network::TCPListener m_Listener;
std::unique_ptr<network::TCPListener> m_Listener;
ConnexionMap m_Connections;
utils::TickCounter m_TickCounter;
@@ -91,7 +91,7 @@ class Server {
* \brief Broadcast a packet to all connexions
* \param packet The packet
*/
void BroadcastPacket(const protocol::Packet* packet);
void BroadcastPacket(const protocol::Packet& packet);
/**
* \brief Broadcast a chat message
* \param msg The message

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, std::unique_ptr<network::TCPSocket>&& socket, std::uint8_t id);
/**
* \brief Move constructor
*/
@@ -72,14 +72,14 @@ 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 Handle(const protocol::PlayerLoginPacket& packet) override;
virtual void Handle(const protocol::KeepAlivePacket& packet) override;
virtual void Handle(const protocol::DisconnectPacket& packet) override;
virtual void Handle(const protocol::ChatPacket& packet) override;
virtual void Handle(const protocol::PlayerPositionAndRotationPacket& packet) override;
virtual void Handle(const protocol::PlayerShootPacket& packet) override;
virtual bool UpdateSocket() override;
virtual bool UpdateSocket() override;
private:
void RegisterHandlers();

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

@@ -1,100 +0,0 @@
#include "blitz/common/DataBuffer.h"
#include <fstream>
#include <iomanip>
#include <sstream>
#include "blitz/misc/Format.h"
#include "blitz/misc/Log.h"
namespace blitz {
DataBuffer::DataBuffer() : m_ReadOffset(0) {}
DataBuffer::DataBuffer(const DataBuffer& other) : m_Buffer(other.m_Buffer), m_ReadOffset(other.m_ReadOffset) {}
DataBuffer::DataBuffer(DataBuffer&& other) : m_Buffer(std::move(other.m_Buffer)), m_ReadOffset(std::move(other.m_ReadOffset)) {}
DataBuffer::DataBuffer(const std::string& str) : m_Buffer(str.begin(), str.end()), m_ReadOffset(0) {}
DataBuffer::DataBuffer(const DataBuffer& other, Data::difference_type offset) : m_ReadOffset(0) {
m_Buffer.reserve(other.GetSize() - static_cast<std::size_t>(offset));
std::copy(other.m_Buffer.begin() + offset, other.m_Buffer.end(), std::back_inserter(m_Buffer));
}
DataBuffer& DataBuffer::operator=(const DataBuffer& other) {
m_Buffer = other.m_Buffer;
m_ReadOffset = other.m_ReadOffset;
return *this;
}
DataBuffer& DataBuffer::operator=(DataBuffer&& other) {
m_Buffer = std::move(other.m_Buffer);
m_ReadOffset = std::move(other.m_ReadOffset);
return *this;
}
void DataBuffer::SetReadOffset(std::size_t pos) {
assert(pos <= GetSize());
m_ReadOffset = pos;
}
std::size_t DataBuffer::GetSize() const {
return m_Buffer.size();
}
std::size_t DataBuffer::GetRemaining() const {
return m_Buffer.size() - m_ReadOffset;
}
DataBuffer::iterator DataBuffer::begin() {
return m_Buffer.begin();
}
DataBuffer::iterator DataBuffer::end() {
return m_Buffer.end();
}
DataBuffer::const_iterator DataBuffer::begin() const {
return m_Buffer.begin();
}
DataBuffer::const_iterator DataBuffer::end() const {
return m_Buffer.end();
}
std::ostream& operator<<(std::ostream& os, const DataBuffer& buffer) {
for (unsigned char u : buffer)
os << std::hex << std::setfill('0') << std::setw(2) << static_cast<int>(u) << " ";
os << std::dec;
return os;
}
bool DataBuffer::ReadFile(const std::string& fileName) {
try {
std::ifstream file(fileName, std::istream::binary);
std::ostringstream ss;
ss << file.rdbuf();
const std::string& s = ss.str();
m_Buffer = DataBuffer::Data(s.begin(), s.end());
m_ReadOffset = 0;
} catch (std::exception& e) {
utils::LOGE(utils::Format("[IO] Failed to read file %s ! reason : %s", fileName.c_str(), e.what()));
return false;
}
return m_Buffer.size() > 0;
}
bool DataBuffer::WriteFile(const std::string& fileName) const {
try {
std::ofstream file(fileName, std::ostream::binary);
file.write(reinterpret_cast<const char*>(m_Buffer.data()), static_cast<std::streamsize>(m_Buffer.size()));
file.flush();
} catch (std::exception& e) {
utils::LOGE(utils::Format("[IO] Failed to read file %s ! reason : %s", fileName.c_str(), e.what()));
return false;
}
return true;
}
} // namespace blitz

View File

@@ -9,8 +9,9 @@ void LeaderBoard::AddPlayer(Player* player) {
}
void LeaderBoard::RemovePlayer(PlayerID player) {
m_Players.erase(std::remove_if(m_Players.begin(), m_Players.end(), [player](game::Player* p) { return p->GetID() == player; }),
m_Players.end());
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);
}
void LeaderBoard::Update() {

View File

@@ -1,6 +1,6 @@
#include "blitz/misc/Compression.h"
#include "blitz/protocol/VarInt.h"
#include <sp/common/VarInt.h>
#include <cassert>
#include <zlib.h>
@@ -37,7 +37,7 @@ DataBuffer Compress(const DataBuffer& buffer) {
if (buffer.GetSize() < COMPRESSION_THRESHOLD) {
// Don't compress since it's a small packet
protocol::VarInt compressedDataLength = 0;
sp::VarInt compressedDataLength = 0;
std::uint64_t packetLength = compressedDataLength.GetSerializedLength() + buffer.GetSize();
packet << packetLength;
@@ -48,7 +48,7 @@ DataBuffer Compress(const DataBuffer& buffer) {
DataBuffer compressedData = Deflate(buffer.data(), buffer.GetSize());
protocol::VarInt uncompressedDataLength = buffer.GetSize();
sp::VarInt uncompressedDataLength = buffer.GetSize();
std::uint64_t packetLength = uncompressedDataLength.GetSerializedLength() + compressedData.GetSize();
packet << packetLength;
@@ -58,7 +58,7 @@ DataBuffer Compress(const DataBuffer& buffer) {
}
DataBuffer Decompress(DataBuffer& buffer, std::uint64_t packetLength) {
protocol::VarInt uncompressedLength;
sp::VarInt uncompressedLength;
buffer >> uncompressedLength;
std::uint64_t compressedLength = packetLength - uncompressedLength.GetSerializedLength();

View File

@@ -1,67 +1,48 @@
#include "blitz/misc/Compression.h"
#include "blitz/misc/Format.h"
#include "blitz/misc/Log.h"
#include "blitz/misc/Time.h"
#include "blitz/network/Connexion.h"
#include "blitz/protocol/PacketDispatcher.h"
#include "blitz/protocol/PacketFactory.h"
#include "blitz/misc/Log.h"
namespace blitz {
namespace network {
Connexion::Connexion(Connexion&& move) : protocol::PacketHandler(m_Dispatcher), m_Socket(std::move(move.m_Socket)) {}
Connexion::Connexion(TCPSocket&& socket) : TCPStream(std::move(socket), {}) {}
Connexion::Connexion(protocol::PacketDispatcher& dispatcher) : protocol::PacketHandler(dispatcher) {}
Connexion::Connexion(protocol::PacketDispatcher& dispatcher, TCPSocket& socket) :
protocol::PacketHandler(dispatcher), m_Socket(std::move(socket)) {}
bool Connexion::UpdateSocket() {
if (m_Socket.GetStatus() != TCPSocket::Status::Connected)
return false;
while (true) {
DataBuffer buffer;
m_Socket.Receive(buffer, sizeof(std::uint64_t));
if (buffer.GetSize() == 0)
break;
std::uint64_t packetBufferLenght;
buffer >> packetBufferLenght;
m_Socket.Receive(buffer, packetBufferLenght);
DataBuffer decompressed = utils::Decompress(buffer, packetBufferLenght);
protocol::PacketType packetType;
decompressed >> packetType;
const protocol::PacketPtr packet = protocol::PacketFactory::CreatePacket(packetType, decompressed);
GetDispatcher().Dispatch(*packet.get());
}
return true;
}
bool Connexion::Connect(const std::string& address, std::uint16_t port) {
if (!m_Socket.Connect(address, port)) {
return false;
}
m_Socket.SetBlocking(false);
return true;
}
void Connexion::SendPacket(const protocol::Packet* packet) {
network::SendPacket(packet->Serialize(), m_Socket);
// utils::LOGD(utils::Format("Sent packet id %i", packet->GetID()));
}
Connexion::Connexion(Connexion&& move) : TCPStream(std::move(move)) {}
void Connexion::CloseConnection() {
m_Socket.Disconnect();
m_Interface.Disconnect();
}
Connexion::~Connexion() {}
void Connexion::SendPacket(const protocol::Packet& packet) {
SendMessage(packet);
}
bool Connexion::UpdateSocket() {
if (GetSocketStatus() != sp::io::TcpSocket::Status::Connected)
return false;
try {
RecieveMessages();
} catch (sp::io::SocketError& e) {
utils::LOGE(e.what());
return false;
}
return true;
}
/**
* \brief Tries to connect the socket at the specified address and port
* \return Whether this action was succesfull
*/
bool Connexion::Connect(const std::string& address, std::uint16_t port) {
try {
TCPSocket socket(address, port);
m_Interface = std::move(socket);
m_Interface.SetBlocking(false);
} catch(sp::io::SocketError& e) {
return false;
}
return true;
}
} // namespace network
} // namespace blitz

View File

@@ -1,81 +0,0 @@
#include "blitz/network/TCPListener.h"
#include "blitz/misc/Log.h"
#ifndef _WIN32
#define closesocket close
#define SD_BOTH SHUT_RDWR
#define ioctlsocket ioctl
#endif
namespace blitz {
namespace network {
TCPListener::TCPListener() : m_Handle(static_cast<blitz::network::SocketHandle>(INVALID_SOCKET)), m_Port(0), m_MaxConnections(0) {}
TCPListener::~TCPListener() {
Destroy();
}
bool TCPListener::Listen(std::uint16_t port, int maxConnections) {
if ((m_Handle = static_cast<SocketHandle>(socket(AF_INET, SOCK_STREAM, IPPROTO_TCP))) < 0) {
utils::LOGE("[TCPListener] Failed to create server socket !");
return false;
}
struct sockaddr_in address;
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons(port);
if (bind(m_Handle, reinterpret_cast<sockaddr*>(&address), sizeof(address)) < 0)
return false;
if (listen(m_Handle, maxConnections) < 0)
return false;
socklen_t len = sizeof(address);
if (getsockname(m_Handle, reinterpret_cast<sockaddr*>(&address), &len) < 0)
return false;
m_Port = ntohs(address.sin_port);
m_MaxConnections = maxConnections;
return true;
}
bool TCPListener::Accept(TCPSocket& newSocket) {
int addrlen = sizeof(newSocket.m_RemoteAddr);
newSocket.m_Handle = static_cast<SocketHandle>(
accept(m_Handle, reinterpret_cast<sockaddr*>(&newSocket.m_RemoteAddr), reinterpret_cast<socklen_t*>(&addrlen)));
if (newSocket.m_Handle < 0)
return false;
newSocket.SetStatus(TCPSocket::Status::Connected);
newSocket.SetBlocking(false);
return true;
}
void TCPListener::Destroy() {
if (m_Handle > 0)
closesocket(m_Handle);
}
bool TCPListener::Close() {
if (shutdown(m_Handle, SD_BOTH) == 0)
return true;
return false;
}
bool TCPListener::SetBlocking(bool blocking) {
unsigned long mode = !blocking;
if (ioctlsocket(m_Handle, FIONBIO, &mode) < 0)
return false;
return true;
}
} // namespace network
} // namespace blitz

View File

@@ -1,174 +0,0 @@
#include "blitz/network/TCPSocket.h"
#include "blitz/misc/Compression.h"
#include "blitz/misc/Log.h"
#include "blitz/network/Network.h"
#ifdef _WIN32
#define ioctl ioctlsocket
#define WOULDBLOCK WSAEWOULDBLOCK
#define MSG_DONTWAIT 0
#else
#define WOULDBLOCK EWOULDBLOCK
#endif
namespace blitz {
namespace network {
TCPSocket::TCPSocket() :
m_Blocking(false), m_Status(Status::Disconnected), m_Handle(static_cast<SocketHandle>(INVALID_SOCKET)), m_Port(0) {}
TCPSocket::TCPSocket(TCPSocket&& other) {
m_Handle = other.m_Handle;
m_Port = other.m_Port;
m_RemoteAddr = other.m_RemoteAddr;
SetStatus(other.GetStatus());
SetBlocking(other.IsBlocking());
other.m_Handle = static_cast<SocketHandle>(INVALID_SOCKET);
}
TCPSocket::~TCPSocket() {
Disconnect();
}
bool TCPSocket::SetBlocking(bool block) {
unsigned long mode = !block;
if (ioctl(m_Handle, FIONBIO, &mode) < 0) {
return false;
}
m_Blocking = block;
return true;
}
bool TCPSocket::IsBlocking() const {
return m_Blocking;
}
void TCPSocket::SetStatus(TCPSocket::Status status) {
m_Status = status;
}
TCPSocket::Status TCPSocket::GetStatus() const {
return m_Status;
}
std::size_t TCPSocket::Send(DataBuffer& buffer) {
return Send(buffer.data(), buffer.GetSize());
}
void TCPSocket::Disconnect() {
if (m_Handle > 0)
closesocket(m_Handle);
m_Status = Status::Disconnected;
}
bool TCPSocket::Connect(const std::string& host, unsigned short port) {
if (GetStatus() == Status::Connected)
return true;
struct addrinfo hints {};
struct addrinfo* result = nullptr;
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
if (getaddrinfo(host.c_str(), std::to_string(static_cast<int>(port)).c_str(), &hints, &result) != 0) {
utils::LOGE("[TCPSocket] Failed to get address info !");
return false;
}
m_Handle = static_cast<SocketHandle>(socket(AF_INET, SOCK_STREAM, IPPROTO_TCP));
if (m_Handle < 0) {
utils::LOGE("[TCPSocket] Failed to create socket !");
return false;
}
struct addrinfo* ptr = nullptr;
for (ptr = result; ptr != nullptr; ptr = ptr->ai_next) {
struct sockaddr* sockaddr = ptr->ai_addr;
if (connect(m_Handle, sockaddr, sizeof(sockaddr_in)) != 0) {
utils::LOGE("[TCPSocket] Failed to connect with this address !");
continue;
}
m_RemoteAddr = *sockaddr;
break;
}
freeaddrinfo(result);
if (!ptr) {
utils::LOGE("[TCPSocket] Could not find a suitable interface for connecting !");
return false;
}
SetStatus(Status::Connected);
m_Port = port;
return true;
}
size_t TCPSocket::Send(const unsigned char* data, size_t size) {
if (GetStatus() != Status::Connected)
return 0;
std::size_t sent = 0;
while (sent < size) {
int cur = send(m_Handle, reinterpret_cast<const char*>(data + sent), static_cast<int>(size - sent), 0);
if (cur <= 0) {
Disconnect();
SetStatus(Status::Error);
return 0;
}
sent += static_cast<std::size_t>(cur);
}
return sent;
}
std::size_t TCPSocket::Receive(DataBuffer& buffer, std::size_t amount) {
buffer.Resize(amount);
buffer.SetReadOffset(0);
int recvAmount = recv(m_Handle, reinterpret_cast<char*>(buffer.data()), static_cast<int>(amount), 0);
if (recvAmount <= 0) {
#if defined(_WIN32) || defined(WIN32)
int err = WSAGetLastError();
#else
int err = errno;
#endif
if (err == WOULDBLOCK) {
buffer.Clear();
return 0;
}
Disconnect();
buffer.Clear();
SetStatus(Status::Error);
return 0;
}
buffer.Resize(static_cast<std::size_t>(recvAmount));
return static_cast<std::size_t>(recvAmount);
}
DataBuffer TCPSocket::Receive(std::size_t amount) {
DataBuffer buffer;
Receive(buffer, amount);
return buffer;
}
void SendPacket(const DataBuffer& data, network::TCPSocket& socket) {
DataBuffer compressed = utils::Compress(data);
socket.Send(compressed.data(), compressed.GetSize());
}
} // namespace network
} // namespace blitz

View File

@@ -1,6 +1,6 @@
#include "blitz/protocol/packets/ChatPacket.h"
#include "blitz/protocol/Color.h"
#include "blitz/protocol/VarInt.h"
#include <sp/common/VarInt.h>
#include "blitz/maths/Vector.h"
#include "blitz/misc/Log.h"
#include <map>
@@ -19,30 +19,7 @@ const static std::map<std::string, Vec4f> COLORS = {
{"yellow", {1, 1, 0, 1}},
};
DataBuffer ChatPacket::Serialize(bool packetID) const {
DataBuffer data;
WritePacketID(data, packetID);
data << VarInt{m_Message.size()};
for (const auto& part : m_Message) {
data << part.m_Color << part.m_Text;
}
return data;
}
void ChatPacket::Deserialize(DataBuffer& data) {
VarInt partsNumber;
data >> partsNumber;
m_Message.resize(partsNumber.GetValue());
for (std::size_t i = 0; i < partsNumber.GetValue(); ++i) {
data >> m_Message[i].m_Color >> m_Message[i].m_Text;
}
}
std::string ChatPacket::GetTextColor(Vec3uc color) {
std::string GetTextColor(Vec3uc color) {
std::stringstream ss;
ss << std::hex << "\\u";
if (color.r <= 0xF)
@@ -57,7 +34,7 @@ std::string ChatPacket::GetTextColor(Vec3uc color) {
return ss.str();
}
ColoredText ChatPacket::ColorizeText(const std::string& text) {
ColoredText ColorizeText(const std::string& text) {
ColoredText parts;
Vec4f currentColor{1, 1, 1, 1};
@@ -135,7 +112,7 @@ ColoredText ChatPacket::ColorizeText(const std::string& text) {
return parts;
}
std::string ChatPacket::GetColoredTextString(const ColoredText& text) {
std::string GetColoredTextString(const ColoredText& text) {
std::string result;
for (auto& part : text) {
@@ -148,5 +125,15 @@ std::string ChatPacket::GetColoredTextString(const ColoredText& text) {
return result;
}
DataBuffer& operator<<(DataBuffer& out, const ColoredPart& var) {
out << var.m_Color << var.m_Text;
return out;
}
DataBuffer& operator>>(DataBuffer& in, ColoredPart& var) {
in >> var.m_Color >> var.m_Text;
return in;
}
} // namespace protocol
} // namespace blitz

View File

@@ -1,34 +0,0 @@
#include "blitz/protocol/PacketDispatcher.h"
namespace blitz {
namespace protocol {
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);
}
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) {
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());
}
}
void PacketDispatcher::Dispatch(const Packet& packet) {
PacketType type = packet.GetType();
for (PacketHandler* handler : m_Handlers[type])
packet.Dispatch(handler);
}
} // namespace protocol
} // namespace blitz

View File

@@ -1,41 +0,0 @@
#include "blitz/protocol/PacketFactory.h"
#include "blitz/protocol/Packets.h"
#include <array>
#include <functional>
#include <memory>
namespace blitz {
namespace protocol {
namespace PacketFactory {
typedef std::function<PacketPtr()> PacketCreator;
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>(); },
[]() -> PacketPtr { return std::make_unique<PlayerDeathPacket>(); },
[]() -> PacketPtr { return std::make_unique<PlayerJoinPacket>(); },
[]() -> PacketPtr { return std::make_unique<PlayerLeavePacket>(); },
[]() -> PacketPtr { return std::make_unique<PlayerListPacket>(); },
[]() -> PacketPtr { return std::make_unique<PlayerStatsPacket>(); },
[]() -> PacketPtr { return std::make_unique<ServerConfigPacket>(); },
[]() -> PacketPtr { return std::make_unique<ServerTpsPacket>(); },
[]() -> PacketPtr { return std::make_unique<UpdateGameStatePacket>(); },
[]() -> PacketPtr { return std::make_unique<KeepAlivePacket>(); },
[]() -> PacketPtr { return std::make_unique<DisconnectPacket>(); },
[]() -> PacketPtr { return std::make_unique<ChatPacket>(); },
[]() -> PacketPtr { return std::make_unique<PlayerPositionAndRotationPacket>(); },
[]() -> PacketPtr { return std::make_unique<PlayerShootPacket>(); },
};
const PacketPtr CreatePacket(PacketType type, DataBuffer& buffer) {
PacketPtr packet = Packets[static_cast<std::size_t>(type)]();
packet->Deserialize(buffer);
return packet;
}
} // namespace PacketFactory
} // namespace protocol
} // namespace blitz

View File

@@ -1,36 +0,0 @@
#include "blitz/protocol/PacketHandler.h"
#include "blitz/protocol/Packets.h"
namespace blitz {
namespace protocol {
void Packet::WritePacketID(DataBuffer& data, bool packetID) const {
if (packetID)
data << GetID();
}
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

View File

@@ -1,54 +0,0 @@
#include "blitz/protocol/VarInt.h"
#include "blitz/common/DataBuffer.h"
#include <stdexcept>
namespace blitz {
namespace protocol {
static constexpr int SEGMENT_BITS = 0x7F;
static constexpr int CONTINUE_BIT = 0x80;
std::size_t VarInt::GetSerializedLength() const {
DataBuffer buffer;
buffer << *this;
return buffer.GetSize();
}
DataBuffer& operator<<(DataBuffer& out, const VarInt& var) {
std::uint64_t value = var.m_Value;
while (true) {
if ((value & ~static_cast<std::uint64_t>(SEGMENT_BITS)) == 0) {
out << static_cast<std::uint8_t>(value);
return out;
}
out << static_cast<std::uint8_t>((value & SEGMENT_BITS) | CONTINUE_BIT);
value >>= 7;
}
}
DataBuffer& operator>>(DataBuffer& in, VarInt& var) {
var.m_Value = 0;
unsigned int position = 0;
std::uint8_t currentByte;
while (true) {
in.ReadSome(&currentByte, 1);
var.m_Value |= static_cast<std::uint64_t>(currentByte & SEGMENT_BITS) << position;
if ((currentByte & CONTINUE_BIT) == 0)
break;
position += 7;
if (position >= 8 * sizeof(var.m_Value))
throw std::runtime_error("VarInt is too big");
}
return in;
}
} // namespace protocol
} // namespace blitz

View File

@@ -1,19 +0,0 @@
#include "blitz/protocol/packets/ConnexionInfoPacket.h"
namespace blitz {
namespace protocol {
DataBuffer ConnexionInfoPacket::Serialize(bool packetID) const {
DataBuffer data;
WritePacketID(data, packetID);
data << m_ConnectionID;
return data;
}
void ConnexionInfoPacket::Deserialize(DataBuffer& data) {
data >> m_ConnectionID;
}
} // namespace protocol
} // namespace blitz

View File

@@ -1,19 +0,0 @@
#include "blitz/protocol/packets/DisconnectPacket.h"
namespace blitz {
namespace protocol {
DataBuffer DisconnectPacket::Serialize(bool packetID) const {
DataBuffer data;
WritePacketID(data, packetID);
data << m_Reason;
return data;
}
void DisconnectPacket::Deserialize(DataBuffer& data) {
data >> m_Reason;
}
} // namespace protocol
} // namespace blitz

View File

@@ -1,21 +0,0 @@
#include "blitz/protocol/packets/KeepAlivePacket.h"
#include "blitz/protocol/VarInt.h"
namespace blitz {
namespace protocol {
DataBuffer KeepAlivePacket::Serialize(bool packetID) const {
DataBuffer data;
WritePacketID(data, packetID);
data << m_AliveID;
return data;
}
void KeepAlivePacket::Deserialize(DataBuffer& data) {
data >> m_AliveID;
}
} // namespace protocol
} // namespace blitz

View File

@@ -1,20 +0,0 @@
#include "blitz/protocol/packets/PlayerDeathPacket.h"
namespace blitz {
namespace protocol {
DataBuffer PlayerDeathPacket::Serialize(bool packetID) const {
DataBuffer data;
WritePacketID(data, packetID);
data << m_PlayerID;
return data;
}
void PlayerDeathPacket::Deserialize(DataBuffer& data) {
data >> m_PlayerID;
}
} // namespace protocol
} // namespace blitz

View File

@@ -1,19 +0,0 @@
#include "blitz/protocol/packets/PlayerJoinPacket.h"
namespace blitz {
namespace protocol {
DataBuffer PlayerJoinPacket::Serialize(bool packetID) const {
DataBuffer data;
WritePacketID(data, packetID);
data << m_PlayerID << m_PlayerName;
return data;
}
void PlayerJoinPacket::Deserialize(DataBuffer& data) {
data >> m_PlayerID >> m_PlayerName;
}
} // namespace protocol
} // namespace blitz

View File

@@ -1,20 +0,0 @@
#include "blitz/protocol/packets/PlayerLeavePacket.h"
namespace blitz {
namespace protocol {
DataBuffer PlayerLeavePacket::Serialize(bool packetID) const {
DataBuffer data;
WritePacketID(data, packetID);
data << m_PlayerID;
return data;
}
void PlayerLeavePacket::Deserialize(DataBuffer& data) {
data >> m_PlayerID;
}
} // namespace protocol
} // namespace blitz

View File

@@ -1,32 +0,0 @@
#include "blitz/protocol/packets/PlayerListPacket.h"
#include "blitz/protocol/VarInt.h"
namespace blitz {
namespace protocol {
DataBuffer PlayerListPacket::Serialize(bool packetID) const {
DataBuffer data;
WritePacketID(data, packetID);
data << VarInt(m_Players.size());
for (auto [playerID, playerInfo] : m_Players) {
data << playerID << playerInfo.m_Name;
}
return data;
}
void PlayerListPacket::Deserialize(DataBuffer& data) {
VarInt playerCount;
data >> playerCount;
for (std::size_t i = 0; i < playerCount.GetValue(); i++) {
std::uint8_t playerID;
PlayerInfo playerInfo;
data >> playerID >> playerInfo.m_Name;
m_Players.insert({playerID, playerInfo});
}
}
} // namespace protocol
} // namespace blitz

View File

@@ -1,19 +0,0 @@
#include "blitz/protocol/packets/PlayerLoginPacket.h"
namespace blitz {
namespace protocol {
DataBuffer PlayerLoginPacket::Serialize(bool packetID) const {
DataBuffer data;
WritePacketID(data, packetID);
data << m_PlayerName;
return data;
}
void PlayerLoginPacket::Deserialize(DataBuffer& data) {
data >> m_PlayerName;
}
} // namespace protocol
} // namespace blitz

View File

@@ -1,21 +0,0 @@
#include "blitz/protocol/packets/PlayerPositionAndRotationPacket.h"
namespace blitz {
namespace protocol {
DataBuffer PlayerPositionAndRotationPacket::Serialize(bool packetID) const {
DataBuffer data;
WritePacketID(data, packetID);
data << m_Player << m_Position << m_Yaw << m_Pitch;
return data;
}
void PlayerPositionAndRotationPacket::Deserialize(DataBuffer& data) {
data >> m_Player >> m_Position >> m_Yaw >> m_Pitch;
}
} // namespace protocol
} // namespace blitz

View File

@@ -1,19 +0,0 @@
#include "blitz/protocol/packets/PlayerShootPacket.h"
namespace blitz {
namespace protocol {
DataBuffer PlayerShootPacket::Serialize(bool packetID) const {
DataBuffer data;
WritePacketID(data, packetID);
data << m_Player << m_Position << m_Yaw << m_Pitch;
return data;
}
void PlayerShootPacket::Deserialize(DataBuffer& data) {
data >> m_Player >> m_Position >> m_Yaw >> m_Pitch;
}
} // namespace protocol
} // namespace blitz

View File

@@ -1,19 +0,0 @@
#include "blitz/protocol/packets/PlayerStatsPacket.h"
namespace blitz {
namespace protocol {
DataBuffer PlayerStatsPacket::Serialize(bool packetID) const {
DataBuffer data;
WritePacketID(data, packetID);
data << m_PlayerID << m_PlayerStats;
return data;
}
void PlayerStatsPacket::Deserialize(DataBuffer& data) {
data >> m_PlayerID >> m_PlayerStats;
}
} // namespace protocol
} // namespace blitz

View File

@@ -1,21 +0,0 @@
#include "blitz/protocol/packets/ServerConfigPacket.h"
namespace blitz {
namespace protocol {
DataBuffer ServerConfigPacket::Serialize(bool packetID) const {
DataBuffer data;
WritePacketID(data, packetID);
data << static_cast<std::uint16_t>(m_GameConfig.FiringRate) << m_GameConfig.Gravity;
return data;
}
void ServerConfigPacket::Deserialize(DataBuffer& data) {
std::uint16_t firingRate;
data >> firingRate >> m_GameConfig.Gravity;
m_GameConfig.FiringRate = firingRate;
}
} // namespace protocol
} // namespace blitz

View File

@@ -1,19 +0,0 @@
#include "blitz/protocol/packets/ServerTpsPacket.h"
namespace blitz {
namespace protocol {
DataBuffer ServerTpsPacket::Serialize(bool packetID) const {
DataBuffer data;
WritePacketID(data, packetID);
data << m_TPS << m_MSPT << m_PacketSendTime;
return data;
}
void ServerTpsPacket::Deserialize(DataBuffer& data) {
data >> m_TPS >> m_MSPT >> m_PacketSendTime;
}
} // namespace protocol
} // namespace blitz

View File

@@ -1,19 +0,0 @@
#include "blitz/protocol/packets/UpdateGameStatePacket.h"
namespace blitz {
namespace protocol {
DataBuffer UpdateGameStatePacket::Serialize(bool packetID) const {
DataBuffer data;
WritePacketID(data, packetID);
data << m_GameState << m_TimeRemaining;
return data;
}
void UpdateGameStatePacket::Deserialize(DataBuffer& data) {
data >> m_GameState >> m_TimeRemaining;
}
} // namespace protocol
} // namespace blitz

View File

@@ -1,19 +0,0 @@
#include "blitz/protocol/packets/UpdateHealthPacket.h"
namespace blitz {
namespace protocol {
DataBuffer UpdateHealthPacket::Serialize(bool packetID) const {
DataBuffer data;
WritePacketID(data, packetID);
data << m_NewHealth;
return data;
}
void UpdateHealthPacket::Deserialize(DataBuffer& data) {
data >> m_NewHealth;
}
} // namespace protocol
} // namespace blitz

View File

@@ -1,91 +0,0 @@
#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

@@ -1,10 +1,7 @@
#include "client/Client.h"
#include "blitz/misc/Log.h"
#include "blitz/protocol/packets/ChatPacket.h"
#include "blitz/protocol/packets/DisconnectPacket.h"
#include "blitz/protocol/packets/PlayerPositionAndRotationPacket.h"
#include "blitz/protocol/packets/PlayerShootPacket.h"
#include "blitz/protocol/Packets.h"
#include "client/ClientConnexion.h"
#include "client/game/ClientGame.h"
#include "server/Server.h"
@@ -13,16 +10,33 @@
namespace blitz {
namespace client {
Client::Client() : BaseClient(), m_Server(std::make_unique<server::Server>()) {
BindListener(this);
}
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() {
Disconnect();
}
void Client::Update() {
BaseClient::Update();
if (m_Connexion->GetSocketStatus() != network::TCPSocket::Status::Connected)
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);
}
void Client::UpdateServerConfig() {
@@ -45,20 +59,78 @@ bool Client::CreateGame(std::uint16_t port, const std::string& pseudo) {
return true;
}
void Client::OnGameLeave() {
// Clear previous server
m_Server.reset(nullptr);
m_Server = std::make_unique<server::Server>();
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
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(0, position, yaw, pitch);
m_Connexion->SendPacket(packet);
}
void Client::OnLocalPlayerShoot(const Vec3f& position, float yaw, float pitch) {
protocol::PlayerShootPacket packet(position, yaw, pitch);
SendPacket(&packet);
protocol::PlayerShootPacket packet(0, 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;
}
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

@@ -3,12 +3,8 @@
#include "blitz/misc/Format.h"
#include "blitz/misc/Log.h"
#include "blitz/misc/PrettyLog.h"
#include "blitz/protocol/packets/ChatPacket.h"
#include "blitz/protocol/packets/ConnexionInfoPacket.h"
#include "blitz/protocol/packets/DisconnectPacket.h"
#include "blitz/protocol/packets/KeepAlivePacket.h"
#include "blitz/protocol/packets/PlayerLoginPacket.h"
#include "client/BaseClient.h"
#include "blitz/protocol/Packets.h"
#include "client/Client.h"
namespace blitz {
namespace client {
@@ -24,19 +20,19 @@ static std::string PrintColoredText(const protocol::ColoredText& coloredText) {
return text;
}
ClientConnexion::ClientConnexion(BaseClient& client) : network::Connexion(m_Dispatcher), m_Client(client) {
ClientConnexion::ClientConnexion(Client* client) : 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,23 +43,23 @@ bool ClientConnexion::Connect(const std::string& pseudo, const std::string& addr
return true;
}
void ClientConnexion::HandlePacket(const protocol::ChatPacket& packet) {
void ClientConnexion::Handle(const protocol::ChatPacket& packet) {
utils::LOG("[Chat] " + PrintColoredText(packet.GetMessage()));
m_Client.NotifyListeners(&ClientListener::OnTextChatReceived, packet.GetMessage());
m_Client->ChatTextReceived(packet.GetMessage());
}
void ClientConnexion::HandlePacket(const protocol::DisconnectPacket& packet) {
void ClientConnexion::Handle(const protocol::DisconnectPacket& packet) {
utils::LOG("[ClientConnexion] Disconnected ! Reason : " + packet.GetReason());
m_Client.NotifyListeners(&ClientListener::OnGameLeave);
m_Client.Disconnect();
m_Client->NotifyListeners(&client::ClientListener::OnGameLeave);
m_Client->Disconnect();
}
void ClientConnexion::HandlePacket(const protocol::KeepAlivePacket& packet) {
protocol::KeepAlivePacket response(packet.GetAliveID());
SendPacket(&response);
void ClientConnexion::Handle(const protocol::KeepAlivePacket& packet) {
protocol::KeepAlivePacket response(packet.GetAliveId());
SendPacket(response);
}
void ClientConnexion::HandlePacket(const protocol::ConnexionInfoPacket& packet) {
void ClientConnexion::Handle(const protocol::ConnexionInfoPacket& packet) {
m_PlayerID = packet.GetConnectionID();
utils::LOGD("[ClientConnexion] Logging in with pseudo " + m_PlayerName + " ...");
Login(m_PlayerName);
@@ -71,7 +67,7 @@ void ClientConnexion::HandlePacket(const protocol::ConnexionInfoPacket& packet)
void ClientConnexion::Login(const std::string& pseudo) {
protocol::PlayerLoginPacket packet(pseudo);
SendPacket(&packet);
SendPacket(packet);
}
} // namespace client

View File

@@ -3,28 +3,17 @@
#include "blitz/misc/Log.h"
#include "blitz/misc/Random.h"
#include "blitz/protocol/PacketDispatcher.h"
#include "blitz/protocol/packets/PlayerDeathPacket.h"
#include "blitz/protocol/packets/PlayerJoinPacket.h"
#include "blitz/protocol/packets/PlayerLeavePacket.h"
#include "blitz/protocol/packets/PlayerListPacket.h"
#include "blitz/protocol/packets/PlayerPositionAndRotationPacket.h"
#include "blitz/protocol/packets/PlayerShootPacket.h"
#include "blitz/protocol/packets/PlayerStatsPacket.h"
#include "blitz/protocol/packets/ServerConfigPacket.h"
#include "blitz/protocol/packets/UpdateGameStatePacket.h"
#include "blitz/protocol/packets/UpdateHealthPacket.h"
#include "client/BaseClient.h"
#include "client/Client.h"
namespace blitz {
namespace client {
ClientGame::ClientGame(BaseClient& client, protocol::PacketDispatcher& dispatcher) :
protocol::PacketHandler(dispatcher), m_Client(client) {
ClientGame::ClientGame(Client* client, protocol::PacketDispatcher& dispatcher) : m_Client(client), m_Dispatcher(dispatcher) {
RegisterHandlers();
}
ClientGame::~ClientGame() {
GetDispatcher().UnregisterHandler(*this);
GetDispatcher().UnregisterHandler(this);
}
void ClientGame::AddPlayer(game::PlayerID player, const std::string& name) {
@@ -37,49 +26,49 @@ 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) {
void ClientGame::Handle(const protocol::PlayerDeathPacket& packet) {
NotifyListeners(&game::GameListener::OnPlayerDeath, packet.GetPlayerID());
}
void ClientGame::HandlePacket(const protocol::PlayerJoinPacket& packet) {
void ClientGame::Handle(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());
// 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) {
void ClientGame::Handle(const protocol::PlayerLeavePacket& packet) {
RemovePlayer(packet.GetPlayerID());
}
void ClientGame::HandlePacket(const protocol::PlayerListPacket& packet) {
void ClientGame::Handle(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::Handle(const protocol::PlayerStatsPacket& packet) {
game::Player* player = m_Client->GetGame()->GetPlayerById(packet.GetPlayerID());
if (!player)
return;
player->GetStats() = packet.GetPlayerStats();
@@ -87,8 +76,8 @@ void ClientGame::HandlePacket(const protocol::PlayerStatsPacket& packet) {
m_LeaderBoard.Update();
}
void ClientGame::HandlePacket(const protocol::UpdateHealthPacket& packet) {
game::Player* player = m_Client.GetGame()->GetPlayerById(m_Client.GetPlayerID());
void ClientGame::Handle(const protocol::UpdateHealthPacket& packet) {
game::Player* player = m_Client->GetGame()->GetPlayerById(m_Client->GetPlayerID());
player->SetHP(packet.GetNewHealth());
// we are dead
@@ -98,22 +87,22 @@ void ClientGame::HandlePacket(const protocol::UpdateHealthPacket& packet) {
}
}
void ClientGame::HandlePacket(const protocol::UpdateGameStatePacket& packet) {
void ClientGame::Handle(const protocol::UpdateGameStatePacket& packet) {
Game::UpdateGameState(packet.GetGameState(), packet.GetTimeRemaining());
}
void ClientGame::HandlePacket(const protocol::ServerConfigPacket& packet) {
void ClientGame::Handle(const protocol::ServerConfigPacket& packet) {
m_Config = packet.GetGameConfig();
m_Client.NotifyListeners(&client::ClientListener::OnGameConfigUpdate);
m_Client->NotifyListeners(&client::ClientListener::OnGameConfigUpdate);
}
void ClientGame::HandlePacket(const protocol::PlayerShootPacket& packet) {
m_Client.NotifyListeners(
void ClientGame::Handle(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::Handle(const protocol::PlayerPositionAndRotationPacket& packet) {
if (packet.GetPlayer() == m_Client->GetPlayerID())
return;
game::Player* player = GetPlayerById(packet.GetPlayer());
@@ -129,7 +118,7 @@ void ClientGame::HandlePacket(const protocol::PlayerPositionAndRotationPacket& p
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

@@ -1,6 +1,6 @@
#include "client/input/InputManager.h"
#include "imgui.h"
#include <imgui.h>
#include <vector>
namespace blitz {

View File

@@ -7,7 +7,7 @@
#include "client/config/BlitzConfig.h"
#include "client/game/ClientGame.h"
#include "client/input/InputManager.h"
#include "imgui.h"
#include <imgui.h>
#include <algorithm>
#include <iostream>

View File

@@ -6,15 +6,12 @@
#include "blitz/misc/Random.h"
#include "blitz/misc/Time.h"
#include "blitz/protocol/PacketFactory.h"
#include "blitz/protocol/packets/ChatPacket.h"
#include "blitz/protocol/packets/DisconnectPacket.h"
#include "blitz/protocol/packets/PlayerLeavePacket.h"
#include "blitz/protocol/packets/ServerTpsPacket.h"
#include "blitz/protocol/Packets.h"
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();
@@ -52,15 +49,18 @@ void Server::StopThread() {
}
bool Server::Start(std::uint16_t port, bool blocking) {
if (!m_Listener.Listen(port, 10)) {
try {
m_Listener = std::make_unique<network::TCPListener>(port, 10);
} catch (sp::io::SocketError& e) {
utils::LOGE(utils::Format("[Server] Failed to bind port %u !", port));
return false;
}
if (!m_Listener.SetBlocking(false)) {
if (!m_Listener->SetBlocking(false)) {
utils::LOGE("[Server] Failed to block server socket !");
return false;
}
utils::LOG(utils::Format("[Server] Server started at port %u !", m_Listener.GetListeningPort()));
utils::LOG(utils::Format("[Server] Server started at port %u !", m_Listener->GetListeningPort()));
m_TickCounter.Reset();
m_ServerRunning = true;
if (blocking) {
@@ -72,8 +72,7 @@ bool Server::Start(std::uint16_t port, bool blocking) {
}
void Server::Clean() {
m_Listener.Close();
m_Listener.Destroy();
m_Listener->Close();
m_Connections.clear();
@@ -85,7 +84,7 @@ void Server::Stop() {
return;
protocol::DisconnectPacket packet("Server closed");
BroadcastPacket(&packet);
BroadcastPacket(packet);
StopThread();
}
@@ -95,17 +94,17 @@ void Server::Tick(std::uint64_t delta) {
UpdateSockets();
if (m_TickCounter.Update()) {
protocol::ServerTpsPacket packet(m_TickCounter.GetTPS(), m_TickCounter.GetMSPT(), utils::GetTime());
BroadcastPacket(&packet);
BroadcastPacket(packet);
}
m_Game.Tick(delta);
}
void Server::Accept() {
network::TCPSocket newSocket;
if (m_Listener.Accept(newSocket)) {
if (std::unique_ptr<network::TCPSocket> newSocket = m_Listener->Accept(); newSocket != nullptr) {
newSocket->SetBlocking(false);
game::PlayerID newPlayerID = GetNewPlayerID();
auto con = std::make_unique<ServerConnexion>(*this, newSocket, newPlayerID);
m_Connections.insert(ConnexionMap::value_type{newPlayerID, std::move(con)});
auto con = std::make_unique<ServerConnexion>(this, std::move(newSocket), newPlayerID);
m_Connections.emplace(newPlayerID, std::move(con));
m_Connections[newPlayerID]->Init();
newPlayerID++;
}
@@ -134,7 +133,7 @@ void Server::UpdateSockets() {
closeConnexions.clear();
}
void Server::BroadcastPacket(const protocol::Packet* packet) {
void Server::BroadcastPacket(const protocol::Packet& packet) {
for (auto& connection : m_Connections) {
connection.second->SendPacket(packet);
}
@@ -142,7 +141,7 @@ void Server::BroadcastPacket(const protocol::Packet* packet) {
void Server::BroadcastChatMessage(const std::string& msg) {
protocol::ChatPacket packet(msg);
BroadcastPacket(&packet);
BroadcastPacket(packet);
#ifdef BLITZ_HEADLESS
utils::LOG("[CHAT]\t" + msg);
@@ -154,7 +153,7 @@ void Server::RemoveConnexion(std::uint8_t connexionID) {
}
std::uint16_t Server::GetListeningPort() {
return m_Listener.GetListeningPort();
return m_Listener->GetListeningPort();
}
void Server::AddBot() {
@@ -173,7 +172,7 @@ void Server::KickPlayer(game::PlayerID playerID) {
if (it != m_Connections.end()) {
protocol::DisconnectPacket packet("Tu dois disparaître (in game) !");
m_Connections.at(playerID)->SendPacket(&packet);
m_Connections.at(playerID)->SendPacket(packet);
}
game::Player* player = m_Game.GetPlayerById(playerID);

View File

@@ -7,17 +7,7 @@
#include "blitz/misc/Time.h"
#include "blitz/protocol/PacketDispatcher.h"
#include "blitz/protocol/PacketFactory.h"
#include "blitz/protocol/packets/ChatPacket.h"
#include "blitz/protocol/packets/ConnexionInfoPacket.h"
#include "blitz/protocol/packets/DisconnectPacket.h"
#include "blitz/protocol/packets/KeepAlivePacket.h"
#include "blitz/protocol/packets/PlayerJoinPacket.h"
#include "blitz/protocol/packets/PlayerListPacket.h"
#include "blitz/protocol/packets/PlayerLoginPacket.h"
#include "blitz/protocol/packets/PlayerPositionAndRotationPacket.h"
#include "blitz/protocol/packets/PlayerShootPacket.h"
#include "blitz/protocol/packets/ServerConfigPacket.h"
#include "blitz/protocol/packets/UpdateGameStatePacket.h"
#include "blitz/protocol/Packets.h"
#include "client/gui/ColorFulText.h"
#include "server/Server.h"
#include <unordered_map>
@@ -28,27 +18,29 @@ 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, std::unique_ptr<network::TCPSocket>&& socket, std::uint8_t id) :
network::Connexion(std::move(*socket)), m_Server(server), m_ID(id), m_Player(nullptr) {
RegisterHandlers();
}
ServerConnexion::ServerConnexion(ServerConnexion&& move) :
Connexion::Connexion(std::move(move)),
network::Connexion(std::move(move)),
m_Server(move.m_Server),
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() {
@@ -63,7 +55,7 @@ void ServerConnexion::CheckKeepAlive() {
SendKeepAlive();
} else {
protocol::DisconnectPacket packet("Time out");
SendPacket(&packet);
SendPacket(packet);
CloseConnection();
}
}
@@ -74,7 +66,7 @@ void ServerConnexion::SendKeepAlive() {
m_KeepAlive.RecievedResponse = false;
protocol::KeepAlivePacket keepAlivePacket(m_KeepAlive.KeepAliveID);
SendPacket(&keepAlivePacket);
SendPacket(keepAlivePacket);
std::uint64_t time = utils::GetTime();
m_KeepAlive.SendTime = time;
@@ -88,13 +80,13 @@ void ServerConnexion::InitPlayerChatColor() {
std::uint8_t green = hash >> 8 & 0xFF;
std::uint8_t blue = hash & 0xFF;
m_ChatColor = protocol::ChatPacket::GetTextColor({red, green, blue});
m_ChatColor = protocol::GetTextColor({red, green, blue});
}
void ServerConnexion::HandlePacket(const protocol::PlayerLoginPacket& packet) {
m_Server.GetGame().AddPlayer(m_ID, packet.GetPlayerName());
void ServerConnexion::Handle(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();
@@ -103,27 +95,26 @@ void ServerConnexion::HandlePacket(const protocol::PlayerLoginPacket& packet) {
InitPlayerChatColor();
}
void ServerConnexion::HandlePacket(const protocol::KeepAlivePacket& packet) {
if (packet.GetAliveID() != m_KeepAlive.KeepAliveID)
void ServerConnexion::Handle(const protocol::KeepAlivePacket& packet) {
if (packet.GetAliveId() != m_KeepAlive.KeepAliveID)
return;
m_KeepAlive.RecievedResponse = true;
}
void ServerConnexion::HandlePacket(const protocol::DisconnectPacket& packet) {
void ServerConnexion::Handle(const protocol::DisconnectPacket& packet) {
CloseConnection();
}
void ServerConnexion::HandlePacket(const protocol::ChatPacket& packet) {
void ServerConnexion::Handle(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(),
protocol::ChatPacket::GetTextColor(protocol::WHITE).c_str(),
protocol::ChatPacket::GetColoredTextString(packet.GetMessage()).c_str()));
m_Server->BroadcastChatMessage(utils::Format("<%s%s%s> %s", m_ChatColor.c_str(), m_Player->GetName().c_str(),
protocol::GetTextColor(protocol::WHITE).c_str(), protocol::GetColoredTextString(packet.GetMessage()).c_str()));
}
void ServerConnexion::HandlePacket(const protocol::PlayerPositionAndRotationPacket& packet) {
void ServerConnexion::Handle(const protocol::PlayerPositionAndRotationPacket& packet) {
if (!m_Player)
return;
@@ -132,11 +123,11 @@ void ServerConnexion::HandlePacket(const protocol::PlayerPositionAndRotationPack
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::Handle(const protocol::PlayerShootPacket& packet) {
protocol::PlayerShootPacket broadcastShoot(m_Player->GetID(), packet.GetPosition(), packet.GetYaw(), packet.GetPitch());
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() {
@@ -145,37 +136,37 @@ void ServerConnexion::Init() {
}
void ServerConnexion::SendGameState() {
protocol::UpdateGameStatePacket packet(m_Server.GetGame().GetGameState(), m_Server.GetGame().GetGameStateRemainingTime());
SendPacket(&packet);
protocol::UpdateGameStatePacket packet(m_Server->GetGame().GetGameState(), m_Server->GetGame().GetGameStateRemainingTime());
SendPacket(packet);
}
void ServerConnexion::SendPlayers() {
protocol::PlayerList list;
protocol::PlayerMap 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()}});
}
protocol::PlayerListPacket packet(list);
SendPacket(&packet);
SendPacket(packet);
}
void ServerConnexion::SendServerConfig() {
protocol::ServerConfigPacket packet(m_Server.GetGame().GetGameConfig());
SendPacket(&packet);
protocol::ServerConfigPacket packet(m_Server->GetGame().GetGameConfig());
SendPacket(packet);
}
void ServerConnexion::InitConnection() {
protocol::ConnexionInfoPacket conPacket(m_ID);
SendPacket(&conPacket);
SendPacket(conPacket);
}
ServerConnexion::~ServerConnexion() {
GetDispatcher().UnregisterHandler(*this);
GetDispatcher().UnregisterHandler(this);
m_Server.GetGame().RemovePlayer(m_ID);
m_Server->GetGame().RemovePlayer(m_ID);
}
} // namespace server

View File

@@ -4,22 +4,14 @@
#include "blitz/misc/Format.h"
#include "blitz/misc/Log.h"
#include "blitz/misc/Random.h"
#include "blitz/protocol/packets/ChatPacket.h"
#include "blitz/protocol/packets/PlayerDeathPacket.h"
#include "blitz/protocol/packets/PlayerJoinPacket.h"
#include "blitz/protocol/packets/PlayerLeavePacket.h"
#include "blitz/protocol/packets/PlayerPositionAndRotationPacket.h"
#include "blitz/protocol/packets/PlayerStatsPacket.h"
#include "blitz/protocol/packets/ServerConfigPacket.h"
#include "blitz/protocol/packets/UpdateGameStatePacket.h"
#include "blitz/protocol/packets/UpdateHealthPacket.h"
#include "blitz/protocol/Packets.h"
#include "server/Server.h"
#include <cmath>
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 +20,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::GetTextColor(protocol::AQUA) + "La partie commence dans 10s !");
}
void ServerGame::CancelGame() {
@@ -72,8 +64,8 @@ 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);
protocol::PlayerPositionAndRotationPacket packet(playerID, player.GetPosition(), player.GetYaw(), player.GetPitch());
m_Server->BroadcastPacket(packet);
}
}
@@ -109,12 +101,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::GetTextColor(protocol::YELLOW) + joinMessage);
if (m_GameState == game::gsWaiting && m_Players.size() > 1) {
StartGame();
@@ -123,7 +115,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 +124,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::GetTextColor(protocol::YELLOW) + leaveMessage);
Game::RemovePlayer(playerID);
@@ -164,7 +156,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 +168,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())
it->second->SendPacket(&packet);
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 +195,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);
}

View File

@@ -1,10 +1,12 @@
add_requires("zlib")
add_repositories("persson-repo https://git.ale-pri.com/Persson-dev/xmake-repo.git")
add_requires("splib 1.0.4", {debug = is_mode("debug")})
-- Game files (with server)
target("Blitz")
if is_os("windows") then
set_kind("static")
add_links("ws2_32") -- link network stuff
else
set_kind("shared")
end
@@ -12,4 +14,5 @@ target("Blitz")
add_includedirs("../include")
add_files("../src/blitz/**.cpp", "../src/server/**.cpp")
add_packages("zlib")
add_packages("zlib")
add_packages("splib", {public = true})

View File

@@ -7,7 +7,7 @@ if is_plat("linux") and is_arch("arm64-v8a") then
add_defines("BLITZ_GL_LOADER_GLEW")
end
add_requires("libsdl 2.28.5", {configs = {sdlmain = false}})
add_requires("libsdl2 2.28.5", {configs = {sdlmain = false}})
add_requires("imgui 1.90", {configs = {sdl2 = true, opengl3 = true}})
add_requires(opengl, "assimp 5.3.1", "nlohmann_json", "openal-soft", "stb")