begin packet serialization
This commit is contained in:
36
include/blitz/common/Format.h
Normal file
36
include/blitz/common/Format.h
Normal file
@@ -0,0 +1,36 @@
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* \file Format.h
|
||||
* \brief This file contains the definition of the `Format` function.
|
||||
*/
|
||||
|
||||
#include <memory>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
|
||||
namespace blitz {
|
||||
|
||||
/**
|
||||
* \brief Formats a string using a format string and variadic arguments.
|
||||
*
|
||||
* This function takes a format string and a variable number of arguments and returns a formatted string.
|
||||
* The format string can contain placeholders that will be replaced by the corresponding arguments.
|
||||
*
|
||||
* \param format The format string.
|
||||
* \param args The variadic arguments to be formatted.
|
||||
* \return The formatted string.
|
||||
* \throws std::runtime_error if an error occurs during formatting.
|
||||
*/
|
||||
template <typename... Args>
|
||||
std::string Format(const std::string& format, Args... args) {
|
||||
int size = snprintf(nullptr, 0, format.c_str(), args...) + 1; // Extra space for '\0'
|
||||
if (size <= 0) {
|
||||
throw std::runtime_error("Error during formatting.");
|
||||
}
|
||||
std::unique_ptr<char[]> buf(new char[size]);
|
||||
snprintf(buf.get(), static_cast<std::size_t>(size), format.c_str(), args...);
|
||||
return std::string(buf.get(), buf.get() + size - 1); // We don't want the '\0' inside
|
||||
}
|
||||
|
||||
} // namespace blitz
|
||||
30
include/blitz/common/Log.h
Normal file
30
include/blitz/common/Log.h
Normal file
@@ -0,0 +1,30 @@
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* \file Log.h
|
||||
* \brief File defining log functions
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace blitz {
|
||||
|
||||
/**
|
||||
* \brief Logs a normal message.
|
||||
* \param msg The message to be logged.
|
||||
*/
|
||||
void Log(const std::string& msg);
|
||||
|
||||
/**
|
||||
* \brief Logs a normal message in debug mode.
|
||||
* \param msg The message to be logged.
|
||||
*/
|
||||
void LogD(const std::string& msg);
|
||||
|
||||
/**
|
||||
* \brief Logs an error message.
|
||||
* \param err The error message to be logged.
|
||||
*/
|
||||
void LogE(const std::string& err);
|
||||
|
||||
} // namespace blitz
|
||||
49
include/blitz/protocol/PacketData.h
Normal file
49
include/blitz/protocol/PacketData.h
Normal file
@@ -0,0 +1,49 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace blitz {
|
||||
namespace protocol {
|
||||
namespace data {
|
||||
|
||||
struct PlayerLogin {
|
||||
std::string m_PlayerName;
|
||||
};
|
||||
|
||||
struct UpdateHealth {
|
||||
float m_NewHealth;
|
||||
};
|
||||
|
||||
struct LoggingSuccess {};
|
||||
|
||||
struct PlayerDeath {};
|
||||
|
||||
struct PlayerJoin {};
|
||||
|
||||
struct PlayerLeave {};
|
||||
|
||||
struct PlayerStats {};
|
||||
|
||||
struct PlayerList {};
|
||||
|
||||
struct ServerConfig {};
|
||||
|
||||
struct ServerTps {};
|
||||
|
||||
struct UpdateGameState {};
|
||||
|
||||
struct KeepAlive {};
|
||||
|
||||
struct Disconnect {};
|
||||
|
||||
struct ChatMessage {
|
||||
std::string m_Text;
|
||||
};
|
||||
|
||||
struct PlayerPositionAndRotation {};
|
||||
|
||||
struct PlayerShoot {};
|
||||
|
||||
} // namespace data
|
||||
} // namespace protocol
|
||||
} // namespace blitz
|
||||
19
include/blitz/protocol/PacketFactory.h
Normal file
19
include/blitz/protocol/PacketFactory.h
Normal file
@@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#include <blitz/protocol/Packets.h>
|
||||
#include <memory>
|
||||
|
||||
namespace blitz {
|
||||
namespace protocol {
|
||||
namespace PacketFactory {
|
||||
|
||||
template<typename PacketDerived, typename = typename std::enable_if<std::is_base_of<Packet, PacketDerived>::value>::type>
|
||||
std::unique_ptr<PacketDerived> CreatePacket() {
|
||||
return std::make_unique<PacketDerived>();
|
||||
}
|
||||
|
||||
const std::unique_ptr<Packet>& CreateReadOnlyPacket(PacketType a_Type);
|
||||
|
||||
} // namespace PacketFactory
|
||||
} // namespace protocol
|
||||
} // namespace blitz
|
||||
19
include/blitz/protocol/PacketSerializer.h
Normal file
19
include/blitz/protocol/PacketSerializer.h
Normal file
@@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#include <blitz/protocol/Packets.h>
|
||||
#include <Nazara/Core/ByteArray.hpp>
|
||||
|
||||
namespace blitz {
|
||||
namespace protocol {
|
||||
|
||||
using PacketPtr = std::unique_ptr<Packet>;
|
||||
|
||||
namespace PacketSerializer {
|
||||
|
||||
Nz::ByteArray Serialize(const Packet& a_Packet);
|
||||
|
||||
std::unique_ptr<Packet> Deserialize(Nz::ByteArray& a_Data);
|
||||
|
||||
}
|
||||
} // namespace protocol
|
||||
} // namespace blitz
|
||||
35
include/blitz/protocol/PacketVisitor.h
Normal file
35
include/blitz/protocol/PacketVisitor.h
Normal file
@@ -0,0 +1,35 @@
|
||||
#pragma once
|
||||
|
||||
#include <blitz/protocol/Packets.h>
|
||||
|
||||
namespace blitz {
|
||||
namespace protocol {
|
||||
|
||||
class PacketVisitor {
|
||||
protected:
|
||||
PacketVisitor() {}
|
||||
virtual ~PacketVisitor() {}
|
||||
|
||||
public:
|
||||
void Check(const Packet& packet);
|
||||
|
||||
virtual void Visit(const packets::PlayerLogin&) {}
|
||||
virtual void Visit(const packets::UpdateHealth&) {}
|
||||
virtual void Visit(const packets::LoggingSuccess&) {}
|
||||
virtual void Visit(const packets::PlayerDeath&) {}
|
||||
virtual void Visit(const packets::PlayerJoin&) {}
|
||||
virtual void Visit(const packets::PlayerLeave&) {}
|
||||
virtual void Visit(const packets::PlayerList&) {}
|
||||
virtual void Visit(const packets::PlayerStats&) {}
|
||||
virtual void Visit(const packets::ServerConfig&) {}
|
||||
virtual void Visit(const packets::ServerTps&) {}
|
||||
virtual void Visit(const packets::UpdateGameState&) {}
|
||||
virtual void Visit(const packets::KeepAlive&) {}
|
||||
virtual void Visit(const packets::Disconnect&) {}
|
||||
virtual void Visit(const packets::ChatMessage&) {}
|
||||
virtual void Visit(const packets::PlayerPositionAndRotation&) {}
|
||||
virtual void Visit(const packets::PlayerShoot&) {}
|
||||
};
|
||||
|
||||
} // namespace protocol
|
||||
} // namespace blitz
|
||||
121
include/blitz/protocol/Packets.h
Normal file
121
include/blitz/protocol/Packets.h
Normal file
@@ -0,0 +1,121 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <blitz/protocol/PacketData.h>
|
||||
|
||||
namespace blitz {
|
||||
namespace protocol {
|
||||
|
||||
class PacketVisitor;
|
||||
|
||||
using PacketID = std::uint8_t;
|
||||
|
||||
enum class PacketType : PacketID {
|
||||
// client --> server
|
||||
|
||||
PlayerLogin = 0,
|
||||
UpdateHealth,
|
||||
|
||||
// client <-- server
|
||||
|
||||
LoggingSuccess,
|
||||
PlayerDeath,
|
||||
PlayerJoin,
|
||||
PlayerLeave,
|
||||
PlayerList,
|
||||
PlayerStats,
|
||||
ServerConfig,
|
||||
ServerTps,
|
||||
UpdateGameState,
|
||||
|
||||
// client <--> server
|
||||
|
||||
KeepAlive,
|
||||
Disconnect,
|
||||
ChatMessage,
|
||||
PlayerPositionAndRotation,
|
||||
PlayerShoot,
|
||||
|
||||
PACKET_COUNT
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class Packet {
|
||||
public:
|
||||
virtual PacketType GetType() const = 0;
|
||||
|
||||
virtual void Accept(PacketVisitor& a_Visitor) const = 0;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
namespace packets {
|
||||
|
||||
/**
|
||||
* \tparam PT The packet type
|
||||
* \tparam Data The structure holding the data of the packet
|
||||
*/
|
||||
template <PacketType PT, typename Data>
|
||||
class ConcretePacket : public Packet {
|
||||
public:
|
||||
using PacketDataType = Data;
|
||||
|
||||
PacketDataType m_Data;
|
||||
|
||||
ConcretePacket(const PacketDataType& a_Data = {});
|
||||
|
||||
constexpr PacketType GetType() const override {
|
||||
return PT;
|
||||
};
|
||||
|
||||
private:
|
||||
void Accept(PacketVisitor& a_Visitor) const override;
|
||||
|
||||
friend class PacketVisitor;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// define BLITZ_INSTANCIATE_PACKETS
|
||||
// before including this file
|
||||
// if you want to instantiate templates
|
||||
#ifdef BLITZ_INSTANCIATE_PACKETS
|
||||
#define DeclarePacket(Type) \
|
||||
using Type = ConcretePacket<PacketType::Type, data::Type>; \
|
||||
template class ConcretePacket<PacketType::Type, data::Type>
|
||||
#else
|
||||
#define DeclarePacket(Type) using Type = ConcretePacket<PacketType::Type, data::Type>
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
DeclarePacket(PlayerLogin);
|
||||
DeclarePacket(UpdateHealth);
|
||||
DeclarePacket(LoggingSuccess);
|
||||
DeclarePacket(PlayerDeath);
|
||||
DeclarePacket(PlayerJoin);
|
||||
DeclarePacket(PlayerLeave);
|
||||
DeclarePacket(PlayerStats);
|
||||
DeclarePacket(PlayerList);
|
||||
DeclarePacket(ServerConfig);
|
||||
DeclarePacket(ServerTps);
|
||||
DeclarePacket(UpdateGameState);
|
||||
DeclarePacket(KeepAlive);
|
||||
DeclarePacket(Disconnect);
|
||||
DeclarePacket(ChatMessage);
|
||||
DeclarePacket(PlayerPositionAndRotation);
|
||||
DeclarePacket(PlayerShoot);
|
||||
|
||||
} // namespace packets
|
||||
|
||||
} // namespace protocol
|
||||
} // namespace blitz
|
||||
70
include/blitz/utils/Test.h
Normal file
70
include/blitz/utils/Test.h
Normal file
@@ -0,0 +1,70 @@
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* \file Test.h
|
||||
* \brief File containing unit testing utilities
|
||||
*/
|
||||
|
||||
#include <cstdlib>
|
||||
#include <blitz/common/Log.h>
|
||||
|
||||
namespace blitz {
|
||||
namespace test {
|
||||
|
||||
/**
|
||||
* \def BLITZ_TEST_SUCCESSFUL
|
||||
* \brief Used in tests to indicate that a test was successful
|
||||
*/
|
||||
#define BLITZ_TEST_SUCCESSFUL 0
|
||||
|
||||
/**
|
||||
* \def BLITZ_TEST_FAILED
|
||||
* \brief Used in tests to indicate that a test failed
|
||||
*/
|
||||
#define BLITZ_TEST_FAILED 1
|
||||
|
||||
#ifndef __FUNCTION_NAME__
|
||||
#ifdef _WIN32
|
||||
#define __FUNCTION_NAME__ __FUNCTION__
|
||||
#else
|
||||
#define __FUNCTION_NAME__ __PRETTY_FUNCTION__
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \def blitz_test_assert
|
||||
* \param ... The expression to evaluate
|
||||
* \brief Evaluates the expression and exits the program if not valid.
|
||||
* \note It works like a basic assert() but also in release mode
|
||||
*/
|
||||
#define blitz_test_assert(...) \
|
||||
if (!static_cast<bool>(__VA_ARGS__)) { \
|
||||
blitz::test::LogAssert(#__VA_ARGS__, __FILE__, __LINE__, __FUNCTION_NAME__); \
|
||||
std::exit(BLITZ_TEST_FAILED); \
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \def blitz_debug_assert
|
||||
* \param ... The expression to execute
|
||||
* \brief Assertion without checks in release mode
|
||||
* \note The expression is always executed. However, in release, no checks are made !
|
||||
*/
|
||||
#ifdef NDEBUG
|
||||
#define blitz_debug_assert(...) __VA_ARGS__
|
||||
#else
|
||||
#define blitz_debug_assert blitz_test_assert
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* \brief Prints an error message associated with a failed assertion
|
||||
* \param expression The expression that was tested
|
||||
* \param file The file in which the assertion failed
|
||||
* \param line The line in the file in which the assertion failed
|
||||
* \param function The function in which the assertion failed
|
||||
*/
|
||||
void LogAssert(const char* expression, const char* file, int line, const char* function);
|
||||
|
||||
} // namespace test
|
||||
} // namespace blitz
|
||||
Reference in New Issue
Block a user