592 lines
19 KiB
C++
592 lines
19 KiB
C++
#include "protocol/PacketHandler.h"
|
|
#include <cmath>
|
|
|
|
#define REGISTER_DISPATCH_CLASS(className) void className::Dispatch(PacketHandler* handler) const {handler->HandlePacket(this);}
|
|
|
|
namespace td {
|
|
namespace protocol {
|
|
|
|
const int BITS_IN_BYTE = 8;
|
|
const int BITS_IN_LONG = BITS_IN_BYTE * sizeof(std::uint64_t);
|
|
|
|
unsigned int countBits(unsigned int number) {
|
|
// log function in base 2
|
|
// take only integer part
|
|
return (int)std::log2(number) + 1;
|
|
}
|
|
|
|
DataBuffer& operator<<(DataBuffer& buffer, game::TilePtr tile) {
|
|
buffer << tile->getType();
|
|
switch (tile->getType()) {
|
|
case game::TileType::Tower: {
|
|
const game::TowerTile* towerTile = (const game::TowerTile*)tile.get();
|
|
buffer << towerTile->color_palette_ref << towerTile->team_owner;
|
|
break;
|
|
}
|
|
case game::TileType::Walk: {
|
|
const game::WalkableTile* walkTile = (const game::WalkableTile*)tile.get();
|
|
buffer << walkTile->direction;
|
|
break;
|
|
}
|
|
case game::TileType::Decoration: {
|
|
const game::DecorationTile* decoTile = (const game::DecorationTile*)tile.get();
|
|
buffer << decoTile->color_palette_ref;
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
return buffer;
|
|
}
|
|
|
|
DataBuffer& operator>>(DataBuffer& buffer, game::TilePtr& tile) {
|
|
game::TileType tileType;
|
|
buffer >> tileType;
|
|
switch (tileType) {
|
|
case game::TileType::Tower: {
|
|
std::shared_ptr<game::TowerTile> tilePtr = std::make_shared<game::TowerTile>();
|
|
buffer >> tilePtr->color_palette_ref >> tilePtr->team_owner;
|
|
tile = tilePtr;
|
|
break;
|
|
}
|
|
case game::TileType::Walk: {
|
|
std::shared_ptr<game::WalkableTile> tilePtr = std::make_shared<game::WalkableTile>();
|
|
buffer >> tilePtr->direction;
|
|
tile = tilePtr;
|
|
break;
|
|
}
|
|
case game::TileType::Decoration: {
|
|
std::shared_ptr<game::DecorationTile> tilePtr = std::make_shared<game::DecorationTile>();
|
|
buffer >> tilePtr->color_palette_ref;
|
|
tile = tilePtr;
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
return buffer;
|
|
}
|
|
|
|
DataBuffer PlayerLoginPacket::Serialize() const {
|
|
DataBuffer data;
|
|
data << getID() << m_PlayerName;
|
|
return data;
|
|
}
|
|
|
|
void PlayerLoginPacket::Deserialize(DataBuffer& data) {
|
|
data >> m_PlayerName;
|
|
}
|
|
|
|
DataBuffer WorldBeginDataPacket::SerializeCustom() const {
|
|
DataBuffer data;
|
|
const game::TowerTileColorPalette towerTilePalette = m_Header.m_TowerPlacePalette;
|
|
const std::vector<game::Color>& decoTilePalette = m_Header.m_DecorationPalette;
|
|
|
|
data << getID() << towerTilePalette << m_Header.m_WalkablePalette
|
|
<< (std::uint16_t)decoTilePalette.size();
|
|
|
|
// deco color palette
|
|
std::size_t bufferSize = data.GetSize();
|
|
data.Resize(bufferSize + decoTilePalette.size() * sizeof(game::Color));
|
|
|
|
memcpy((std::uint8_t*)data.data() + bufferSize, decoTilePalette.data(), decoTilePalette.size() * sizeof(game::Color));
|
|
|
|
data << m_Header.m_Background;
|
|
|
|
const game::Spawn& redSpawn = m_Header.m_RedSpawn, blueSpawn = m_Header.m_BlueSpawn;
|
|
const game::TeamCastle& redCastle = m_Header.m_RedCastle, blueCastle = m_Header.m_BlueCastle;
|
|
|
|
data << redSpawn << static_cast<utils::shape::Rectangle>(redCastle);
|
|
data << blueSpawn << static_cast<utils::shape::Rectangle>(blueCastle);
|
|
|
|
// tile palette
|
|
data << static_cast<std::uint64_t>(m_Header.m_TilePalette.size());
|
|
|
|
for (game::TilePtr tile : m_Header.m_TilePalette) {
|
|
data << tile;
|
|
}
|
|
|
|
data << m_Header.m_SpawnColorPalette;
|
|
|
|
return data;
|
|
}
|
|
|
|
DataBuffer WorldBeginDataPacket::Serialize() const {
|
|
DataBuffer data;
|
|
const game::TowerTileColorPalette towerTilePalette = m_Header.m_World->getTowerTileColorPalette();
|
|
const std::vector<game::Color>& decoTilePalette = m_Header.m_World->getDecorationPalette();
|
|
|
|
data << getID() << towerTilePalette << m_Header.m_World->getWalkableTileColor()
|
|
<< (std::uint16_t)decoTilePalette.size();
|
|
|
|
// deco color palette
|
|
std::size_t bufferSize = data.GetSize();
|
|
data.Resize(bufferSize + decoTilePalette.size() * sizeof(game::Color));
|
|
|
|
memcpy((std::uint8_t*)data.data() + bufferSize, decoTilePalette.data(), decoTilePalette.size() * sizeof(game::Color));
|
|
|
|
data << m_Header.m_World->getBackgroundColor();
|
|
|
|
const game::Spawn& redSpawn = m_Header.m_World->getRedTeam().getSpawn(), blueSpawn = m_Header.m_World->getBlueTeam().getSpawn();
|
|
const game::TeamCastle& redCastle = m_Header.m_World->getRedTeam().getCastle(), blueCastle = m_Header.m_World->getBlueTeam().getCastle();
|
|
|
|
data << redSpawn << static_cast<utils::shape::Rectangle>(redCastle);
|
|
data << blueSpawn << static_cast<utils::shape::Rectangle>(blueCastle);
|
|
|
|
// tile palette
|
|
data << static_cast<std::uint64_t>(m_Header.m_World->getTilePalette().size());
|
|
|
|
for (game::TilePtr tile : m_Header.m_World->getTilePalette()) {
|
|
data << tile;
|
|
}
|
|
|
|
data << m_Header.m_World->getSpawnColors();
|
|
|
|
return data;
|
|
}
|
|
|
|
void WorldBeginDataPacket::Deserialize(DataBuffer& data) {
|
|
data >> m_Header.m_TowerPlacePalette >> m_Header.m_WalkablePalette;
|
|
|
|
std::uint16_t decoPaletteSize;
|
|
data >> decoPaletteSize;
|
|
|
|
std::size_t decoPalletteSizeByte = decoPaletteSize * sizeof(game::Color);
|
|
|
|
m_Header.m_DecorationPalette.resize(decoPaletteSize);
|
|
|
|
memcpy((std::uint8_t*)m_Header.m_DecorationPalette.data(), data.data() + data.GetReadOffset(), decoPalletteSizeByte);
|
|
|
|
data.SetReadOffset(data.GetReadOffset() + decoPalletteSizeByte);
|
|
|
|
data >> m_Header.m_Background;
|
|
|
|
utils::shape::Rectangle redCastle, blueCastle;
|
|
|
|
data >> m_Header.m_RedSpawn >> redCastle;
|
|
data >> m_Header.m_BlueSpawn >> blueCastle;
|
|
|
|
m_Header.m_RedCastle.setShape(redCastle);
|
|
m_Header.m_BlueCastle.setShape(blueCastle);
|
|
|
|
std::uint64_t tilePaletteSize;
|
|
data >> tilePaletteSize;
|
|
|
|
m_Header.m_TilePalette.reserve(tilePaletteSize);
|
|
|
|
for (std::uint64_t tileNumber = 0; tileNumber < tilePaletteSize; tileNumber++) {
|
|
game::TilePtr tile;
|
|
data >> tile;
|
|
m_Header.m_TilePalette.push_back(tile);
|
|
}
|
|
|
|
data >> m_Header.m_SpawnColorPalette;
|
|
}
|
|
|
|
typedef std::vector<uint64_t> ChunkPackedData;
|
|
|
|
DataBuffer WorldDataPacket::SerializeCustom() const {
|
|
DataBuffer data;
|
|
data << getID() << m_WorldData.m_Chunks.size();
|
|
for (const auto& pair : m_WorldData.m_Chunks) {
|
|
game::ChunkCoord coords = pair.first;
|
|
game::ChunkPtr chunk = pair.second;
|
|
|
|
data << coords.x << coords.y << (std::uint64_t)chunk->palette.size();
|
|
|
|
std::size_t bufferSize = data.GetSize();
|
|
data.Resize(data.GetSize() + chunk->palette.size() * sizeof(game::ChunkPalette::value_type));
|
|
memcpy((std::uint8_t*)data.data() + bufferSize, chunk->palette.data(), chunk->palette.size() * sizeof(game::ChunkPalette::value_type));
|
|
|
|
std::uint8_t bitsPerTile = countBits(chunk->palette.size());
|
|
|
|
game::Chunk::ChunkData::value_type individualValueMask = ((1 << bitsPerTile) - 1);
|
|
|
|
ChunkPackedData chunkData(game::Chunk::ChunkSize / (BITS_IN_BYTE * sizeof(ChunkPackedData::value_type) / bitsPerTile), 0);
|
|
|
|
for (int tileNumber = 0; tileNumber < game::Chunk::ChunkSize; tileNumber++) {
|
|
int startLong = (tileNumber * bitsPerTile) / BITS_IN_LONG;
|
|
int startOffset = (tileNumber * bitsPerTile) % BITS_IN_LONG;
|
|
int endLong = ((tileNumber + 1) * bitsPerTile - 1) / BITS_IN_LONG;
|
|
|
|
std::uint64_t value = chunk->tiles[tileNumber];
|
|
|
|
value &= individualValueMask;
|
|
|
|
|
|
chunkData[startLong] |= (value << startOffset);
|
|
|
|
if (startLong != endLong) {
|
|
chunkData[endLong] = (value >> (BITS_IN_LONG - startOffset));
|
|
}
|
|
}
|
|
|
|
bufferSize = data.GetSize();
|
|
data.Resize(data.GetSize() + chunkData.size() * sizeof(ChunkPackedData::value_type));
|
|
memcpy((std::uint8_t*)data.data() + bufferSize, chunkData.data(), chunkData.size() * sizeof(ChunkPackedData::value_type));
|
|
}
|
|
return data;
|
|
}
|
|
|
|
DataBuffer WorldDataPacket::Serialize() const {
|
|
DataBuffer data;
|
|
data << getID() << m_World->getChunks().size();
|
|
for (const auto& pair : m_World->getChunks()) {
|
|
game::ChunkCoord coords = pair.first;
|
|
game::ChunkPtr chunk = pair.second;
|
|
|
|
data << coords.x << coords.y << (std::uint64_t)chunk->palette.size();
|
|
|
|
std::size_t bufferSize = data.GetSize();
|
|
data.Resize(data.GetSize() + chunk->palette.size() * sizeof(game::ChunkPalette::value_type));
|
|
memcpy((std::uint8_t*)data.data() + bufferSize, chunk->palette.data(), chunk->palette.size() * sizeof(game::ChunkPalette::value_type));
|
|
|
|
std::uint8_t bitsPerTile = countBits(chunk->palette.size());
|
|
|
|
game::Chunk::ChunkData::value_type individualValueMask = ((1 << bitsPerTile) - 1);
|
|
|
|
ChunkPackedData chunkData(game::Chunk::ChunkSize / (BITS_IN_BYTE * sizeof(ChunkPackedData::value_type) / bitsPerTile), 0);
|
|
|
|
for (int tileNumber = 0; tileNumber < game::Chunk::ChunkSize; tileNumber++) {
|
|
int startLong = (tileNumber * bitsPerTile) / BITS_IN_LONG;
|
|
int startOffset = (tileNumber * bitsPerTile) % BITS_IN_LONG;
|
|
int endLong = ((tileNumber + 1) * bitsPerTile - 1) / BITS_IN_LONG;
|
|
|
|
std::uint64_t value = chunk->tiles[tileNumber];
|
|
|
|
value &= individualValueMask;
|
|
|
|
|
|
chunkData[startLong] |= (value << startOffset);
|
|
|
|
if (startLong != endLong) {
|
|
chunkData[endLong] = (value >> (BITS_IN_LONG - startOffset));
|
|
}
|
|
}
|
|
|
|
bufferSize = data.GetSize();
|
|
data.Resize(data.GetSize() + chunkData.size() * sizeof(ChunkPackedData::value_type));
|
|
memcpy((std::uint8_t*)data.data() + bufferSize, chunkData.data(), chunkData.size() * sizeof(ChunkPackedData::value_type));
|
|
}
|
|
return data;
|
|
}
|
|
|
|
void WorldDataPacket::Deserialize(DataBuffer& data) {
|
|
std::uint64_t chunkCount;
|
|
data >> chunkCount;
|
|
|
|
for (std::uint64_t chunkNumber = 0; chunkNumber < chunkCount; chunkNumber++) {
|
|
game::ChunkPtr chunk = std::make_shared<game::Chunk>();
|
|
|
|
decltype(game::ChunkCoord::x) chunkX, chunkY;
|
|
data >> chunkX >> chunkY;
|
|
|
|
std::uint64_t chunkPaletteSize;
|
|
data >> chunkPaletteSize;
|
|
|
|
game::ChunkPalette chunkPalette(chunkPaletteSize);
|
|
|
|
memcpy((void*)chunkPalette.data(), data.data() + data.GetReadOffset(), chunkPaletteSize * sizeof(game::ChunkPalette::value_type));
|
|
data.SetReadOffset(data.GetReadOffset() + chunkPaletteSize * sizeof(game::ChunkPalette::value_type));
|
|
|
|
chunk->palette = chunkPalette;
|
|
|
|
std::uint8_t bitsPerTile = countBits(chunkPaletteSize);
|
|
|
|
// A bitmask that contains bitsPerTile set bits
|
|
game::Chunk::ChunkData::value_type individualValueMask = ((1 << bitsPerTile) - 1);
|
|
|
|
ChunkPackedData chunkData(game::Chunk::ChunkSize / (BITS_IN_BYTE * sizeof(ChunkPackedData::value_type) / bitsPerTile), 0);
|
|
|
|
memcpy((void*)chunkData.data(), data.data() + data.GetReadOffset(), chunkData.size() * sizeof(ChunkPackedData::value_type));
|
|
data.SetReadOffset(data.GetReadOffset() + chunkData.size() * sizeof(ChunkPackedData::value_type));
|
|
|
|
for (int tileNumber = 0; tileNumber < game::Chunk::ChunkSize; tileNumber++) {
|
|
int startLong = (tileNumber * bitsPerTile) / BITS_IN_LONG;
|
|
int startOffset = (tileNumber * bitsPerTile) % BITS_IN_LONG;
|
|
int endLong = ((tileNumber + 1) * bitsPerTile - 1) / BITS_IN_LONG;
|
|
|
|
game::Chunk::ChunkData::value_type value;
|
|
if (startLong == endLong) {
|
|
value = (chunkData[startLong] >> startOffset);
|
|
} else {
|
|
int endOffset = BITS_IN_LONG - startOffset;
|
|
value = (chunkData[startLong] >> startOffset | chunkData[endLong] << endOffset);
|
|
}
|
|
value &= individualValueMask;
|
|
|
|
chunk->tiles[tileNumber] = value;
|
|
}
|
|
|
|
|
|
m_WorldData.m_Chunks.insert({ {chunkX, chunkY}, chunk });
|
|
}
|
|
}
|
|
|
|
DataBuffer KeepAlivePacket::Serialize() const {
|
|
DataBuffer data;
|
|
data << getID() << m_AliveID;
|
|
return data;
|
|
}
|
|
|
|
void KeepAlivePacket::Deserialize(DataBuffer& data) {
|
|
data >> m_AliveID;
|
|
}
|
|
|
|
DataBuffer UpdateMoneyPacket::Serialize() const {
|
|
DataBuffer data;
|
|
data << getID() << m_NewAmount;
|
|
return data;
|
|
}
|
|
|
|
void UpdateMoneyPacket::Deserialize(DataBuffer& data) {
|
|
data >> m_NewAmount;
|
|
}
|
|
|
|
DataBuffer UpdateExpPacket::Serialize() const {
|
|
DataBuffer data;
|
|
data << getID() << m_NewAmount;
|
|
return data;
|
|
}
|
|
|
|
void UpdateExpPacket::Deserialize(DataBuffer& data) {
|
|
data >> m_NewAmount;
|
|
}
|
|
|
|
DataBuffer UpdateLobbyTimePacket::Serialize() const {
|
|
DataBuffer data;
|
|
data << getID() << m_RemainingTime;
|
|
return data;
|
|
}
|
|
|
|
void UpdateLobbyTimePacket::Deserialize(DataBuffer& data) {
|
|
data >> m_RemainingTime;
|
|
}
|
|
|
|
DataBuffer UpdateGameStatePacket::Serialize() const {
|
|
DataBuffer data;
|
|
data << getID() << m_GameState;
|
|
return data;
|
|
}
|
|
|
|
void UpdateGameStatePacket::Deserialize(DataBuffer& data) {
|
|
data >> m_GameState;
|
|
}
|
|
|
|
DataBuffer PlayerListPacket::Serialize() const {
|
|
DataBuffer data;
|
|
data << getID() << (std::uint8_t)m_Players.size();
|
|
for (auto pair : m_Players) {
|
|
data << pair.first << pair.second.name << pair.second.team;
|
|
}
|
|
return data;
|
|
}
|
|
|
|
void PlayerListPacket::Deserialize(DataBuffer& data) {
|
|
std::uint8_t playerCount;
|
|
data >> playerCount;
|
|
|
|
for (int i = 0; i < playerCount; i++) {
|
|
std::uint8_t playerID;
|
|
PlayerInfo playerInfo;
|
|
data >> playerID >> playerInfo.name >> playerInfo.team;
|
|
m_Players.insert({ playerID, playerInfo });
|
|
}
|
|
}
|
|
|
|
DataBuffer PlayerJoinPacket::Serialize() const {
|
|
DataBuffer data;
|
|
data << getID() << m_PlayerID << m_PlayerName;
|
|
return data;
|
|
}
|
|
|
|
void PlayerJoinPacket::Deserialize(DataBuffer& data) {
|
|
data >> m_PlayerID >> m_PlayerName;
|
|
}
|
|
|
|
DataBuffer PlayerLeavePacket::Serialize() const {
|
|
DataBuffer data;
|
|
data << getID() << m_PlayerID;
|
|
return data;
|
|
}
|
|
|
|
void PlayerLeavePacket::Deserialize(DataBuffer& data) {
|
|
data >> m_PlayerID;
|
|
}
|
|
|
|
DataBuffer ConnexionInfoPacket::Serialize() const {
|
|
DataBuffer data;
|
|
data << getID() << m_ConnectionID;
|
|
return data;
|
|
}
|
|
|
|
void ConnexionInfoPacket::Deserialize(DataBuffer& data) {
|
|
data >> m_ConnectionID;
|
|
}
|
|
|
|
DataBuffer SelectTeamPacket::Serialize() const {
|
|
DataBuffer data;
|
|
data << getID() << m_SelectedTeam;
|
|
return data;
|
|
}
|
|
|
|
void SelectTeamPacket::Deserialize(DataBuffer& data) {
|
|
data >> m_SelectedTeam;
|
|
}
|
|
|
|
DataBuffer UpdatePlayerTeamPacket::Serialize() const {
|
|
DataBuffer data;
|
|
data << getID() << m_PlayerID << m_SelectedTeam;
|
|
return data;
|
|
}
|
|
|
|
void UpdatePlayerTeamPacket::Deserialize(DataBuffer& data) {
|
|
data >> m_PlayerID >> m_SelectedTeam;
|
|
}
|
|
|
|
DataBuffer DisconnectPacket::Serialize() const {
|
|
DataBuffer data;
|
|
data << getID() << m_Reason;
|
|
return data;
|
|
}
|
|
|
|
void DisconnectPacket::Deserialize(DataBuffer& data) {
|
|
data >> m_Reason;
|
|
}
|
|
|
|
DataBuffer ServerTpsPacket::Serialize() const {
|
|
DataBuffer data;
|
|
data << getID() << m_TPS << m_PacketSendTime;
|
|
return data;
|
|
}
|
|
|
|
void ServerTpsPacket::Deserialize(DataBuffer& data) {
|
|
data >> m_TPS >> m_PacketSendTime;
|
|
}
|
|
|
|
DataBuffer SpawnMobPacket::Serialize() const {
|
|
DataBuffer data;
|
|
data << getID() << m_MobID << m_MobType << m_MobLevel << m_MobDirection
|
|
<< m_Sender << m_MobX << m_MobY;
|
|
return data;
|
|
}
|
|
|
|
void SpawnMobPacket::Deserialize(DataBuffer& data) {
|
|
data >> m_MobID >> m_MobType >> m_MobLevel >> m_MobDirection
|
|
>> m_Sender >> m_MobX >> m_MobY;
|
|
}
|
|
|
|
DataBuffer PlaceTowerPacket::Serialize() const {
|
|
DataBuffer data;
|
|
data << getID() << m_TowerX << m_TowerY << m_TowerType;
|
|
return data;
|
|
}
|
|
|
|
void PlaceTowerPacket::Deserialize(DataBuffer& data) {
|
|
data >> m_TowerX >> m_TowerY >> m_TowerType;
|
|
}
|
|
|
|
DataBuffer WorldAddTowerPacket::Serialize() const {
|
|
DataBuffer data;
|
|
data << getID() << m_TowerID << m_TowerX << m_TowerY << m_TowerType << m_Builder;
|
|
return data;
|
|
}
|
|
|
|
void WorldAddTowerPacket::Deserialize(DataBuffer& data) {
|
|
data >> m_TowerID >> m_TowerX >> m_TowerY >> m_TowerType >> m_Builder;
|
|
}
|
|
|
|
DataBuffer RemoveTowerPacket::Serialize() const {
|
|
DataBuffer data;
|
|
data << getID() << m_TowerID;
|
|
return data;
|
|
}
|
|
|
|
void RemoveTowerPacket::Deserialize(DataBuffer& data) {
|
|
data >> m_TowerID;
|
|
}
|
|
|
|
DataBuffer SendMobsPacket::Serialize() const {
|
|
DataBuffer data;
|
|
data << getID() << static_cast<std::uint8_t>(m_MobSends.size());
|
|
for (const MobSend& mobSend : m_MobSends) {
|
|
data << mobSend;
|
|
}
|
|
return data;
|
|
}
|
|
|
|
void SendMobsPacket::Deserialize(DataBuffer& data) {
|
|
std::uint8_t mobSendCount;
|
|
data >> mobSendCount;
|
|
protocol::MobSend mobSend;
|
|
for (int i = 0; i < mobSendCount; i++) {
|
|
data >> mobSend;
|
|
m_MobSends.push_back(mobSend);
|
|
}
|
|
}
|
|
|
|
DataBuffer UpgradeTowerPacket::Serialize() const {
|
|
DataBuffer data;
|
|
data << getID() << m_TowerID << m_TowerLevel;
|
|
return data;
|
|
}
|
|
|
|
void UpgradeTowerPacket::Deserialize(DataBuffer& data) {
|
|
data >> m_TowerID >> m_TowerLevel;
|
|
}
|
|
|
|
DataBuffer UpdateCastleLifePacket::Serialize() const {
|
|
DataBuffer data;
|
|
data << getID() << m_CastleLife << m_Team;
|
|
return data;
|
|
}
|
|
|
|
void UpdateCastleLifePacket::Deserialize(DataBuffer& data) {
|
|
data >> m_CastleLife >> m_Team;
|
|
}
|
|
|
|
DataBuffer UpdateMobStatesPacket::Serialize() const {
|
|
DataBuffer data;
|
|
data << getID() << static_cast<std::uint64_t>(m_MobStates.size());
|
|
for (auto mobState : m_MobStates) {
|
|
data << mobState;
|
|
}
|
|
return data;
|
|
}
|
|
|
|
void UpdateMobStatesPacket::Deserialize(DataBuffer& data) {
|
|
std::uint64_t mobCount;
|
|
data >> mobCount;
|
|
m_MobStates.resize(mobCount);
|
|
for (std::uint64_t mobIndex = 0; mobIndex < mobCount; mobIndex++) {
|
|
data >> m_MobStates[mobIndex];
|
|
}
|
|
}
|
|
|
|
REGISTER_DISPATCH_CLASS(PlayerLoginPacket);
|
|
REGISTER_DISPATCH_CLASS(WorldBeginDataPacket);
|
|
REGISTER_DISPATCH_CLASS(WorldDataPacket);
|
|
REGISTER_DISPATCH_CLASS(KeepAlivePacket);
|
|
REGISTER_DISPATCH_CLASS(UpdateExpPacket);
|
|
REGISTER_DISPATCH_CLASS(UpdateMoneyPacket);
|
|
REGISTER_DISPATCH_CLASS(UpdateLobbyTimePacket);
|
|
REGISTER_DISPATCH_CLASS(UpdateGameStatePacket);
|
|
REGISTER_DISPATCH_CLASS(PlayerListPacket);
|
|
REGISTER_DISPATCH_CLASS(PlayerJoinPacket);
|
|
REGISTER_DISPATCH_CLASS(PlayerLeavePacket);
|
|
REGISTER_DISPATCH_CLASS(ConnexionInfoPacket);
|
|
REGISTER_DISPATCH_CLASS(SelectTeamPacket);
|
|
REGISTER_DISPATCH_CLASS(UpdatePlayerTeamPacket);
|
|
REGISTER_DISPATCH_CLASS(DisconnectPacket);
|
|
REGISTER_DISPATCH_CLASS(ServerTpsPacket);
|
|
REGISTER_DISPATCH_CLASS(SpawnMobPacket);
|
|
REGISTER_DISPATCH_CLASS(PlaceTowerPacket);
|
|
REGISTER_DISPATCH_CLASS(WorldAddTowerPacket);
|
|
REGISTER_DISPATCH_CLASS(RemoveTowerPacket);
|
|
REGISTER_DISPATCH_CLASS(SendMobsPacket);
|
|
REGISTER_DISPATCH_CLASS(UpgradeTowerPacket);
|
|
REGISTER_DISPATCH_CLASS(UpdateCastleLifePacket);
|
|
REGISTER_DISPATCH_CLASS(UpdateMobStatesPacket);
|
|
|
|
} // namespace protocol
|
|
} // namespace td
|