big push
This commit is contained in:
37
.clang-format
Normal file
37
.clang-format
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
Language: Cpp
|
||||||
|
BasedOnStyle: LLVM
|
||||||
|
|
||||||
|
AlignAfterOpenBracket: DontAlign
|
||||||
|
BreakConstructorInitializers: AfterColon
|
||||||
|
ConstructorInitializerAllOnOneLineOrOnePerLine: true
|
||||||
|
PointerAlignment: Left
|
||||||
|
SortIncludes: true
|
||||||
|
SpacesBeforeTrailingComments: 2
|
||||||
|
UseTab: Always
|
||||||
|
MaxEmptyLinesToKeep: 5
|
||||||
|
|
||||||
|
TabWidth: 4
|
||||||
|
ConstructorInitializerIndentWidth: 4
|
||||||
|
ContinuationIndentWidth: 4
|
||||||
|
IndentWidth: 4
|
||||||
|
IndentCaseLabels: true
|
||||||
|
|
||||||
|
ColumnLimit: 135
|
||||||
|
AlwaysBreakTemplateDeclarations: Yes
|
||||||
|
|
||||||
|
AllowShortFunctionsOnASingleLine: Empty
|
||||||
|
BreakBeforeBraces: Custom
|
||||||
|
BraceWrapping:
|
||||||
|
AfterClass: false
|
||||||
|
AfterControlStatement: false
|
||||||
|
AfterEnum: false
|
||||||
|
AfterExternBlock: false
|
||||||
|
AfterFunction: false
|
||||||
|
AfterNamespace: false
|
||||||
|
AfterStruct: false
|
||||||
|
AfterUnion: false
|
||||||
|
BeforeCatch: false
|
||||||
|
BeforeElse: false
|
||||||
|
IndentBraces: false
|
||||||
|
SplitEmptyFunction: true
|
||||||
|
SplitEmptyRecord: true
|
||||||
66
include/td/Types.h
Normal file
66
include/td/Types.h
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include <fpm/fpm.hpp>
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
|
||||||
|
enum class Team : std::uint8_t {
|
||||||
|
Blue = 0,
|
||||||
|
Red,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class CastleType : std::uint8_t {
|
||||||
|
Archer = 0,
|
||||||
|
Leach,
|
||||||
|
Artillery,
|
||||||
|
Mage,
|
||||||
|
Ice,
|
||||||
|
Poison,
|
||||||
|
Quake,
|
||||||
|
Sorcerer,
|
||||||
|
Zeus,
|
||||||
|
Necromancer,
|
||||||
|
Turret,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class EntityType : std::uint8_t {
|
||||||
|
Zombie = 0,
|
||||||
|
Spider,
|
||||||
|
Pigman,
|
||||||
|
Skeleton,
|
||||||
|
Creeper,
|
||||||
|
Silverfish,
|
||||||
|
Blaze,
|
||||||
|
Witch,
|
||||||
|
Slime,
|
||||||
|
Giant,
|
||||||
|
Wither,
|
||||||
|
// And passive animals
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class ShopItem : std::uint8_t {
|
||||||
|
Goldmine = 0,
|
||||||
|
Inferno,
|
||||||
|
Meteor,
|
||||||
|
Zeus,
|
||||||
|
Freeze,
|
||||||
|
Speed,
|
||||||
|
Heal,
|
||||||
|
};
|
||||||
|
|
||||||
|
using CastleID = std::uint16_t;
|
||||||
|
using PlayerID = std::uint8_t;
|
||||||
|
using EntityID = std::uint16_t;
|
||||||
|
|
||||||
|
struct CastleCoords {
|
||||||
|
std::int16_t x;
|
||||||
|
std::int16_t y;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct EntityCoords {
|
||||||
|
fpm::fixed_16_16 x;
|
||||||
|
fpm::fixed_16_16 y;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace td
|
||||||
94
include/td/protocol/ByteBuffer.h
Normal file
94
include/td/protocol/ByteBuffer.h
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <godot_cpp/variant/packed_byte_array.hpp>
|
||||||
|
#include <godot_cpp/variant/string.hpp>
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
namespace protocol {
|
||||||
|
|
||||||
|
class PlayerInfo;
|
||||||
|
|
||||||
|
class ByteBuffer {
|
||||||
|
private:
|
||||||
|
godot::PackedByteArray m_Buffer;
|
||||||
|
std::size_t m_ReadOffset;
|
||||||
|
|
||||||
|
public:
|
||||||
|
class ReadError : public std::runtime_error {
|
||||||
|
public:
|
||||||
|
ReadError(const std::string& msg) : std::runtime_error(msg) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
ByteBuffer(godot::PackedByteArray&& a_Buffer) : m_Buffer(std::move(a_Buffer)), m_ReadOffset(0) {}
|
||||||
|
ByteBuffer() : m_ReadOffset(0) {
|
||||||
|
m_Buffer.resize(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
const godot::PackedByteArray& GetByteArray() const {
|
||||||
|
return m_Buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
godot::PackedByteArray& GetByteArray() {
|
||||||
|
return m_Buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Integers
|
||||||
|
ByteBuffer& operator<<(int8_t a_Data);
|
||||||
|
ByteBuffer& operator>>(int8_t& a_Data);
|
||||||
|
ByteBuffer& operator<<(uint8_t a_Data);
|
||||||
|
ByteBuffer& operator>>(uint8_t& a_Data);
|
||||||
|
|
||||||
|
ByteBuffer& operator<<(int16_t a_Data);
|
||||||
|
ByteBuffer& operator>>(int16_t& a_Data);
|
||||||
|
ByteBuffer& operator<<(uint16_t a_Data);
|
||||||
|
ByteBuffer& operator>>(uint16_t& a_Data);
|
||||||
|
|
||||||
|
ByteBuffer& operator<<(int32_t a_Data);
|
||||||
|
ByteBuffer& operator>>(int32_t& a_Data);
|
||||||
|
ByteBuffer& operator<<(uint32_t a_Data);
|
||||||
|
ByteBuffer& operator>>(uint32_t& a_Data);
|
||||||
|
|
||||||
|
ByteBuffer& operator<<(int64_t a_Data);
|
||||||
|
ByteBuffer& operator>>(int64_t& a_Data);
|
||||||
|
ByteBuffer& operator<<(uint64_t a_Data);
|
||||||
|
ByteBuffer& operator>>(uint64_t& a_Data);
|
||||||
|
|
||||||
|
ByteBuffer& operator<<(float a_Data);
|
||||||
|
ByteBuffer& operator>>(float& a_Data);
|
||||||
|
ByteBuffer& operator<<(double a_Data);
|
||||||
|
ByteBuffer& operator>>(double& a_Data);
|
||||||
|
|
||||||
|
ByteBuffer& operator<<(const godot::String& a_Data);
|
||||||
|
ByteBuffer& operator>>(godot::String& a_Data);
|
||||||
|
|
||||||
|
ByteBuffer& operator<<(const godot::Vector3& a_Data);
|
||||||
|
ByteBuffer& operator>>(godot::Vector3& a_Data);
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
ByteBuffer& operator<<(const std::vector<T>& a_Data) {
|
||||||
|
*this << static_cast<std::uint32_t>(a_Data.size());
|
||||||
|
for (const T& data : a_Data) {
|
||||||
|
*this << data;
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
ByteBuffer& operator>>(std::vector<T>& a_Data) {
|
||||||
|
std::uint32_t arraySize;
|
||||||
|
*this >> arraySize;
|
||||||
|
a_Data.resize(arraySize);
|
||||||
|
for (std::uint32_t i = 0; i < arraySize; i++) {
|
||||||
|
*this >> a_Data[i];
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
ByteBuffer& operator<<(const PlayerInfo& a_Data);
|
||||||
|
ByteBuffer& operator>>(PlayerInfo& a_Data);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace protocol
|
||||||
|
} // namespace td
|
||||||
78
include/td/protocol/PacketData.h
Normal file
78
include/td/protocol/PacketData.h
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <td/common/Types.h>
|
||||||
|
#include <godot_cpp/variant/string.hpp>
|
||||||
|
#include <godot_cpp/variant/vector3.hpp>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
namespace protocol {
|
||||||
|
|
||||||
|
struct PlayerInfo {
|
||||||
|
PlayerID m_PlayerId;
|
||||||
|
godot::String m_PlayerName;
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace data {
|
||||||
|
|
||||||
|
struct PlayerLogin {
|
||||||
|
godot::String m_PlayerName;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct UpdateHealth {
|
||||||
|
float m_NewHealth;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct LoggingSuccess {
|
||||||
|
PlayerID m_PlayerId;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PlayerDeath {};
|
||||||
|
|
||||||
|
struct PlayerJoin {
|
||||||
|
PlayerInfo m_Player;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PlayerLeave {
|
||||||
|
PlayerID m_PlayerId;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PlayerStats {};
|
||||||
|
|
||||||
|
struct PlayerList {
|
||||||
|
std::vector<PlayerInfo> m_Players;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ServerConfig {};
|
||||||
|
|
||||||
|
struct ServerTps {};
|
||||||
|
|
||||||
|
struct UpdateGameState {};
|
||||||
|
|
||||||
|
struct KeepAlive {
|
||||||
|
std::uint64_t m_KeepAliveId;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Disconnect {};
|
||||||
|
|
||||||
|
struct ChatMessage {
|
||||||
|
godot::String m_Text;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PlayerPositionAndRotation {
|
||||||
|
PlayerID m_Player;
|
||||||
|
godot::Vector3 m_Position;
|
||||||
|
godot::Vector3 m_Rotation;
|
||||||
|
godot::Vector3 m_Velocity;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PlayerShoot {
|
||||||
|
PlayerID m_Sender;
|
||||||
|
godot::Vector3 m_Position;
|
||||||
|
godot::Vector3 m_Rotation;
|
||||||
|
godot::Vector3 m_Velocity;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace data
|
||||||
|
} // namespace protocol
|
||||||
|
} // namespace td
|
||||||
55
include/td/protocol/PacketDeclare.h
Normal file
55
include/td/protocol/PacketDeclare.h
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \file PacketDeclare.h
|
||||||
|
* \brief Holds the definitions of the packets (but not their content)
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
namespace protocol {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \enum PacketSender
|
||||||
|
* \brief Indicate who should send a packet
|
||||||
|
*/
|
||||||
|
enum class PacketSenderType {
|
||||||
|
/** Sent by clients and server */
|
||||||
|
Both = 1,
|
||||||
|
/** Sent by clients to the server */
|
||||||
|
Client,
|
||||||
|
/** Sent by server to the clients */
|
||||||
|
Server,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class PacketSendType {
|
||||||
|
Reliable = 1,
|
||||||
|
Unreliable,
|
||||||
|
UnreliableOrdered,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \def DeclareAllPacket
|
||||||
|
* \brief Avoids repetitive operations on packets
|
||||||
|
*/
|
||||||
|
#define DeclareAllPacket() \
|
||||||
|
DeclarePacket(ChatMessage, Reliable, Both) \
|
||||||
|
DeclarePacket(Disconnect, Reliable, Both) \
|
||||||
|
DeclarePacket(KeepAlive, Reliable, Both) \
|
||||||
|
DeclarePacket(LoggingSuccess, Reliable, Server) \
|
||||||
|
DeclarePacket(PlayerDeath, Reliable, Server) \
|
||||||
|
DeclarePacket(PlayerJoin, Reliable, Server) \
|
||||||
|
DeclarePacket(PlayerLeave, Reliable, Server) \
|
||||||
|
DeclarePacket(PlayerList, Reliable, Server) \
|
||||||
|
DeclarePacket(PlayerLogin, Reliable, Client) \
|
||||||
|
DeclarePacket(PlayerPositionAndRotation, Unreliable, Both) \
|
||||||
|
DeclarePacket(PlayerShoot, Reliable, Both) \
|
||||||
|
DeclarePacket(PlayerStats, Reliable, Server) \
|
||||||
|
DeclarePacket(ServerConfig, Reliable, Server) \
|
||||||
|
DeclarePacket(ServerTps, Reliable, Server) \
|
||||||
|
DeclarePacket(UpdateGameState, Reliable, Server) \
|
||||||
|
DeclarePacket(UpdateHealth, Reliable, Client)
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace protocol
|
||||||
|
} // namespace td
|
||||||
58
include/td/protocol/PacketDispatcher.h
Normal file
58
include/td/protocol/PacketDispatcher.h
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \file PacketDispatcher.h
|
||||||
|
* \brief File containing the blitz::protocol::PacketDispatcher class
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <td/common/NonCopyable.h>
|
||||||
|
#include <td/protocol/Packets.h>
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
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);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace protocol
|
||||||
|
} // namespace td
|
||||||
19
include/td/protocol/PacketFactory.h
Normal file
19
include/td/protocol/PacketFactory.h
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <td/protocol/Packets.h>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
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 td
|
||||||
34
include/td/protocol/PacketHandler.h
Normal file
34
include/td/protocol/PacketHandler.h
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \file PacketHandler.h
|
||||||
|
* \brief File containing the blitz::protocol::PacketHandler class
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <td/protocol/Packets.h>
|
||||||
|
#include <td/protocol/PacketVisitor.h>
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
namespace protocol {
|
||||||
|
|
||||||
|
class PacketDispatcher;
|
||||||
|
|
||||||
|
#define DeclarePacket(PacketName, ...) virtual void Visit(const packets::PacketName&); virtual void HandlePacket(const packets::PacketName&) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \class PacketHandler
|
||||||
|
* \brief Class used to handle packets
|
||||||
|
*/
|
||||||
|
class PacketHandler : public PacketVisitor {
|
||||||
|
public:
|
||||||
|
PacketHandler() {}
|
||||||
|
~PacketHandler() {}
|
||||||
|
|
||||||
|
DeclareAllPacket()
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#undef DeclarePacket
|
||||||
|
|
||||||
|
} // namespace protocol
|
||||||
|
} // namespace td
|
||||||
60
include/td/protocol/PacketSender.h
Normal file
60
include/td/protocol/PacketSender.h
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <td/protocol/PacketVisitor.h>
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
|
||||||
|
class NetworkInterface;
|
||||||
|
|
||||||
|
namespace protocol {
|
||||||
|
|
||||||
|
#define DeclarePacket(PacketName, Reliability, ...) void Visit(const protocol::packets::PacketName& a_Packet) override;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////
|
||||||
|
/* PacketBroadcaster */
|
||||||
|
///////////////////////
|
||||||
|
class PacketBroadcaster : public protocol::PacketVisitor {
|
||||||
|
private:
|
||||||
|
NetworkInterface& m_NetworkInterface;
|
||||||
|
|
||||||
|
public:
|
||||||
|
PacketBroadcaster(NetworkInterface& a_NetworkInterface) : m_NetworkInterface(a_NetworkInterface) {}
|
||||||
|
|
||||||
|
void BroadcastPacket(const protocol::Packet& a_Packet) {
|
||||||
|
Check(a_Packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
DeclareAllPacket()
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////
|
||||||
|
/* PacketSender */
|
||||||
|
//////////////////
|
||||||
|
class PacketSender : public protocol::PacketVisitor {
|
||||||
|
private:
|
||||||
|
NetworkInterface& m_NetworkInterface;
|
||||||
|
PeerID m_PeerId;
|
||||||
|
|
||||||
|
public:
|
||||||
|
PacketSender(PeerID a_PeerId, NetworkInterface& a_NetworkInterface) : m_PeerId(a_PeerId), m_NetworkInterface(a_NetworkInterface) {}
|
||||||
|
|
||||||
|
void SendPacket(const protocol::Packet& a_Packet) {
|
||||||
|
Check(a_Packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
DeclareAllPacket()
|
||||||
|
};
|
||||||
|
|
||||||
|
#undef DeclarePacket
|
||||||
|
|
||||||
|
} // namespace protocol
|
||||||
|
} // namespace td
|
||||||
20
include/td/protocol/PacketSerializer.h
Normal file
20
include/td/protocol/PacketSerializer.h
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <td/protocol/Packets.h>
|
||||||
|
#include <godot_cpp/variant/packed_byte_array.hpp>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
namespace protocol {
|
||||||
|
|
||||||
|
using PacketPtr = std::unique_ptr<Packet>;
|
||||||
|
|
||||||
|
namespace PacketSerializer {
|
||||||
|
|
||||||
|
godot::PackedByteArray Serialize(const Packet& a_Packet);
|
||||||
|
|
||||||
|
std::unique_ptr<Packet> Deserialize(godot::PackedByteArray& a_Data);
|
||||||
|
|
||||||
|
}
|
||||||
|
} // namespace protocol
|
||||||
|
} // namespace td
|
||||||
39
include/td/protocol/PacketVisitor.h
Normal file
39
include/td/protocol/PacketVisitor.h
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \file PacketVisitor.h
|
||||||
|
* \brief File containing the blitz::protocol::PacketVisitor class
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <td/protocol/Packets.h>
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
namespace protocol {
|
||||||
|
|
||||||
|
#define DeclarePacket(PacketName, ...) \
|
||||||
|
/** This function is called when the packet processed by PacketVisitor::Check is a PacketName */ \
|
||||||
|
virtual void Visit(const packets::PacketName&) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \class PacketVisitor
|
||||||
|
* \brief This class uses double-dispatch in order to find the real type of a packet
|
||||||
|
*/
|
||||||
|
class PacketVisitor : private NonCopyable {
|
||||||
|
protected:
|
||||||
|
PacketVisitor() {}
|
||||||
|
virtual ~PacketVisitor() {}
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* \brief Calls the right PacketVisitor::Visit method corresponding to the real type of the packet
|
||||||
|
* \param packet the Packet to visit
|
||||||
|
*/
|
||||||
|
void Check(const Packet& packet);
|
||||||
|
|
||||||
|
DeclareAllPacket()
|
||||||
|
};
|
||||||
|
|
||||||
|
#undef DeclarePacket
|
||||||
|
|
||||||
|
} // namespace protocol
|
||||||
|
} // namespace td
|
||||||
112
include/td/protocol/Packets.h
Normal file
112
include/td/protocol/Packets.h
Normal file
@@ -0,0 +1,112 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \file Packets.h
|
||||||
|
* \brief File containing the definitions of the packets
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <td/common/NonCopyable.h>
|
||||||
|
#include <td/protocol/PacketData.h>
|
||||||
|
#include <td/protocol/PacketDeclare.h>
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
namespace protocol {
|
||||||
|
|
||||||
|
class PacketVisitor;
|
||||||
|
|
||||||
|
/** A Packet id is 8 bits wide */
|
||||||
|
using PacketID = std::uint8_t;
|
||||||
|
|
||||||
|
#define DeclarePacket(PacketName, ...) /** PacketName */ PacketName,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \enum PacketType
|
||||||
|
* \brief Map a Packet to an id
|
||||||
|
*/
|
||||||
|
enum class PacketType : PacketID {
|
||||||
|
|
||||||
|
DeclareAllPacket()
|
||||||
|
|
||||||
|
/** The number of packets */
|
||||||
|
PACKET_COUNT
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#undef DeclarePacket
|
||||||
|
|
||||||
|
|
||||||
|
class Packet : private NonCopyable {
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* \return The real type of the packet
|
||||||
|
*/
|
||||||
|
virtual PacketType GetType() const = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief The network peer who sent the packet
|
||||||
|
*/
|
||||||
|
PeerID m_Sender;
|
||||||
|
|
||||||
|
private:
|
||||||
|
/** Use a PacketVisitor to make double-dispatch possible */
|
||||||
|
virtual void Accept(PacketVisitor& a_Visitor) const = 0;
|
||||||
|
|
||||||
|
friend class PacketVisitor;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
namespace packets {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \class ConcretePacket
|
||||||
|
* \brief A Packet associated with an id and holding data
|
||||||
|
* \tparam PT The packet type
|
||||||
|
* \tparam Data The structure holding the data of the packet (in blitz::protocol::data namespace)
|
||||||
|
*/
|
||||||
|
template <PacketType PT, typename Data>
|
||||||
|
class ConcretePacket : public Packet {
|
||||||
|
public:
|
||||||
|
/** The type of the struct holding the data */
|
||||||
|
using PacketDataType = Data;
|
||||||
|
|
||||||
|
/** The structure holding the actual data */
|
||||||
|
PacketDataType m_Data;
|
||||||
|
|
||||||
|
/** Construct the packet with data of type PacketDataType */
|
||||||
|
ConcretePacket(const PacketDataType& a_Data = {});
|
||||||
|
|
||||||
|
constexpr PacketType GetType() const override {
|
||||||
|
return PT;
|
||||||
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
|
void Accept(PacketVisitor& a_Visitor) const override;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// define BLITZ_INSTANCIATE_PACKETS
|
||||||
|
// before including this file
|
||||||
|
// if you want to instantiate templates
|
||||||
|
#ifdef BLITZ_INSTANCIATE_PACKETS
|
||||||
|
#define DeclarePacket(PacketName, ...) \
|
||||||
|
using PacketName = ConcretePacket<PacketType::PacketName, data::PacketName>; \
|
||||||
|
template class ConcretePacket<PacketType::PacketName, data::PacketName>;
|
||||||
|
#else
|
||||||
|
#define DeclarePacket(PacketName, ...) /** Defines the PacketName packet */ \
|
||||||
|
using PacketName = ConcretePacket<PacketType::PacketName, data::PacketName>;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
DeclareAllPacket()
|
||||||
|
|
||||||
|
#undef DeclarePacket
|
||||||
|
|
||||||
|
} // namespace packets
|
||||||
|
|
||||||
|
} // namespace protocol
|
||||||
|
} // namespace td
|
||||||
58
include/td/protocol/command/CommandData.h
Normal file
58
include/td/protocol/command/CommandData.h
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <td/Types.h>
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
namespace protocol {
|
||||||
|
|
||||||
|
|
||||||
|
struct LockStep {
|
||||||
|
std::uint8_t m_CommandNumber;
|
||||||
|
std::vector<LockStepCommand> m_Commands;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct LockSteps {
|
||||||
|
std::uint16_t m_FirstFrameNumber;
|
||||||
|
std::array<LockStep, 10> m_LockSteps;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
namespace data {
|
||||||
|
|
||||||
|
|
||||||
|
struct PlaceTower {
|
||||||
|
CastleType m_Type : 4;
|
||||||
|
PlayerID m_Placer : 4;
|
||||||
|
CastleCoords m_Position;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct UpgradeTower {
|
||||||
|
CastleID m_Tower : 12;
|
||||||
|
std::uint8_t m_Upgrade : 4;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SpawnTroop {
|
||||||
|
EntityType m_Type : 5;
|
||||||
|
std::uint8_t m_Level : 3;
|
||||||
|
EntityCoords m_Position;
|
||||||
|
PlayerID m_Sender;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct UseItem {
|
||||||
|
ShopItem m_Item : 4;
|
||||||
|
PlayerID m_User : 4;
|
||||||
|
EntityCoords m_Position;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct TeamChange {
|
||||||
|
PlayerID m_Player : 7;
|
||||||
|
Team m_NewTeam : 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace data
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace protocol
|
||||||
|
} // namespace td
|
||||||
@@ -1,8 +1,12 @@
|
|||||||
add_rules("mode.debug", "mode.release")
|
add_rules("mode.debug", "mode.release")
|
||||||
|
|
||||||
|
add_requires("fpm")
|
||||||
|
|
||||||
target("Tower-Defense2")
|
target("Tower-Defense2")
|
||||||
|
add_includedirs("include")
|
||||||
set_kind("binary")
|
set_kind("binary")
|
||||||
add_files("src/*.cpp")
|
add_files("src/*.cpp")
|
||||||
|
add_packages("fpm")
|
||||||
|
|
||||||
--
|
--
|
||||||
-- If you want to known more usage about xmake, please see https://xmake.io
|
-- If you want to known more usage about xmake, please see https://xmake.io
|
||||||
|
|||||||
Reference in New Issue
Block a user