diff options
author | Tiger Wang <ziwei.tiger@outlook.com> | 2020-04-20 21:46:04 +0200 |
---|---|---|
committer | Tiger Wang <ziwei.tiger@outlook.com> | 2020-05-01 00:04:56 +0200 |
commit | 0b9b7bc1a8d5cf6f92b802dc376a189ef066e62d (patch) | |
tree | afe3041898d51e53ca693861564792e0d828774e /src/Protocol | |
parent | NBT: Dynamic list-max-count protection. (#4697) (diff) | |
download | cuberite-0b9b7bc1a8d5cf6f92b802dc376a189ef066e62d.tar cuberite-0b9b7bc1a8d5cf6f92b802dc376a189ef066e62d.tar.gz cuberite-0b9b7bc1a8d5cf6f92b802dc376a189ef066e62d.tar.bz2 cuberite-0b9b7bc1a8d5cf6f92b802dc376a189ef066e62d.tar.lz cuberite-0b9b7bc1a8d5cf6f92b802dc376a189ef066e62d.tar.xz cuberite-0b9b7bc1a8d5cf6f92b802dc376a189ef066e62d.tar.zst cuberite-0b9b7bc1a8d5cf6f92b802dc376a189ef066e62d.zip |
Diffstat (limited to '')
-rw-r--r-- | src/Protocol/Protocol.h | 8 | ||||
-rw-r--r-- | src/Protocol/ProtocolRecognizer.cpp | 43 | ||||
-rw-r--r-- | src/Protocol/ProtocolRecognizer.h | 8 | ||||
-rw-r--r-- | src/Protocol/Protocol_1_11.cpp | 2 | ||||
-rw-r--r-- | src/Protocol/Protocol_1_8.cpp | 353 | ||||
-rw-r--r-- | src/Protocol/Protocol_1_8.h | 19 | ||||
-rw-r--r-- | src/Protocol/Protocol_1_9.cpp | 139 | ||||
-rw-r--r-- | src/Protocol/Protocol_1_9.h | 7 |
8 files changed, 212 insertions, 367 deletions
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<int, 2> 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<const cMinecart &>(a_Entity); + EntityData = static_cast<Int32>(Cart.GetPayload()); + } + else if (a_Entity.IsItemFrame()) + { + const auto & Frame = static_cast<const cItemFrame &>(a_Entity); + EntityData = static_cast<Int32>(Frame.GetProtocolFacing()); + } + else if (a_Entity.IsFallingBlock()) + { + const auto & Block = static_cast<const cFallingBlock &>(a_Entity); + EntityData = Block.GetBlockType() | (static_cast<Int32>(Block.GetBlockMeta()) << 12); + } + else if (a_Entity.IsFloater()) + { + const auto & Floater = static_cast<const cFloater &>(a_Entity); + EntityData = static_cast<Int32>(Floater.GetOwnerID()); + } + else if (a_Entity.IsProjectile()) + { + using PType = cProjectileEntity::eKind; + const auto & Projectile = static_cast<const cProjectileEntity &>(a_Entity); + + if (Projectile.GetProjectileKind() == PType::pkArrow) + { + const auto & Arrow = static_cast<const cArrowEntity &>(Projectile); + EntityData = static_cast<Int32>(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<Int32>(a_FallingBlock.GetBlockType()) | (static_cast<Int32>(a_FallingBlock.GetBlockMeta()) << 12)); - Pkt.WriteBEInt16(static_cast<Int16>(a_FallingBlock.GetSpeedX() * 400)); - Pkt.WriteBEInt16(static_cast<Int16>(a_FallingBlock.GetSpeedY() * 400)); - Pkt.WriteBEInt16(static_cast<Int16>(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<UInt8>(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<Int16>(a_Entity.GetSpeedX() * 400)); - Pkt.WriteBEInt16(static_cast<Int16>(a_Entity.GetSpeedY() * 400)); - Pkt.WriteBEInt16(static_cast<Int16>(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<UInt8>(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<Int16>(a_Vehicle.GetSpeedX() * 400)); - Pkt.WriteBEInt16(static_cast<Int16>(a_Vehicle.GetSpeedY() * 400)); - Pkt.WriteBEInt16(static_cast<Int16>(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<AString, int> ParticleMap; - if (ParticleMap.empty()) + static const std::unordered_map<AString, int> 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; - } - - AString ParticleName = StrToLower(a_ParticleName); - if (ParticleMap.find(ParticleName) == ParticleMap.end()) + { "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 } + }; + + 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<Int16>(a_Entity.GetSpeedX() * 400)); + a_Pkt.WriteBEInt16(static_cast<Int16>(a_Entity.GetSpeedY() * 400)); + a_Pkt.WriteBEInt16(static_cast<Int16>(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<const cProjectileEntity &>(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<Int32>(a_FallingBlock.GetBlockType()) | (static_cast<Int32>(a_FallingBlock.GetBlockMeta()) << 12)); - Pkt.WriteBEInt16(static_cast<Int16>(a_FallingBlock.GetSpeedX() * 400)); - Pkt.WriteBEInt16(static_cast<Int16>(a_FallingBlock.GetSpeedY() * 400)); - Pkt.WriteBEInt16(static_cast<Int16>(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<UInt8>(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<Int16>(a_Entity.GetSpeedX() * 400)); - Pkt.WriteBEInt16(static_cast<Int16>(a_Entity.GetSpeedY() * 400)); - Pkt.WriteBEInt16(static_cast<Int16>(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<UInt8>(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<Int16>(a_Vehicle.GetSpeedX() * 400)); - Pkt.WriteBEInt16(static_cast<Int16>(a_Vehicle.GetSpeedY() * 400)); - Pkt.WriteBEInt16(static_cast<Int16>(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<Int16>(a_Entity.GetSpeedX() * 400)); + a_Pkt.WriteBEInt16(static_cast<Int16>(a_Entity.GetSpeedY() * 400)); + a_Pkt.WriteBEInt16(static_cast<Int16>(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; |