From 0b9b7bc1a8d5cf6f92b802dc376a189ef066e62d Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Mon, 20 Apr 2020 20:46:04 +0100 Subject: [PATCH] Unify entity spawn packet sending --- src/ClientHandle.cpp | 31 +-- src/ClientHandle.h | 6 +- src/Entities/ArrowEntity.cpp | 11 - src/Entities/ArrowEntity.h | 1 - src/Entities/Boat.cpp | 2 +- src/Entities/EnderCrystal.cpp | 2 +- src/Entities/FallingBlock.cpp | 2 +- src/Entities/Floater.cpp | 4 +- src/Entities/ItemFrame.cpp | 6 +- src/Entities/LeashKnot.cpp | 2 +- src/Entities/Minecart.cpp | 2 +- src/Entities/Pickup.cpp | 3 +- src/Entities/ProjectileEntity.cpp | 5 +- src/Entities/ProjectileEntity.h | 27 ++- src/Entities/SplashPotionEntity.cpp | 15 -- src/Entities/SplashPotionEntity.h | 2 - src/Entities/TNTEntity.cpp | 4 +- src/Items/ItemItemFrame.h | 4 +- src/Protocol/Protocol.h | 8 +- src/Protocol/ProtocolRecognizer.cpp | 43 +--- src/Protocol/ProtocolRecognizer.h | 8 +- src/Protocol/Protocol_1_11.cpp | 2 +- src/Protocol/Protocol_1_8.cpp | 351 +++++++++++++--------------- src/Protocol/Protocol_1_8.h | 19 +- src/Protocol/Protocol_1_9.cpp | 139 +++-------- src/Protocol/Protocol_1_9.h | 7 +- 26 files changed, 242 insertions(+), 464 deletions(-) diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index 30f7c986f..cbe8249c2 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -2733,15 +2733,6 @@ void cClientHandle::SendParticleEffect(const AString & a_ParticleName, const Vec -void cClientHandle::SendPickupSpawn(const cPickup & a_Pickup) -{ - m_Protocol->SendPickupSpawn(a_Pickup); -} - - - - - void cClientHandle::SendPaintingSpawn(const cPainting & a_Painting) { m_Protocol->SendPaintingSpawn(a_Painting); @@ -3031,9 +3022,9 @@ void cClientHandle::SendSoundParticleEffect(const EffectID a_EffectID, int a_Src -void cClientHandle::SendSpawnFallingBlock(const cFallingBlock & a_FallingBlock) +void cClientHandle::SendSpawnEntity(const cEntity & a_Entity) { - m_Protocol->SendSpawnFallingBlock(a_FallingBlock); + m_Protocol->SendSpawnEntity(a_Entity); } @@ -3049,24 +3040,6 @@ void cClientHandle::SendSpawnMob(const cMonster & a_Mob) -void cClientHandle::SendSpawnObject(const cEntity & a_Entity, char a_ObjectType, int a_ObjectData) -{ - m_Protocol->SendSpawnObject(a_Entity, a_ObjectType, a_ObjectData); -} - - - - - -void cClientHandle::SendSpawnVehicle(const cEntity & a_Vehicle, char a_VehicleType, char a_VehicleSubType) // VehicleSubType is specific to Minecarts -{ - m_Protocol->SendSpawnVehicle(a_Vehicle, a_VehicleType, a_VehicleSubType); -} - - - - - void cClientHandle::SendStatistics(const cStatManager & a_Manager) { m_Protocol->SendStatistics(a_Manager); diff --git a/src/ClientHandle.h b/src/ClientHandle.h index dde521cbf..817b2a7da 100644 --- a/src/ClientHandle.h +++ b/src/ClientHandle.h @@ -166,7 +166,6 @@ public: // tolua_export void SendEntityHeadLook (const cEntity & a_Entity); void SendEntityLook (const cEntity & a_Entity); void SendEntityMetadata (const cEntity & a_Entity); - void SendEntityProperties (const cEntity & a_Entity); void SendEntityRelMove (const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ); void SendEntityRelMoveLook (const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ); void SendEntityStatus (const cEntity & a_Entity, char a_Status); @@ -184,7 +183,6 @@ public: // tolua_export void SendPaintingSpawn (const cPainting & a_Painting); void SendParticleEffect (const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmount); void SendParticleEffect (const AString & a_ParticleName, const Vector3f a_Src, const Vector3f a_Offset, float a_ParticleData, int a_ParticleAmount, std::array a_Data); - void SendPickupSpawn (const cPickup & a_Pickup); void SendPlayerAbilities (void); void SendPlayerListAddPlayer (const cPlayer & a_Player); void SendPlayerListRemovePlayer (const cPlayer & a_Player); @@ -209,10 +207,8 @@ public: // tolua_export void SendSoundEffect (const AString & a_SoundName, double a_X, double a_Y, double a_Z, float a_Volume, float a_Pitch); // tolua_export void SendSoundEffect (const AString & a_SoundName, Vector3d a_Position, float a_Volume, float a_Pitch); // tolua_export void SendSoundParticleEffect (const EffectID a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data); - void SendSpawnFallingBlock (const cFallingBlock & a_FallingBlock); + void SendSpawnEntity (const cEntity & a_Entity); void SendSpawnMob (const cMonster & a_Mob); - void SendSpawnObject (const cEntity & a_Entity, char a_ObjectType, int a_ObjectData); - void SendSpawnVehicle (const cEntity & a_Vehicle, char a_VehicleType, char a_VehicleSubType = 0); void SendStatistics (const cStatManager & a_Manager); void SendTabCompletionResults (const AStringVector & a_Results); void SendTeleportEntity (const cEntity & a_Entity); diff --git a/src/Entities/ArrowEntity.cpp b/src/Entities/ArrowEntity.cpp index e0d1cebc1..17c915742 100644 --- a/src/Entities/ArrowEntity.cpp +++ b/src/Entities/ArrowEntity.cpp @@ -3,7 +3,6 @@ #include "Player.h" #include "ArrowEntity.h" #include "../Chunk.h" -#include "../ClientHandle.h" @@ -161,16 +160,6 @@ void cArrowEntity::CollectedBy(cPlayer & a_Dest) -void cArrowEntity::SpawnOn(cClientHandle & a_Client) -{ - a_Client.SendSpawnObject(*this, m_ProjectileKind, static_cast(m_CreatorData.m_UniqueID + 1)); - a_Client.SendEntityMetadata(*this); -} - - - - - void cArrowEntity::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) { Super::Tick(a_Dt, a_Chunk); diff --git a/src/Entities/ArrowEntity.h b/src/Entities/ArrowEntity.h index 8576ca002..474932514 100644 --- a/src/Entities/ArrowEntity.h +++ b/src/Entities/ArrowEntity.h @@ -108,7 +108,6 @@ protected: virtual void OnHitSolidBlock(Vector3d a_HitPos, eBlockFace a_HitFace) override; virtual void OnHitEntity(cEntity & a_EntityHit, Vector3d a_HitPos) override; virtual void CollectedBy(cPlayer & a_Player) override; - virtual void SpawnOn(cClientHandle & a_Client) override; virtual void Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override; }; // tolua_export diff --git a/src/Entities/Boat.cpp b/src/Entities/Boat.cpp index d5ccd7359..872b7e4d4 100644 --- a/src/Entities/Boat.cpp +++ b/src/Entities/Boat.cpp @@ -33,7 +33,7 @@ cBoat::cBoat(Vector3d a_Pos, eMaterial a_Material) : void cBoat::SpawnOn(cClientHandle & a_ClientHandle) { - a_ClientHandle.SendSpawnVehicle(*this, 1); + a_ClientHandle.SendSpawnEntity(*this); } diff --git a/src/Entities/EnderCrystal.cpp b/src/Entities/EnderCrystal.cpp index 11273f818..4f2bd857f 100644 --- a/src/Entities/EnderCrystal.cpp +++ b/src/Entities/EnderCrystal.cpp @@ -22,7 +22,7 @@ cEnderCrystal::cEnderCrystal(Vector3d a_Pos): void cEnderCrystal::SpawnOn(cClientHandle & a_ClientHandle) { - a_ClientHandle.SendSpawnObject(*this, 51, 0); + a_ClientHandle.SendSpawnEntity(*this); } diff --git a/src/Entities/FallingBlock.cpp b/src/Entities/FallingBlock.cpp index ed0661dae..dd3ba59cc 100644 --- a/src/Entities/FallingBlock.cpp +++ b/src/Entities/FallingBlock.cpp @@ -26,7 +26,7 @@ cFallingBlock::cFallingBlock(Vector3d a_Position, BLOCKTYPE a_BlockType, NIBBLET void cFallingBlock::SpawnOn(cClientHandle & a_ClientHandle) { - a_ClientHandle.SendSpawnFallingBlock(*this); + a_ClientHandle.SendSpawnEntity(*this); } diff --git a/src/Entities/Floater.cpp b/src/Entities/Floater.cpp index 3982a1ca5..bd1e7a637 100644 --- a/src/Entities/Floater.cpp +++ b/src/Entities/Floater.cpp @@ -92,7 +92,7 @@ cFloater::cFloater(Vector3d a_Pos, Vector3d a_Speed, UInt32 a_PlayerID, int a_Co void cFloater::SpawnOn(cClientHandle & a_Client) { - a_Client.SendSpawnObject(*this, 90, static_cast(m_PlayerID)); + a_Client.SendSpawnEntity(*this); } @@ -107,7 +107,7 @@ void cFloater::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) if (IsBlockWater(m_World->GetBlock(POSX_TOINT, POSY_TOINT, POSZ_TOINT)) && (m_World->GetBlockMeta(POSX_TOINT, POSY_TOINT, POSZ_TOINT) == 0)) { - if ((!m_CanPickupItem) && (m_AttachedMobID == cEntity::INVALID_ID)) // Check if you can't already pickup a fish and if the floater isn't attached to a mob. + if (!m_CanPickupItem && (m_AttachedMobID == cEntity::INVALID_ID)) // Check if you can't already pickup a fish and if the floater isn't attached to a mob. { if (m_CountDownTime <= 0) { diff --git a/src/Entities/ItemFrame.cpp b/src/Entities/ItemFrame.cpp index aaac0e88b..807a67b15 100644 --- a/src/Entities/ItemFrame.cpp +++ b/src/Entities/ItemFrame.cpp @@ -95,10 +95,6 @@ void cItemFrame::GetDrops(cItems & a_Items, cEntity * a_Killer) void cItemFrame::SpawnOn(cClientHandle & a_ClientHandle) { Super::SpawnOn(a_ClientHandle); - a_ClientHandle.SendSpawnObject(*this, 71, GetProtocolFacing()); + a_ClientHandle.SendSpawnEntity(*this); a_ClientHandle.SendEntityMetadata(*this); } - - - - diff --git a/src/Entities/LeashKnot.cpp b/src/Entities/LeashKnot.cpp index b11c29703..2c91c5613 100644 --- a/src/Entities/LeashKnot.cpp +++ b/src/Entities/LeashKnot.cpp @@ -107,7 +107,7 @@ void cLeashKnot::GetDrops(cItems & a_Items, cEntity * a_Killer) void cLeashKnot::SpawnOn(cClientHandle & a_ClientHandle) { Super::SpawnOn(a_ClientHandle); - a_ClientHandle.SendSpawnObject(*this, 77, GetProtocolFacing()); + a_ClientHandle.SendSpawnEntity(*this); a_ClientHandle.SendEntityMetadata(*this); } diff --git a/src/Entities/Minecart.cpp b/src/Entities/Minecart.cpp index 35bbdf617..8b93dc28c 100644 --- a/src/Entities/Minecart.cpp +++ b/src/Entities/Minecart.cpp @@ -116,7 +116,7 @@ cMinecart::cMinecart(ePayload a_Payload, Vector3d a_Pos): void cMinecart::SpawnOn(cClientHandle & a_ClientHandle) { - a_ClientHandle.SendSpawnVehicle(*this, 10, static_cast(m_Payload)); // 10 = Minecarts + a_ClientHandle.SendSpawnEntity(*this); a_ClientHandle.SendEntityMetadata(*this); } diff --git a/src/Entities/Pickup.cpp b/src/Entities/Pickup.cpp index 5c8d58f21..785d29ce9 100644 --- a/src/Entities/Pickup.cpp +++ b/src/Entities/Pickup.cpp @@ -118,7 +118,8 @@ cPickup::cPickup(Vector3d a_Pos, const cItem & a_Item, bool IsPlayerCreated, Vec void cPickup::SpawnOn(cClientHandle & a_Client) { - a_Client.SendPickupSpawn(*this); + a_Client.SendSpawnEntity(*this); + a_Client.SendEntityMetadata(*this); } diff --git a/src/Entities/ProjectileEntity.cpp b/src/Entities/ProjectileEntity.cpp index 75ac850e6..c38fa0180 100644 --- a/src/Entities/ProjectileEntity.cpp +++ b/src/Entities/ProjectileEntity.cpp @@ -283,7 +283,6 @@ std::unique_ptr cProjectileEntity::Create( return cpp14::make_unique(a_Creator, a_Pos, *a_Item); } - case pkFishingFloat: break; } LOGWARNING("%s: Unknown projectile kind: %d", __FUNCTION__, a_Kind); @@ -347,7 +346,6 @@ AString cProjectileEntity::GetMCAClassName(void) const case pkSplashPotion: return "SplashPotion"; case pkWitherSkull: return "WitherSkull"; case pkFirework: return "Firework"; - case pkFishingFloat: return ""; // Unknown, perhaps MC doesn't save this? } UNREACHABLE("Unsupported projectile kind"); } @@ -443,8 +441,7 @@ void cProjectileEntity::HandlePhysics(std::chrono::milliseconds a_Dt, cChunk & a void cProjectileEntity::SpawnOn(cClientHandle & a_Client) { - // Default spawning - use the projectile kind to spawn an object: - a_Client.SendSpawnObject(*this, m_ProjectileKind, 12); + a_Client.SendSpawnEntity(*this); a_Client.SendEntityMetadata(*this); } diff --git a/src/Entities/ProjectileEntity.h b/src/Entities/ProjectileEntity.h index 439b10118..ddd09f831 100644 --- a/src/Entities/ProjectileEntity.h +++ b/src/Entities/ProjectileEntity.h @@ -29,20 +29,19 @@ class cProjectileEntity : public: - /** The kind of the projectile. The numbers correspond to the network type ID used for spawning them in the protocol. */ + /** The kind of the projectile. */ enum eKind { - pkArrow = 60, - pkSnowball = 61, - pkEgg = 62, - pkGhastFireball = 63, - pkFireCharge = 64, - pkEnderPearl = 65, - pkExpBottle = 75, - pkSplashPotion = 73, - pkFirework = 76, - pkWitherSkull = 66, - pkFishingFloat = 90, + pkArrow, + pkSnowball, + pkEgg, + pkGhastFireball, + pkFireCharge, + pkEnderPearl, + pkExpBottle, + pkSplashPotion, + pkFirework, + pkWitherSkull, } ; // tolua_end @@ -93,7 +92,7 @@ public: /** Returns the unique ID of the entity who created this projectile May return an ID <0 */ - UInt32 GetCreatorUniqueID(void) { return m_CreatorData.m_UniqueID; } + UInt32 GetCreatorUniqueID(void) const { return m_CreatorData.m_UniqueID; } /** Returns the name of the player that created the projectile Will be empty for non-player creators @@ -142,6 +141,6 @@ protected: // cEntity overrides: virtual void Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override; virtual void HandlePhysics(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override; - virtual void SpawnOn(cClientHandle & a_Client) override; + virtual void SpawnOn(cClientHandle & a_Client) final override; } ; // tolua_export diff --git a/src/Entities/SplashPotionEntity.cpp b/src/Entities/SplashPotionEntity.cpp index 8ed6eb763..35d79e6cd 100644 --- a/src/Entities/SplashPotionEntity.cpp +++ b/src/Entities/SplashPotionEntity.cpp @@ -2,7 +2,6 @@ #include "SplashPotionEntity.h" #include "Pawn.h" -#include "../ClientHandle.h" #include "../EffectID.h" @@ -89,17 +88,3 @@ void cSplashPotionEntity::Splash(Vector3d a_HitPos) m_PotionColor ); } - - - - - -void cSplashPotionEntity::SpawnOn(cClientHandle & a_Client) -{ - a_Client.SendSpawnObject(*this, 73, m_PotionColor); - a_Client.SendEntityMetadata(*this); -} - - - - diff --git a/src/Entities/SplashPotionEntity.h b/src/Entities/SplashPotionEntity.h index 8427f34b3..1a51de1a7 100644 --- a/src/Entities/SplashPotionEntity.h +++ b/src/Entities/SplashPotionEntity.h @@ -84,8 +84,6 @@ protected: @param a_HitPos The position where the potion will splash */ void Splash(Vector3d a_HitPos); - virtual void SpawnOn(cClientHandle & a_Client) override; - private: /** Time in ticks to wait for the hit animation to begin before destroying */ int m_DestroyTimer; diff --git a/src/Entities/TNTEntity.cpp b/src/Entities/TNTEntity.cpp index 33c49b097..aaf3261b4 100644 --- a/src/Entities/TNTEntity.cpp +++ b/src/Entities/TNTEntity.cpp @@ -22,8 +22,8 @@ cTNTEntity::cTNTEntity(Vector3d a_Pos, int a_FuseTicks) : void cTNTEntity::SpawnOn(cClientHandle & a_ClientHandle) { - a_ClientHandle.SendSpawnObject(*this, 50, 1); // 50 means TNT - m_bDirtyOrientation = false; + a_ClientHandle.SendSpawnEntity(*this); + m_bDirtyOrientation = false; // TODO: why? m_bDirtyHead = false; } diff --git a/src/Items/ItemItemFrame.h b/src/Items/ItemItemFrame.h index bcc325701..2c191a003 100644 --- a/src/Items/ItemItemFrame.h +++ b/src/Items/ItemItemFrame.h @@ -41,7 +41,7 @@ public: } // Make sure block that will be occupied by the item frame is free now: - auto PlacePos = AddFaceDirection(a_ClickedBlockPos, a_ClickedBlockFace); + const auto PlacePos = AddFaceDirection(a_ClickedBlockPos, a_ClickedBlockFace); BLOCKTYPE Block = a_World->GetBlock(PlacePos); if (Block != E_BLOCK_AIR) { @@ -49,7 +49,7 @@ public: } // Place the item frame: - auto ItemFrame = cpp14::make_unique(a_ClickedBlockFace, a_ClickedBlockPos); + auto ItemFrame = cpp14::make_unique(a_ClickedBlockFace, PlacePos); auto ItemFramePtr = ItemFrame.get(); if (!ItemFramePtr->Initialize(std::move(ItemFrame), *a_World)) { diff --git a/src/Protocol/Protocol.h b/src/Protocol/Protocol.h index eb7b3cc9a..fc1a1d9d3 100644 --- a/src/Protocol/Protocol.h +++ b/src/Protocol/Protocol.h @@ -185,7 +185,6 @@ public: virtual void SendLoginSuccess (void) = 0; virtual void SendMapData (const cMap & a_Map, int a_DataStartX, int a_DataStartY) = 0; virtual void SendPaintingSpawn (const cPainting & a_Painting) = 0; - virtual void SendPickupSpawn (const cPickup & a_Pickup) = 0; virtual void SendPlayerAbilities (void) = 0; virtual void SendEntityAnimation (const cEntity & a_Entity, char a_Animation) = 0; virtual void SendParticleEffect (const AString & a_SoundName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmount) = 0; @@ -215,10 +214,8 @@ public: virtual void SendSetRawTitle (const AString & a_Title) = 0; virtual void SendSoundEffect (const AString & a_SoundName, double a_X, double a_Y, double a_Z, float a_Volume, float a_Pitch) = 0; virtual void SendSoundParticleEffect (const EffectID a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data) = 0; - virtual void SendSpawnFallingBlock (const cFallingBlock & a_FallingBlock) = 0; + virtual void SendSpawnEntity (const cEntity & a_Entity) = 0; virtual void SendSpawnMob (const cMonster & a_Mob) = 0; - virtual void SendSpawnObject (const cEntity & a_Entity, char a_ObjectType, int a_ObjectData) = 0; - virtual void SendSpawnVehicle (const cEntity & a_Vehicle, char a_VehicleType, char a_VehicleSubType) = 0; virtual void SendStatistics (const cStatManager & a_Manager) = 0; virtual void SendTabCompletionResults (const AStringVector & a_Results) = 0; virtual void SendTeleportEntity (const cEntity & a_Entity) = 0; @@ -259,9 +256,6 @@ protected: /** Returns the protocol-specific packet ID given the protocol-agnostic packet enum. */ virtual UInt32 GetPacketID(ePacketType a_Packet) = 0; - /** Converts eMonsterType to protocol-specific mob types */ - virtual UInt32 GetProtocolMobType(eMonsterType a_MobType) = 0; - /** A generic data-sending routine, all outgoing packet data needs to be routed through this so that descendants may override it. */ virtual void SendData(const char * a_Data, size_t a_Size) = 0; diff --git a/src/Protocol/ProtocolRecognizer.cpp b/src/Protocol/ProtocolRecognizer.cpp index ee6d61cea..d5f40b19b 100644 --- a/src/Protocol/ProtocolRecognizer.cpp +++ b/src/Protocol/ProtocolRecognizer.cpp @@ -550,16 +550,6 @@ void cProtocolRecognizer::SendPaintingSpawn(const cPainting & a_Painting) -void cProtocolRecognizer::SendPickupSpawn(const cPickup & a_Pickup) -{ - ASSERT(m_Protocol != nullptr); - m_Protocol->SendPickupSpawn(a_Pickup); -} - - - - - void cProtocolRecognizer::SendPlayerAbilities(void) { ASSERT(m_Protocol != nullptr); @@ -830,10 +820,10 @@ void cProtocolRecognizer::SendSoundParticleEffect(const EffectID a_EffectID, int -void cProtocolRecognizer::SendSpawnFallingBlock(const cFallingBlock & a_FallingBlock) +void cProtocolRecognizer::SendSpawnEntity(const cEntity & a_Entity) { ASSERT(m_Protocol != nullptr); - m_Protocol->SendSpawnFallingBlock(a_FallingBlock); + m_Protocol->SendSpawnEntity(a_Entity); } @@ -850,26 +840,6 @@ void cProtocolRecognizer::SendSpawnMob(const cMonster & a_Mob) -void cProtocolRecognizer::SendSpawnObject(const cEntity & a_Entity, char a_ObjectType, int a_ObjectData) -{ - ASSERT(m_Protocol != nullptr); - m_Protocol->SendSpawnObject(a_Entity, a_ObjectType, a_ObjectData); -} - - - - - -void cProtocolRecognizer::SendSpawnVehicle(const cEntity & a_Vehicle, char a_VehicleType, char a_VehicleSubType) -{ - ASSERT(m_Protocol != nullptr); - m_Protocol->SendSpawnVehicle(a_Vehicle, a_VehicleType, a_VehicleSubType); -} - - - - - void cProtocolRecognizer::SendStatistics(const cStatManager & a_Manager) { ASSERT(m_Protocol != nullptr); @@ -1020,15 +990,6 @@ AString cProtocolRecognizer::GetAuthServerID(void) -UInt32 cProtocolRecognizer::GetProtocolMobType(eMonsterType a_MobType) -{ - return 0; -} - - - - - void cProtocolRecognizer::SendData(const char * a_Data, size_t a_Size) { // This is used only when handling the server ping diff --git a/src/Protocol/ProtocolRecognizer.h b/src/Protocol/ProtocolRecognizer.h index 9caa891a4..a658a95d9 100644 --- a/src/Protocol/ProtocolRecognizer.h +++ b/src/Protocol/ProtocolRecognizer.h @@ -89,7 +89,6 @@ public: virtual void SendParticleEffect (const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmount) override; virtual void SendParticleEffect (const AString & a_ParticleName, Vector3f a_Src, Vector3f a_Offset, float a_ParticleData, int a_ParticleAmount, std::array a_Data) override; virtual void SendPaintingSpawn (const cPainting & a_Painting) override; - virtual void SendPickupSpawn (const cPickup & a_Pickup) override; virtual void SendPlayerAbilities (void) override; virtual void SendEntityAnimation (const cEntity & a_Entity, char a_Animation) override; virtual void SendPlayerListAddPlayer (const cPlayer & a_Player) override; @@ -117,10 +116,8 @@ public: virtual void SendSetRawTitle (const AString & a_Title) override; virtual void SendSoundEffect (const AString & a_SoundName, double a_X, double a_Y, double a_Z, float a_Volume, float a_Pitch) override; virtual void SendSoundParticleEffect (const EffectID a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data) override; - virtual void SendSpawnFallingBlock (const cFallingBlock & a_FallingBlock) override; + virtual void SendSpawnEntity (const cEntity & a_Entity) override; virtual void SendSpawnMob (const cMonster & a_Mob) override; - virtual void SendSpawnObject (const cEntity & a_Entity, char a_ObjectType, int a_ObjectData) override; - virtual void SendSpawnVehicle (const cEntity & a_Vehicle, char a_VehicleType, char a_VehicleSubType) override; virtual void SendStatistics (const cStatManager & a_Manager) override; virtual void SendTabCompletionResults (const AStringVector & a_Results) override; virtual void SendTeleportEntity (const cEntity & a_Entity) override; @@ -156,9 +153,6 @@ protected: /** Returns the protocol-specific packet ID given the protocol-agnostic packet enum. */ virtual UInt32 GetPacketID(ePacketType a_PacketType) override; - /** Converts eMonsterType to protocol-specific mob types */ - virtual UInt32 GetProtocolMobType(eMonsterType a_MobType) override; - // Packet handlers while in status state (m_InPingForUnrecognizedVersion == true) void HandlePacketStatusRequest(); void HandlePacketStatusPing(); diff --git a/src/Protocol/Protocol_1_11.cpp b/src/Protocol/Protocol_1_11.cpp index 7ce4db539..3ccb76d39 100644 --- a/src/Protocol/Protocol_1_11.cpp +++ b/src/Protocol/Protocol_1_11.cpp @@ -544,7 +544,7 @@ UInt32 cProtocol_1_11_0::GetProtocolMobType(eMonsterType a_MobType) switch (a_MobType) { // Map invalid type to Giant for easy debugging (if this ever spawns, something has gone very wrong) - case mtInvalidType: return 52; + case mtInvalidType: return 53; case mtBat: return 65; case mtBlaze: return 61; case mtCaveSpider: return 59; diff --git a/src/Protocol/Protocol_1_8.cpp b/src/Protocol/Protocol_1_8.cpp index d402a41ec..a2ea4eceb 100644 --- a/src/Protocol/Protocol_1_8.cpp +++ b/src/Protocol/Protocol_1_8.cpp @@ -31,6 +31,7 @@ Implements the 1.8 protocol classes: #include "../Entities/ExpOrb.h" #include "../Entities/Minecart.h" #include "../Entities/FallingBlock.h" +#include "../Entities/Floater.h" #include "../Entities/Painting.h" #include "../Entities/Pickup.h" #include "../Entities/Player.h" @@ -852,28 +853,6 @@ void cProtocol_1_8_0::SendMapData(const cMap & a_Map, int a_DataStartX, int a_Da -void cProtocol_1_8_0::SendPickupSpawn(const cPickup & a_Pickup) -{ - ASSERT(m_State == 3); // In game mode? - - { - cPacketizer Pkt(*this, pktSpawnObject); - Pkt.WriteVarInt32(a_Pickup.GetUniqueID()); - Pkt.WriteBEUInt8(2); // Type = Pickup - Pkt.WriteFPInt(a_Pickup.GetPosX()); - Pkt.WriteFPInt(a_Pickup.GetPosY()); - Pkt.WriteFPInt(a_Pickup.GetPosZ()); - Pkt.WriteByteAngle(a_Pickup.GetYaw()); - Pkt.WriteByteAngle(a_Pickup.GetPitch()); - Pkt.WriteBEInt32(0); // No object data - } - SendEntityMetadata(a_Pickup); -} - - - - - void cProtocol_1_8_0::SendPlayerAbilities(void) { ASSERT(m_State == 3); // In game mode? @@ -1370,23 +1349,45 @@ void cProtocol_1_8_0::SendSoundParticleEffect(const EffectID a_EffectID, int a_S -void cProtocol_1_8_0::SendSpawnFallingBlock(const cFallingBlock & a_FallingBlock) +void cProtocol_1_8_0::SendSpawnEntity(const cEntity & a_Entity) { - ASSERT(m_State == 3); // In game mode? + Int32 EntityData = /* Default: velocity present flag */ 1; + const auto EntityType = GetProtocolEntityType(a_Entity); + + if (a_Entity.IsMinecart()) + { + const auto & Cart = static_cast(a_Entity); + EntityData = static_cast(Cart.GetPayload()); + } + else if (a_Entity.IsItemFrame()) + { + const auto & Frame = static_cast(a_Entity); + EntityData = static_cast(Frame.GetProtocolFacing()); + } + else if (a_Entity.IsFallingBlock()) + { + const auto & Block = static_cast(a_Entity); + EntityData = Block.GetBlockType() | (static_cast(Block.GetBlockMeta()) << 12); + } + else if (a_Entity.IsFloater()) + { + const auto & Floater = static_cast(a_Entity); + EntityData = static_cast(Floater.GetOwnerID()); + } + else if (a_Entity.IsProjectile()) + { + using PType = cProjectileEntity::eKind; + const auto & Projectile = static_cast(a_Entity); + + if (Projectile.GetProjectileKind() == PType::pkArrow) + { + const auto & Arrow = static_cast(Projectile); + EntityData = static_cast(Arrow.GetCreatorUniqueID() + 1); + } + } cPacketizer Pkt(*this, pktSpawnObject); - Pkt.WriteVarInt32(a_FallingBlock.GetUniqueID()); - Pkt.WriteBEUInt8(70); // Falling block - Vector3d LastSentPos = a_FallingBlock.GetLastSentPos(); - Pkt.WriteFPInt(LastSentPos.x); - Pkt.WriteFPInt(LastSentPos.y); - Pkt.WriteFPInt(LastSentPos.z); - Pkt.WriteByteAngle(a_FallingBlock.GetYaw()); - Pkt.WriteByteAngle(a_FallingBlock.GetPitch()); - Pkt.WriteBEInt32(static_cast(a_FallingBlock.GetBlockType()) | (static_cast(a_FallingBlock.GetBlockMeta()) << 12)); - Pkt.WriteBEInt16(static_cast(a_FallingBlock.GetSpeedX() * 400)); - Pkt.WriteBEInt16(static_cast(a_FallingBlock.GetSpeedY() * 400)); - Pkt.WriteBEInt16(static_cast(a_FallingBlock.GetSpeedZ() * 400)); + WriteEntitySpawn(Pkt, a_Entity, EntityType, EntityData); } @@ -1418,64 +1419,6 @@ void cProtocol_1_8_0::SendSpawnMob(const cMonster & a_Mob) -void cProtocol_1_8_0::SendSpawnObject(const cEntity & a_Entity, char a_ObjectType, int a_ObjectData) -{ - ASSERT(m_State == 3); // In game mode? - double PosX = a_Entity.GetPosX(); - double PosZ = a_Entity.GetPosZ(); - double Yaw = a_Entity.GetYaw(); - if (a_ObjectType == 71) - { - FixItemFramePositions(a_ObjectData, PosX, PosZ, Yaw); - } - - cPacketizer Pkt(*this, pktSpawnObject); - Pkt.WriteVarInt32(a_Entity.GetUniqueID()); - Pkt.WriteBEUInt8(static_cast(a_ObjectType)); - Pkt.WriteFPInt(PosX); - Pkt.WriteFPInt(a_Entity.GetPosY()); - Pkt.WriteFPInt(PosZ); - Pkt.WriteByteAngle(a_Entity.GetPitch()); - Pkt.WriteByteAngle(Yaw); - Pkt.WriteBEInt32(a_ObjectData); - if (a_ObjectData != 0) - { - Pkt.WriteBEInt16(static_cast(a_Entity.GetSpeedX() * 400)); - Pkt.WriteBEInt16(static_cast(a_Entity.GetSpeedY() * 400)); - Pkt.WriteBEInt16(static_cast(a_Entity.GetSpeedZ() * 400)); - } -} - - - - - -void cProtocol_1_8_0::SendSpawnVehicle(const cEntity & a_Vehicle, char a_VehicleType, char a_VehicleSubType) -{ - ASSERT(m_State == 3); // In game mode? - - cPacketizer Pkt(*this, pktSpawnObject); - Pkt.WriteVarInt32(a_Vehicle.GetUniqueID()); - Pkt.WriteBEUInt8(static_cast(a_VehicleType)); - Vector3d LastSentPos = a_Vehicle.GetLastSentPos(); - Pkt.WriteFPInt(LastSentPos.x); - Pkt.WriteFPInt(LastSentPos.y); - Pkt.WriteFPInt(LastSentPos.z); - Pkt.WriteByteAngle(a_Vehicle.GetPitch()); - Pkt.WriteByteAngle(a_Vehicle.GetYaw()); - Pkt.WriteBEInt32(a_VehicleSubType); - if (a_VehicleSubType != 0) - { - Pkt.WriteBEInt16(static_cast(a_Vehicle.GetSpeedX() * 400)); - Pkt.WriteBEInt16(static_cast(a_Vehicle.GetSpeedY() * 400)); - Pkt.WriteBEInt16(static_cast(a_Vehicle.GetSpeedZ() * 400)); - } -} - - - - - void cProtocol_1_8_0::SendStatistics(const cStatManager & a_Manager) { ASSERT(m_State == 3); // In game mode? @@ -1808,70 +1751,70 @@ bool cProtocol_1_8_0::CompressPacket(const AString & a_Packet, AString & a_Compr int cProtocol_1_8_0::GetParticleID(const AString & a_ParticleName) { - static std::map ParticleMap; - if (ParticleMap.empty()) + static const std::unordered_map ParticleMap { // Initialize the ParticleMap: - ParticleMap["explode"] = 0; - ParticleMap["largeexplode"] = 1; - ParticleMap["hugeexplosion"] = 2; - ParticleMap["fireworksspark"] = 3; - ParticleMap["bubble"] = 4; - ParticleMap["splash"] = 5; - ParticleMap["wake"] = 6; - ParticleMap["suspended"] = 7; - ParticleMap["depthsuspend"] = 8; - ParticleMap["crit"] = 9; - ParticleMap["magiccrit"] = 10; - ParticleMap["smoke"] = 11; - ParticleMap["largesmoke"] = 12; - ParticleMap["spell"] = 13; - ParticleMap["instantspell"] = 14; - ParticleMap["mobspell"] = 15; - ParticleMap["mobspellambient"] = 16; - ParticleMap["witchmagic"] = 17; - ParticleMap["dripwater"] = 18; - ParticleMap["driplava"] = 19; - ParticleMap["angryvillager"] = 20; - ParticleMap["happyvillager"] = 21; - ParticleMap["townaura"] = 22; - ParticleMap["note"] = 23; - ParticleMap["portal"] = 24; - ParticleMap["enchantmenttable"] = 25; - ParticleMap["flame"] = 26; - ParticleMap["lava"] = 27; - ParticleMap["footstep"] = 28; - ParticleMap["cloud"] = 29; - ParticleMap["reddust"] = 30; - ParticleMap["snowballpoof"] = 31; - ParticleMap["snowshovel"] = 32; - ParticleMap["slime"] = 33; - ParticleMap["heart"] = 34; - ParticleMap["barrier"] = 35; - ParticleMap["iconcrack"] = 36; - ParticleMap["blockcrack"] = 37; - ParticleMap["blockdust"] = 38; - ParticleMap["droplet"] = 39; - ParticleMap["take"] = 40; - ParticleMap["mobappearance"] = 41; - ParticleMap["dragonbreath"] = 42; - ParticleMap["endrod"] = 43; - ParticleMap["damageindicator"] = 44; - ParticleMap["sweepattack"] = 45; - ParticleMap["fallingdust"] = 46; - ParticleMap["totem"] = 47; - ParticleMap["spit"] = 48; - } + { "explode", 0 }, + { "largeexplode", 1 }, + { "hugeexplosion", 2 }, + { "fireworksspark", 3 }, + { "bubble", 4 }, + { "splash", 5 }, + { "wake", 6 }, + { "suspended", 7 }, + { "depthsuspend", 8 }, + { "crit", 9 }, + { "magiccrit", 10 }, + { "smoke", 11 }, + { "largesmoke", 12 }, + { "spell", 13 }, + { "instantspell", 14 }, + { "mobspell", 15 }, + { "mobspellambient", 16 }, + { "witchmagic", 17 }, + { "dripwater", 18 }, + { "driplava", 19 }, + { "angryvillager", 20 }, + { "happyvillager", 21 }, + { "townaura", 22 }, + { "note", 23 }, + { "portal", 24 }, + { "enchantmenttable", 25 }, + { "flame", 26 }, + { "lava", 27 }, + { "footstep", 28 }, + { "cloud", 29 }, + { "reddust", 30 }, + { "snowballpoof", 31 }, + { "snowshovel", 32 }, + { "slime", 33 }, + { "heart", 34 }, + { "barrier", 35 }, + { "iconcrack", 36 }, + { "blockcrack", 37 }, + { "blockdust", 38 }, + { "droplet", 39 }, + { "take", 40 }, + { "mobappearance", 41 }, + { "dragonbreath", 42 }, + { "endrod", 43 }, + { "damageindicator", 44 }, + { "sweepattack", 45 }, + { "fallingdust", 46 }, + { "totem", 47 }, + { "spit", 48 } + }; - AString ParticleName = StrToLower(a_ParticleName); - if (ParticleMap.find(ParticleName) == ParticleMap.end()) + const auto ParticleName = StrToLower(a_ParticleName); + const auto FindResult = ParticleMap.find(ParticleName); + if (FindResult == ParticleMap.end()) { LOGWARNING("Unknown particle: %s", a_ParticleName.c_str()); ASSERT(!"Unknown particle"); return 0; } - return ParticleMap[ParticleName]; + return FindResult->second; } @@ -1883,7 +1826,7 @@ UInt32 cProtocol_1_8_0::GetProtocolMobType(eMonsterType a_MobType) switch (a_MobType) { // Map invalid type to Giant for easy debugging (if this ever spawns, something has gone very wrong) - case mtInvalidType: return 52; + case mtInvalidType: return 53; case mtBat: return 65; case mtBlaze: return 61; case mtCaveSpider: return 59; @@ -1925,41 +1868,6 @@ UInt32 cProtocol_1_8_0::GetProtocolMobType(eMonsterType a_MobType) -void cProtocol_1_8_0::FixItemFramePositions(int a_ObjectData, double & a_PosX, double & a_PosZ, double & a_Yaw) -{ - switch (a_ObjectData) - { - case 0: - { - a_PosZ += 1; - a_Yaw = 0; - break; - } - case 1: - { - a_PosX -= 1; - a_Yaw = 90; - break; - } - case 2: - { - a_PosZ -= 1; - a_Yaw = 180; - break; - } - case 3: - { - a_PosX += 1; - a_Yaw = 270; - break; - } - } -} - - - - - void cProtocol_1_8_0::AddReceivedData(const char * a_Data, size_t a_Size) { // Write the incoming data into the comm log file: @@ -3918,3 +3826,76 @@ void cProtocol_1_8_0::WriteEntityProperties(cPacketizer & a_Pkt, const cEntity & a_Pkt.WriteBEInt32(0); // NumProperties } + + + + + +void cProtocol_1_8_0::WriteEntitySpawn(cPacketizer & a_Pkt, const cEntity & a_Entity, const UInt8 a_ObjectType, const Int32 a_ObjectData) +{ + ASSERT(m_State == 3); // In game mode? + + a_Pkt.WriteVarInt32(a_Entity.GetUniqueID()); + a_Pkt.WriteBEUInt8(a_ObjectType); + a_Pkt.WriteFPInt(a_Entity.GetPosX()); + a_Pkt.WriteFPInt(a_Entity.GetPosY()); + a_Pkt.WriteFPInt(a_Entity.GetPosY()); + a_Pkt.WriteByteAngle(a_Entity.GetPitch()); + a_Pkt.WriteByteAngle(a_Entity.GetYaw()); + a_Pkt.WriteBEInt32(a_ObjectData); + + if (a_ObjectData != 0) + { + a_Pkt.WriteBEInt16(static_cast(a_Entity.GetSpeedX() * 400)); + a_Pkt.WriteBEInt16(static_cast(a_Entity.GetSpeedY() * 400)); + a_Pkt.WriteBEInt16(static_cast(a_Entity.GetSpeedZ() * 400)); + } +} + + + + + +UInt8 cProtocol_1_8_0::GetProtocolEntityType(const cEntity & a_Entity) +{ + using Type = cEntity::eEntityType; + + switch (a_Entity.GetEntityType()) + { + case Type::etEnderCrystal: return 51; + case Type::etPickup: return 2; + case Type::etFallingBlock: return 70; + case Type::etMinecart: return 10; + case Type::etBoat: return 1; + case Type::etTNT: return 50; + case Type::etProjectile: + { + using PType = cProjectileEntity::eKind; + const auto & Projectile = static_cast(a_Entity); + + switch (Projectile.GetProjectileKind()) + { + case PType::pkArrow: return 60; + case PType::pkSnowball: return 61; + case PType::pkEgg: return 62; + case PType::pkGhastFireball: return 63; + case PType::pkFireCharge: return 64; + case PType::pkEnderPearl: return 65; + case PType::pkExpBottle: return 75; + case PType::pkSplashPotion: return 73; + case PType::pkFirework: return 76; + case PType::pkWitherSkull: return 66; + } + } + case Type::etFloater: return 90; + case Type::etItemFrame: return 71; + case Type::etLeashKnot: return 77; + + // Non-objects must not be sent + case Type::etEntity: + case Type::etPlayer: + case Type::etMonster: + case Type::etExpOrb: + case Type::etPainting: UNREACHABLE("Tried to spawn an unhandled entity"); + } +} diff --git a/src/Protocol/Protocol_1_8.h b/src/Protocol/Protocol_1_8.h index 7934b7038..69ac1449a 100644 --- a/src/Protocol/Protocol_1_8.h +++ b/src/Protocol/Protocol_1_8.h @@ -76,7 +76,6 @@ public: virtual void SendLoginSuccess (void) override; virtual void SendMapData (const cMap & a_Map, int a_DataStartX, int a_DataStartY) override; virtual void SendPaintingSpawn (const cPainting & a_Painting) override; - virtual void SendPickupSpawn (const cPickup & a_Pickup) override; virtual void SendPlayerAbilities (void) override; virtual void SendEntityAnimation (const cEntity & a_Entity, char a_Animation) override; virtual void SendParticleEffect (const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmount) override; @@ -104,10 +103,8 @@ public: virtual void SendSetTitle (const cCompositeChat & a_Title) override; virtual void SendSetRawTitle (const AString & a_Title) override; virtual void SendSoundParticleEffect (const EffectID a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data) override; - virtual void SendSpawnFallingBlock (const cFallingBlock & a_FallingBlock) override; + virtual void SendSpawnEntity (const cEntity & a_Entity) override; virtual void SendSpawnMob (const cMonster & a_Mob) override; - virtual void SendSpawnObject (const cEntity & a_Entity, char a_ObjectType, int a_ObjectData) override; - virtual void SendSpawnVehicle (const cEntity & a_Vehicle, char a_VehicleType, char a_VehicleSubType) override; virtual void SendStatistics (const cStatManager & a_Manager) override; virtual void SendTabCompletionResults (const AStringVector & a_Results) override; virtual void SendTeleportEntity (const cEntity & a_Entity) override; @@ -135,9 +132,6 @@ public: /** The 1.8 protocol use a particle id instead of a string. This function converts the name to the id. If the name is incorrect, it returns 0. */ static int GetParticleID(const AString & a_ParticleName); - /** Minecraft 1.8 use other locations to spawn the item frame. This function converts the 1.7 positions to 1.8 positions. */ - static void FixItemFramePositions(int a_ObjectData, double & a_PosX, double & a_PosZ, double & a_Yaw); - protected: AString m_ServerAddress; @@ -167,7 +161,7 @@ protected: virtual UInt32 GetPacketID(ePacketType a_Packet) override; /** Converts eMonsterType to protocol-specific mob types */ - virtual UInt32 GetProtocolMobType(eMonsterType a_MobType) override; + virtual UInt32 GetProtocolMobType(eMonsterType a_MobType); /** Reads and handles the packet. The packet length and type have already been read. Returns true if the packet was understood, false if it was an unknown packet @@ -246,6 +240,15 @@ protected: /** Writes the entity properties for the specified entity, including the Count field. */ virtual void WriteEntityProperties(cPacketizer & a_Pkt, const cEntity & a_Entity); + /** Writes the entity type and entity-dependent data into a packet structure required for the entity to initially spawn. */ + virtual void WriteEntitySpawn(cPacketizer & a_Pkt, const cEntity & a_Entity, const UInt8 a_ObjectType, const Int32 a_ObjectData); + /** Writes the block entity data for the specified block entity into the packet. */ virtual void WriteBlockEntity(cPacketizer & a_Pkt, const cBlockEntity & a_BlockEntity); + +private: + + /** Converts an entity to a protocol-specific entity type. + Only entities that the Send Spawn Entity packet supports are valid inputs to this method */ + UInt8 GetProtocolEntityType(const cEntity & a_Entity); } ; diff --git a/src/Protocol/Protocol_1_9.cpp b/src/Protocol/Protocol_1_9.cpp index 91bc43d03..10aed8cc1 100644 --- a/src/Protocol/Protocol_1_9.cpp +++ b/src/Protocol/Protocol_1_9.cpp @@ -329,35 +329,6 @@ void cProtocol_1_9_0::SendMapData(const cMap & a_Map, int a_DataStartX, int a_Da -void cProtocol_1_9_0::SendPickupSpawn(const cPickup & a_Pickup) -{ - ASSERT(m_State == 3); // In game mode? - - { // TODO Use SendSpawnObject - cPacketizer Pkt(*this, pktSpawnObject); - Pkt.WriteVarInt32(a_Pickup.GetUniqueID()); - // TODO: Bad way to write a UUID, and it's not a true UUID, but this is functional for now. - Pkt.WriteBEUInt64(0); - Pkt.WriteBEUInt64(a_Pickup.GetUniqueID()); - Pkt.WriteBEUInt8(2); // Type = Pickup - Pkt.WriteBEDouble(a_Pickup.GetPosX()); - Pkt.WriteBEDouble(a_Pickup.GetPosY()); - Pkt.WriteBEDouble(a_Pickup.GetPosZ()); - Pkt.WriteByteAngle(a_Pickup.GetYaw()); - Pkt.WriteByteAngle(a_Pickup.GetPitch()); - Pkt.WriteBEInt32(0); // No object data - Pkt.WriteBEInt16(0); // No velocity - Pkt.WriteBEInt16(0); - Pkt.WriteBEInt16(0); - } - - SendEntityMetadata(a_Pickup); -} - - - - - void cProtocol_1_9_0::SendPlayerMaxSpeed(void) { ASSERT(m_State == 3); // In game mode? @@ -447,32 +418,6 @@ void cProtocol_1_9_0::SendSoundEffect(const AString & a_SoundName, double a_X, d -void cProtocol_1_9_0::SendSpawnFallingBlock(const cFallingBlock & a_FallingBlock) -{ - ASSERT(m_State == 3); // In game mode? - - cPacketizer Pkt(*this, pktSpawnObject); - Pkt.WriteVarInt32(a_FallingBlock.GetUniqueID()); - // TODO: Bad way to write a UUID, and it's not a true UUID, but this is functional for now. - Pkt.WriteBEUInt64(0); - Pkt.WriteBEUInt64(a_FallingBlock.GetUniqueID()); - Pkt.WriteBEUInt8(70); // Falling block - Vector3d LastSentPos = a_FallingBlock.GetLastSentPos(); - Pkt.WriteBEDouble(LastSentPos.x); - Pkt.WriteBEDouble(LastSentPos.y); - Pkt.WriteBEDouble(LastSentPos.z); - Pkt.WriteByteAngle(a_FallingBlock.GetYaw()); - Pkt.WriteByteAngle(a_FallingBlock.GetPitch()); - Pkt.WriteBEInt32(static_cast(a_FallingBlock.GetBlockType()) | (static_cast(a_FallingBlock.GetBlockMeta()) << 12)); - Pkt.WriteBEInt16(static_cast(a_FallingBlock.GetSpeedX() * 400)); - Pkt.WriteBEInt16(static_cast(a_FallingBlock.GetSpeedY() * 400)); - Pkt.WriteBEInt16(static_cast(a_FallingBlock.GetSpeedZ() * 400)); -} - - - - - void cProtocol_1_9_0::SendSpawnMob(const cMonster & a_Mob) { ASSERT(m_State == 3); // In game mode? @@ -501,64 +446,6 @@ void cProtocol_1_9_0::SendSpawnMob(const cMonster & a_Mob) -void cProtocol_1_9_0::SendSpawnObject(const cEntity & a_Entity, char a_ObjectType, int a_ObjectData) -{ - ASSERT(m_State == 3); // In game mode? - double PosX = a_Entity.GetPosX(); - double PosZ = a_Entity.GetPosZ(); - double Yaw = a_Entity.GetYaw(); - if (a_ObjectType == 71) - { - FixItemFramePositions(a_ObjectData, PosX, PosZ, Yaw); - } - - cPacketizer Pkt(*this, pktSpawnObject); - Pkt.WriteVarInt32(a_Entity.GetUniqueID()); - // TODO: Bad way to write a UUID, and it's not a true UUID, but this is functional for now. - Pkt.WriteBEUInt64(0); - Pkt.WriteBEUInt64(a_Entity.GetUniqueID()); - Pkt.WriteBEUInt8(static_cast(a_ObjectType)); - Pkt.WriteBEDouble(PosX); - Pkt.WriteBEDouble(a_Entity.GetPosY()); - Pkt.WriteBEDouble(PosZ); - Pkt.WriteByteAngle(a_Entity.GetPitch()); - Pkt.WriteByteAngle(Yaw); - Pkt.WriteBEInt32(a_ObjectData); - Pkt.WriteBEInt16(static_cast(a_Entity.GetSpeedX() * 400)); - Pkt.WriteBEInt16(static_cast(a_Entity.GetSpeedY() * 400)); - Pkt.WriteBEInt16(static_cast(a_Entity.GetSpeedZ() * 400)); -} - - - - - -void cProtocol_1_9_0::SendSpawnVehicle(const cEntity & a_Vehicle, char a_VehicleType, char a_VehicleSubType) -{ - ASSERT(m_State == 3); // In game mode? - - cPacketizer Pkt(*this, pktSpawnObject); - Pkt.WriteVarInt32(a_Vehicle.GetUniqueID()); - // TODO: Bad way to write a UUID, and it's not a true UUID, but this is functional for now. - Pkt.WriteBEUInt64(0); - Pkt.WriteBEUInt64(a_Vehicle.GetUniqueID()); - Pkt.WriteBEUInt8(static_cast(a_VehicleType)); - Vector3d LastSentPos = a_Vehicle.GetLastSentPos(); - Pkt.WriteBEDouble(LastSentPos.x); - Pkt.WriteBEDouble(LastSentPos.y); - Pkt.WriteBEDouble(LastSentPos.z); - Pkt.WriteByteAngle(a_Vehicle.GetPitch()); - Pkt.WriteByteAngle(a_Vehicle.GetYaw()); - Pkt.WriteBEInt32(a_VehicleSubType); - Pkt.WriteBEInt16(static_cast(a_Vehicle.GetSpeedX() * 400)); - Pkt.WriteBEInt16(static_cast(a_Vehicle.GetSpeedY() * 400)); - Pkt.WriteBEInt16(static_cast(a_Vehicle.GetSpeedZ() * 400)); -} - - - - - void cProtocol_1_9_0::SendTeleportEntity(const cEntity & a_Entity) { ASSERT(m_State == 3); // In game mode? @@ -2286,6 +2173,32 @@ void cProtocol_1_9_0::WriteEntityProperties(cPacketizer & a_Pkt, const cEntity & +void cProtocol_1_9_0::WriteEntitySpawn(cPacketizer & a_Pkt, const cEntity & a_Entity, const UInt8 a_ObjectType, const Int32 a_ObjectData) +{ + ASSERT(m_State == 3); // In game mode? + + a_Pkt.WriteVarInt32(a_Entity.GetUniqueID()); + + // TODO: Bad way to write a UUID, and it's not a true UUID, but this is functional for now. + a_Pkt.WriteBEUInt64(0); + a_Pkt.WriteBEUInt64(a_Entity.GetUniqueID()); + + a_Pkt.WriteBEUInt8(a_ObjectType); + a_Pkt.WriteBEDouble(a_Entity.GetPosX()); + a_Pkt.WriteBEDouble(a_Entity.GetPosY()); + a_Pkt.WriteBEDouble(a_Entity.GetPosZ()); + a_Pkt.WriteByteAngle(a_Entity.GetPitch()); + a_Pkt.WriteByteAngle(a_Entity.GetYaw()); + a_Pkt.WriteBEInt32(a_ObjectData); + a_Pkt.WriteBEInt16(static_cast(a_Entity.GetSpeedX() * 400)); + a_Pkt.WriteBEInt16(static_cast(a_Entity.GetSpeedY() * 400)); + a_Pkt.WriteBEInt16(static_cast(a_Entity.GetSpeedZ() * 400)); +} + + + + + //////////////////////////////////////////////////////////////////////////////// // cProtocol_1_9_1: diff --git a/src/Protocol/Protocol_1_9.h b/src/Protocol/Protocol_1_9.h index d5b5d1f5a..b4e945c1e 100644 --- a/src/Protocol/Protocol_1_9.h +++ b/src/Protocol/Protocol_1_9.h @@ -54,15 +54,11 @@ public: virtual void SendLeashEntity (const cEntity & a_Entity, const cEntity & a_EntityLeashedTo) override; virtual void SendMapData (const cMap & a_Map, int a_DataStartX, int a_DataStartY) override; virtual void SendPaintingSpawn (const cPainting & a_Painting) override; - virtual void SendPickupSpawn (const cPickup & a_Pickup) override; virtual void SendPlayerMaxSpeed (void) override; virtual void SendPlayerMoveLook (void) override; virtual void SendPlayerSpawn (const cPlayer & a_Player) override; virtual void SendSoundEffect (const AString & a_SoundName, double a_X, double a_Y, double a_Z, float a_Volume, float a_Pitch) override; - virtual void SendSpawnFallingBlock (const cFallingBlock & a_FallingBlock) override; virtual void SendSpawnMob (const cMonster & a_Mob) override; - virtual void SendSpawnObject (const cEntity & a_Entity, char a_ObjectType, int a_ObjectData) override; - virtual void SendSpawnVehicle (const cEntity & a_Vehicle, char a_VehicleType, char a_VehicleSubType) override; virtual void SendTeleportEntity (const cEntity & a_Entity) override; virtual void SendThunderbolt (int a_BlockX, int a_BlockY, int a_BlockZ) override; virtual void SendUnleashEntity (const cEntity & a_Entity) override; @@ -127,6 +123,9 @@ protected: /** Writes the entity properties for the specified entity, including the Count field. */ virtual void WriteEntityProperties(cPacketizer & a_Pkt, const cEntity & a_Entity) override; + /** Writes the entity type and entity-dependent data into a packet structure required for the entity to initially spawn. */ + virtual void WriteEntitySpawn(cPacketizer & a_Pkt, const cEntity & a_Entity, const UInt8 a_ObjectType, const Int32 a_ObjectData) override; + /** Writes the block entity data for the specified block entity into the packet. */ virtual void WriteBlockEntity(cPacketizer & a_Pkt, const cBlockEntity & a_BlockEntity) override;