#pragma once #include "misc/DataBuffer.h" #include "game/World.h" #include "game/BaseGame.h" #include namespace td { namespace protocol { class PacketHandler; enum class PacketType : std::uint8_t { // client --> server PlayerLogin = 0, SelectTeam, SpawnMob, SendMobs, PlaceTower, // client <-- server PlayerJoin, PlayerLeave, WorldBeginData, WorldData, UpdateMoney, UpdateEXP, UpdateLobbyTime, UpdateGameState, PlayerList, ConnectionInfo, UpdatePlayerTeam, ServerTps, WorldAddTower, UpdateMobStates, UpdateCastleLife, // client <--> server KeepAlive, Disconnect, UpgradeTower, RemoveTower, PlayerBuyItem, PlayerBuyMobUpgrade, PACKET_COUNT }; struct WorldHeader { game::TowerTileColorPalette m_TowerPlacePalette; game::Color m_WalkablePalette; std::vector m_DecorationPalette; game::Color m_Background; game::SpawnColorPalette m_SpawnColorPalette; game::TilePalette m_TilePalette; game::Spawn m_RedSpawn, m_BlueSpawn; game::TeamCastle m_RedCastle, m_BlueCastle; const game::World* m_World; }; struct WorldData { std::unordered_map m_Chunks; }; class Packet { public: Packet() {} virtual ~Packet() {} virtual DataBuffer Serialize(bool packetID = true) const = 0; virtual void Deserialize(DataBuffer& data) = 0; virtual void Dispatch(PacketHandler* handler) const = 0; void WritePacketID(DataBuffer& data, bool packetID) const; virtual PacketType GetType() const = 0; std::uint8_t GetID() const { return static_cast(GetType()); } }; typedef std::unique_ptr PacketPtr; class KeepAlivePacket : public Packet { private: std::uint64_t 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); virtual void Dispatch(PacketHandler* handler) const; std::uint64_t GetAliveID() const { return m_AliveID; } virtual PacketType GetType() const { return PacketType::KeepAlive; } }; class PlayerLoginPacket : public Packet { private: std::string m_PlayerName; public: PlayerLoginPacket() {} PlayerLoginPacket(std::string playerName) : m_PlayerName(playerName) {} virtual ~PlayerLoginPacket() {} virtual DataBuffer Serialize(bool packetID = true) const; virtual void Deserialize(DataBuffer& data); virtual void Dispatch(PacketHandler* handler) const; virtual PacketType GetType() const { return PacketType::PlayerLogin; } const std::string& GetPlayerName() const { return m_PlayerName; } }; class WorldBeginDataPacket : public Packet { private: WorldHeader m_Header; public: WorldBeginDataPacket() {} WorldBeginDataPacket(const game::World* world) { m_Header.m_World = world; } virtual ~WorldBeginDataPacket() {} virtual DataBuffer Serialize(bool packetID = true) const; virtual void Deserialize(DataBuffer& data); virtual void Dispatch(PacketHandler* handler) const; virtual PacketType GetType() const { return PacketType::WorldBeginData; } const game::TowerTileColorPalette& GetTowerTilePalette() const { return m_Header.m_TowerPlacePalette; } const game::Color& GetWalkableTileColor() const { return m_Header.m_WalkablePalette; } const std::vector& GetDecorationPalette() const { return m_Header.m_DecorationPalette; } const game::Color& GetBackgroundColor() const { return m_Header.m_Background; } const game::Spawn& GetRedSpawn() const { return m_Header.m_RedSpawn; } const game::Spawn& GetBlueSpawn() const { return m_Header.m_BlueSpawn; } const game::SpawnColorPalette& GetSpawnPalette() const { return m_Header.m_SpawnColorPalette; } const game::TeamCastle& GetRedCastle() const { return m_Header.m_RedCastle; } const game::TeamCastle& GetBlueCastle() const { return m_Header.m_BlueCastle; } const game::TilePalette GetTilePalette() const { return m_Header.m_TilePalette; } void setWorldHeader(const WorldHeader& header) { m_Header = header; } }; class WorldDataPacket : public Packet { private: WorldData m_WorldData; const game::World* m_World; public: WorldDataPacket() {} WorldDataPacket(const game::World* world) : m_World(world) {} virtual ~WorldDataPacket() {} virtual DataBuffer Serialize(bool packetID = true) const; virtual void Deserialize(DataBuffer& data); virtual void Dispatch(PacketHandler* handler) const; virtual PacketType GetType() const { return PacketType::WorldData; } const std::unordered_map& GetChunks() const { return m_WorldData.m_Chunks; } DataBuffer SerializeCustom() const; // allow serialisation with invalid World member void SetWorldData(const WorldData& worldData) { m_WorldData = worldData; } }; class UpdateMoneyPacket : public Packet { private: std::uint32_t m_NewAmount; public: UpdateMoneyPacket() {} UpdateMoneyPacket(std::uint32_t newAmount) : m_NewAmount(newAmount) {} virtual ~UpdateMoneyPacket() {} std::uint32_t GetGold() const { return m_NewAmount; } virtual DataBuffer Serialize(bool packetID = true) const; virtual void Deserialize(DataBuffer& data); virtual void Dispatch(PacketHandler* handler) const; virtual PacketType GetType() const { return PacketType::UpdateMoney; } }; class UpdateExpPacket : public Packet { private: std::uint32_t m_NewAmount; public: UpdateExpPacket() {} UpdateExpPacket(std::uint32_t newAmount) : m_NewAmount(newAmount) {} virtual ~UpdateExpPacket() {} virtual DataBuffer Serialize(bool packetID = true) const; virtual void Deserialize(DataBuffer& data); virtual void Dispatch(PacketHandler* handler) const; virtual PacketType GetType() const { return PacketType::UpdateEXP; } }; class UpdateLobbyTimePacket : public Packet { private: std::uint32_t m_RemainingTime; public: UpdateLobbyTimePacket() {} UpdateLobbyTimePacket(std::uint32_t remainingTime) : m_RemainingTime(remainingTime) {} virtual ~UpdateLobbyTimePacket() {} virtual DataBuffer Serialize(bool packetID = true) const; virtual void Deserialize(DataBuffer& data); virtual void Dispatch(PacketHandler* handler) const; std::uint32_t GetRemainingTime() const { return m_RemainingTime; } virtual PacketType GetType() const { return PacketType::UpdateLobbyTime; } }; class UpdateGameStatePacket : public Packet { private: game::GameState m_GameState; public: UpdateGameStatePacket() {} UpdateGameStatePacket(game::GameState gameState) : m_GameState(gameState) {} virtual ~UpdateGameStatePacket() {} virtual DataBuffer Serialize(bool packetID = true) const; virtual void Deserialize(DataBuffer& data); virtual void Dispatch(PacketHandler* handler) const; game::GameState GetGameState() const { return m_GameState; } virtual PacketType GetType() const { return PacketType::UpdateGameState; } }; struct PlayerInfo { std::string name; game::TeamColor team; }; class PlayerListPacket : public Packet { private: std::map m_Players; public: PlayerListPacket() {} PlayerListPacket(std::map players) : m_Players(players) {} virtual ~PlayerListPacket() {} virtual DataBuffer Serialize(bool packetID = true) const; virtual void Deserialize(DataBuffer& data); virtual void Dispatch(PacketHandler* handler) const; const std::map& GetPlayers() const { return m_Players; } virtual PacketType GetType() const { return PacketType::PlayerList; } }; class PlayerJoinPacket : public Packet { private: std::uint8_t m_PlayerID; std::string m_PlayerName; public: PlayerJoinPacket() {} PlayerJoinPacket(std::uint8_t 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); virtual void Dispatch(PacketHandler* handler) const; std::uint8_t GetPlayerID() const { return m_PlayerID; } const std::string& GetPlayerName() const { return m_PlayerName; } virtual PacketType GetType() const { return PacketType::PlayerJoin; } }; class PlayerLeavePacket : public Packet { private: std::uint8_t m_PlayerID; public: PlayerLeavePacket() {} PlayerLeavePacket(std::uint8_t playerID) : m_PlayerID(playerID) {} virtual ~PlayerLeavePacket() {} virtual DataBuffer Serialize(bool packetID = true) const; virtual void Deserialize(DataBuffer& data); virtual void Dispatch(PacketHandler* handler) const; std::uint8_t GetPlayerID() const { return m_PlayerID; } virtual PacketType GetType() const { return PacketType::PlayerLeave; } }; class ConnexionInfoPacket : public Packet { private: std::uint8_t m_ConnectionID; public: ConnexionInfoPacket() {} ConnexionInfoPacket(std::uint8_t connectionID) : m_ConnectionID(connectionID) {} virtual ~ConnexionInfoPacket() {} virtual DataBuffer Serialize(bool packetID = true) const; virtual void Deserialize(DataBuffer& data); virtual void Dispatch(PacketHandler* handler) const; std::uint8_t GetConnectionID() const { return m_ConnectionID; } virtual PacketType GetType() const { return PacketType::ConnectionInfo; } }; class SelectTeamPacket : public Packet { private: game::TeamColor m_SelectedTeam; public: SelectTeamPacket() {} SelectTeamPacket(game::TeamColor selectedTeam) : m_SelectedTeam(selectedTeam) {} virtual ~SelectTeamPacket() {} virtual DataBuffer Serialize(bool packetID = true) const; virtual void Deserialize(DataBuffer& data); virtual void Dispatch(PacketHandler* handler) const; game::TeamColor GetSelectedTeam() const { return m_SelectedTeam; } virtual PacketType GetType() const { return PacketType::SelectTeam; } }; class UpdatePlayerTeamPacket : public Packet { private: std::uint8_t m_PlayerID; game::TeamColor m_SelectedTeam; public: UpdatePlayerTeamPacket() {} UpdatePlayerTeamPacket(std::uint8_t playerID, game::TeamColor selectedTeam) : m_PlayerID(playerID), m_SelectedTeam(selectedTeam) {} virtual ~UpdatePlayerTeamPacket() {} virtual DataBuffer Serialize(bool packetID = true) const; virtual void Deserialize(DataBuffer& data); virtual void Dispatch(PacketHandler* handler) const; game::TeamColor GetSelectedTeam() const { return m_SelectedTeam; } std::uint8_t GetPlayerID() const { return m_PlayerID; } virtual PacketType GetType() const { return PacketType::UpdatePlayerTeam; } }; class DisconnectPacket : public Packet { private: std::string m_Reason; // only when sent from server public: DisconnectPacket() {} DisconnectPacket(std::string reason) : m_Reason(reason) {} virtual ~DisconnectPacket() {} virtual DataBuffer Serialize(bool packetID = true) const; virtual void Deserialize(DataBuffer& data); virtual void Dispatch(PacketHandler* handler) const; const std::string& GetReason() const { return m_Reason; } virtual PacketType GetType() const { return PacketType::Disconnect; } }; class ServerTpsPacket : public Packet { private: float m_TPS; std::uint64_t m_PacketSendTime; // used to calculate ping public: ServerTpsPacket() {} ServerTpsPacket(float tps, std::uint64_t sendTime) : m_TPS(tps), m_PacketSendTime(sendTime) {} virtual ~ServerTpsPacket() {} virtual DataBuffer Serialize(bool packetID = true) const; virtual void Deserialize(DataBuffer& data); virtual void Dispatch(PacketHandler* handler) const; float GetTPS() const { return m_TPS; } std::uint64_t GetPacketSendTime() const { return m_PacketSendTime; } virtual PacketType GetType() const { return PacketType::ServerTps; } }; struct MobSend { // represents a mob send game::MobType mobType : 4; game::MobLevel mobLevel : 4; std::uint8_t mobCount; // the max is 12 }; class SendMobsPacket : public Packet { private: std::vector m_MobSends; public: SendMobsPacket() {} SendMobsPacket(const std::vector& mobSends) : m_MobSends(mobSends) {} virtual ~SendMobsPacket() {} virtual DataBuffer Serialize(bool packetID = true) const; virtual void Deserialize(DataBuffer& data); virtual void Dispatch(PacketHandler* handler) const; const std::vector& GetMobSends() const { return m_MobSends; } virtual PacketType GetType() const { return PacketType::SendMobs; } }; class SpawnMobPacket : public Packet { private: game::MobID m_MobID; game::MobType m_MobType; game::MobLevel m_MobLevel; game::Direction m_MobDirection; game::PlayerID m_Sender; float m_MobX, m_MobY; public: SpawnMobPacket() {} SpawnMobPacket(game::MobID id, game::MobType type, std::uint8_t level, game::PlayerID sender, float x, float y, game::Direction dir) : m_MobID(id), m_MobType(type), m_MobLevel(level), m_MobDirection(dir), m_Sender(sender), m_MobX(x), m_MobY(y) {} virtual ~SpawnMobPacket() {} virtual DataBuffer Serialize(bool packetID = true) const; virtual void Deserialize(DataBuffer& data); virtual void Dispatch(PacketHandler* handler) const; game::MobID GetMobID() const { return m_MobID; } game::MobType GetMobType() const { return m_MobType; } game::MobLevel GetMobLevel() const { return m_MobLevel; } game::Direction GetMobDirection() const { return m_MobDirection; } game::PlayerID GetSender() const { return m_Sender; } float GetMobX() const { return m_MobX; } float GetMobY() const { return m_MobY; } virtual PacketType GetType() const { return PacketType::SpawnMob; } }; class PlaceTowerPacket : public Packet { private: std::int32_t m_TowerX, m_TowerY; game::TowerType m_TowerType; public: PlaceTowerPacket() {} PlaceTowerPacket(std::int32_t x, std::int32_t y, game::TowerType type) : m_TowerX(x), m_TowerY(y), m_TowerType(type) {} virtual ~PlaceTowerPacket() {} virtual DataBuffer Serialize(bool packetID = true) const; virtual void Deserialize(DataBuffer& data); virtual void Dispatch(PacketHandler* handler) const; std::int32_t GetTowerX() const { return m_TowerX; } std::int32_t GetTowerY() const { return m_TowerY; } game::TowerType GetTowerType() const { return m_TowerType; } virtual PacketType GetType() const { return PacketType::PlaceTower; } }; class WorldAddTowerPacket : public Packet { private: game::TowerID m_TowerID; std::int32_t m_TowerX, m_TowerY; game::TowerType m_TowerType; game::PlayerID m_Builder; public: WorldAddTowerPacket() {} WorldAddTowerPacket(game::TowerID id, std::int32_t x, std::int32_t y, game::TowerType type, game::PlayerID player) : m_TowerID(id), m_TowerX(x), m_TowerY(y), m_TowerType(type), m_Builder(player) {} virtual ~WorldAddTowerPacket() {} virtual DataBuffer Serialize(bool packetID = true) const; virtual void Deserialize(DataBuffer& data); virtual void Dispatch(PacketHandler* handler) const; game::TowerID GetTowerID() const { return m_TowerID; } std::int32_t GetTowerX() const { return m_TowerX; } std::int32_t GetTowerY() const { return m_TowerY; } game::TowerType GetTowerType() const { return m_TowerType; } game::PlayerID GetBuilder() const { return m_Builder; } virtual PacketType GetType() const { return PacketType::WorldAddTower; } }; class RemoveTowerPacket : public Packet { private: game::TowerID m_TowerID; public: RemoveTowerPacket() {} RemoveTowerPacket(game::TowerID id) : m_TowerID(id) {} virtual ~RemoveTowerPacket() {} virtual DataBuffer Serialize(bool packetID = true) const; virtual void Deserialize(DataBuffer& data); virtual void Dispatch(PacketHandler* handler) const; game::TowerID GetTowerID() const { return m_TowerID; } virtual PacketType GetType() const { return PacketType::RemoveTower; } }; class UpgradeTowerPacket : public Packet { private: game::TowerID m_TowerID; game::TowerLevel m_TowerLevel; public: UpgradeTowerPacket() {} UpgradeTowerPacket(game::TowerID tower, game::TowerLevel level) : m_TowerID(tower), m_TowerLevel(level) {} virtual ~UpgradeTowerPacket() {} virtual DataBuffer Serialize(bool packetID = true) const; virtual void Deserialize(DataBuffer& data); virtual void Dispatch(PacketHandler* handler) const; game::TowerID GetTowerID() const { return m_TowerID; } game::TowerLevel GetTowerLevel() const { return m_TowerLevel; } virtual PacketType GetType() const { return PacketType::UpgradeTower; } }; class MobState { using Point = utils::shape::Point; private: game::MobID m_MobID; Point m_MobPosition; float m_MobLife; game::Direction m_MobDirection; public: MobState() {} MobState(game::MobID id, const Point& position, float life, game::Direction direction) : m_MobID(id), m_MobPosition(position), m_MobLife(life), m_MobDirection(direction) {} game::MobID GetMobId() const { return m_MobID; } Point GetMobPosition() const { return m_MobPosition; } float GetMobLife() const { return m_MobLife; } game::Direction GetMobDirection() const { return m_MobDirection; } }; class UpdateMobStatesPacket : public Packet { private: std::vector m_MobStates; public: UpdateMobStatesPacket() {} virtual ~UpdateMobStatesPacket() {} virtual DataBuffer Serialize(bool packetID = true) const; virtual void Deserialize(DataBuffer& data); virtual void Dispatch(PacketHandler* handler) const; void addMobState(MobState mobState) { m_MobStates.push_back(mobState); } const std::vector& GetMobStates() const { return m_MobStates; } virtual PacketType GetType() const { return PacketType::UpdateMobStates; } }; class UpdateCastleLifePacket : public Packet { private: std::uint16_t m_CastleLife; game::TeamColor m_Team; public: UpdateCastleLifePacket() {} UpdateCastleLifePacket(std::uint16_t life, game::TeamColor team) : m_CastleLife(life), m_Team(team) {} virtual ~UpdateCastleLifePacket() {} virtual DataBuffer Serialize(bool packetID = true) const; virtual void Deserialize(DataBuffer& data); virtual void Dispatch(PacketHandler* handler) const; std::uint16_t GetCastleLife() const { return m_CastleLife; } game::TeamColor GetTeamColor() const { return m_Team; } virtual PacketType GetType() const { return PacketType::UpdateCastleLife; } }; enum class ItemType : std::uint8_t { // Upgrades ClickerUpgrade, GoldPerSecUpgrade, // Items }; /** Packet used by the client to buy items or upgrades Packet used by the server to confirm transaction */ class PlayerBuyItemPacket : public Packet { private: ItemType m_ItemType; std::uint8_t m_Count; public: PlayerBuyItemPacket() {} PlayerBuyItemPacket(ItemType itemType, std::uint8_t count) : m_ItemType(itemType), m_Count(count) {} virtual ~PlayerBuyItemPacket() {} virtual DataBuffer Serialize(bool packetID = true) const; virtual void Deserialize(DataBuffer& data); virtual void Dispatch(PacketHandler* handler) const; ItemType GetItemType() const { return m_ItemType; } std::uint8_t GetCount() const { return m_Count; } virtual PacketType GetType() const { return PacketType::PlayerBuyItem; } }; /** Packet used by the client to buy mob upgrades Packet used by the server to confirm transaction */ class PlayerBuyMobUpgradePacket : public Packet { private: game::MobType m_MobType; std::uint8_t m_MobLevel; public: PlayerBuyMobUpgradePacket() {} PlayerBuyMobUpgradePacket(game::MobType mobType, std::uint8_t level) : m_MobType(mobType), m_MobLevel(level) {} virtual ~PlayerBuyMobUpgradePacket() {} virtual DataBuffer Serialize(bool packetID = true) const; virtual void Deserialize(DataBuffer& data); virtual void Dispatch(PacketHandler* handler) const; game::MobType GetMobType() const { return m_MobType; } std::uint8_t GetLevel() const { return m_MobLevel; } virtual PacketType GetType() const { return PacketType::PlayerBuyMobUpgrade; } }; } // namespace protocol } // namespace td