From 1394fc8eb5c8c0ac49bb64ce1871a80470f058c3 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Tue, 6 Apr 2021 12:26:43 +0100 Subject: Streamline player abilities handling * Update player list gamemode on world change * Fix invisibility for spectators, use entity metadata * Populate m_World for cPlayers on load - Remove SendPlayerMaxSpeed, a duplicate of SendEntityProperties --- src/Protocol/Packetizer.cpp | 1 - src/Protocol/Protocol.h | 2 - src/Protocol/Protocol_1_12.cpp | 2 - src/Protocol/Protocol_1_13.cpp | 3 +- src/Protocol/Protocol_1_8.cpp | 84 ++++++++++++++++++------------------------ src/Protocol/Protocol_1_8.h | 1 - src/Protocol/Protocol_1_9.cpp | 54 --------------------------- src/Protocol/Protocol_1_9.h | 4 -- 8 files changed, 37 insertions(+), 114 deletions(-) (limited to 'src/Protocol') diff --git a/src/Protocol/Packetizer.cpp b/src/Protocol/Packetizer.cpp index e71cba086..6c5e5cd63 100644 --- a/src/Protocol/Packetizer.cpp +++ b/src/Protocol/Packetizer.cpp @@ -99,7 +99,6 @@ AString cPacketizer::PacketTypeToStr(cProtocol::ePacketType a_PacketType) case cProtocol::pktPlayerAbilities: return "pktPlayerAbilities"; case cProtocol::pktPlayerList: return "pktPlayerList"; case cProtocol::pktPlayerListHeaderFooter: return "pktPlayerListHeaderFooter"; - case cProtocol::pktPlayerMaxSpeed: return "pktPlayerMaxSpeed"; case cProtocol::pktPlayerMoveLook: return "pktPlayerMoveLook"; case cProtocol::pktPluginMessage: return "pktPluginMessage"; case cProtocol::pktRemoveEntityEffect: return "pktRemoveEntityEffect"; diff --git a/src/Protocol/Protocol.h b/src/Protocol/Protocol.h index 26a411909..0f615f4dc 100644 --- a/src/Protocol/Protocol.h +++ b/src/Protocol/Protocol.h @@ -105,7 +105,6 @@ public: pktPlayerAbilities, pktPlayerList, pktPlayerListHeaderFooter, - pktPlayerMaxSpeed, pktPlayerMoveLook, pktPluginMessage, pktRemoveEntityEffect, @@ -412,7 +411,6 @@ public: virtual void SendPlayerListUpdateGameMode (const cPlayer & a_Player) = 0; virtual void SendPlayerListUpdatePing () = 0; virtual void SendPlayerListUpdateDisplayName(const cPlayer & a_Player, const AString & a_CustomName) = 0; - virtual void SendPlayerMaxSpeed (void) = 0; ///< Informs the client of the maximum player speed (1.6.1+) virtual void SendPlayerMoveLook (void) = 0; virtual void SendPlayerPosition (void) = 0; virtual void SendPlayerSpawn (const cPlayer & a_Player) = 0; diff --git a/src/Protocol/Protocol_1_12.cpp b/src/Protocol/Protocol_1_12.cpp index 06238e408..b340d87f5 100644 --- a/src/Protocol/Protocol_1_12.cpp +++ b/src/Protocol/Protocol_1_12.cpp @@ -1003,7 +1003,6 @@ UInt32 cProtocol_1_12::GetPacketID(cProtocol::ePacketType a_Packet) case pktExperience: return 0x3f; case pktHeldItemChange: return 0x39; case pktLeashEntity: return 0x3c; - case pktPlayerMaxSpeed: return 0x4d; case pktRemoveEntityEffect: return 0x32; case pktResourcePack: return 0x33; case pktRespawn: return 0x34; @@ -1184,7 +1183,6 @@ UInt32 cProtocol_1_12_1::GetPacketID(ePacketType a_Packet) case pktPlayerList: return 0x2e; case pktPlayerListHeaderFooter: return 0x4a; case pktPlayerAbilities: return 0x2c; - case pktPlayerMaxSpeed: return 0x4e; case pktPlayerMoveLook: return 0x2f; case pktRemoveEntityEffect: return 0x33; case pktResourcePack: return 0x34; diff --git a/src/Protocol/Protocol_1_13.cpp b/src/Protocol/Protocol_1_13.cpp index b892e8433..28b6c26f9 100644 --- a/src/Protocol/Protocol_1_13.cpp +++ b/src/Protocol/Protocol_1_13.cpp @@ -372,8 +372,7 @@ UInt32 cProtocol_1_13::GetPacketID(ePacketType a_PacketType) case pktParticleEffect: return 0x24; case pktPlayerAbilities: return 0x2e; case pktPlayerList: return 0x30; - case pktPlayerListHeaderFooter: return 0x4E; - case pktPlayerMaxSpeed: return 0x52; + case pktPlayerListHeaderFooter: return 0x4e; case pktPlayerMoveLook: return 0x32; case pktPluginMessage: return 0x19; case pktRemoveEntityEffect: return 0x36; diff --git a/src/Protocol/Protocol_1_8.cpp b/src/Protocol/Protocol_1_8.cpp index 3c377ce21..179e2b2ea 100644 --- a/src/Protocol/Protocol_1_8.cpp +++ b/src/Protocol/Protocol_1_8.cpp @@ -832,9 +832,6 @@ void cProtocol_1_8_0::SendLogin(const cPlayer & a_Player, const cWorld & a_World cPacketizer Pkt(*this, pktDifficulty); Pkt.WriteBEInt8(1); } - - // Send player abilities: - SendPlayerAbilities(); } @@ -1132,35 +1129,6 @@ void cProtocol_1_8_0::SendPlayerListUpdatePing() -void cProtocol_1_8_0::SendPlayerMaxSpeed(void) -{ - ASSERT(m_State == 3); // In game mode? - - cPacketizer Pkt(*this, pktEntityProperties); - cPlayer * Player = m_Client->GetPlayer(); - Pkt.WriteVarInt32(Player->GetUniqueID()); - Pkt.WriteBEInt32(1); // Count - Pkt.WriteString("generic.movementSpeed"); - // The default game speed is 0.1, multiply that value by the relative speed: - Pkt.WriteBEDouble(0.1 * Player->GetNormalMaxSpeed()); - if (Player->IsSprinting()) - { - Pkt.WriteVarInt32(1); // Modifier count - Pkt.WriteBEUInt64(0x662a6b8dda3e4c1c); - Pkt.WriteBEUInt64(0x881396ea6097278d); // UUID of the modifier - Pkt.WriteBEDouble(Player->GetSprintingMaxSpeed() - Player->GetNormalMaxSpeed()); - Pkt.WriteBEUInt8(2); - } - else - { - Pkt.WriteVarInt32(0); // Modifier count - } -} - - - - - void cProtocol_1_8_0::SendPlayerMoveLook(void) { ASSERT(m_State == 3); // In game mode? @@ -1201,12 +1169,8 @@ void cProtocol_1_8_0::SendPlayerSpawn(const cPlayer & a_Player) Pkt.WriteFPInt(LastSentPos.z); Pkt.WriteByteAngle(a_Player.GetYaw()); Pkt.WriteByteAngle(a_Player.GetPitch()); - short ItemType = a_Player.GetEquippedItem().IsEmpty() ? 0 : a_Player.GetEquippedItem().m_ItemType; - Pkt.WriteBEInt16(ItemType); - Pkt.WriteBEUInt8((3 << 5) | 6); // Metadata: float + index 6 - Pkt.WriteBEFloat(static_cast(a_Player.GetHealth())); - Pkt.WriteBEUInt8((4 << 5 | (2 & 0x1F)) & 0xFF); - Pkt.WriteString(a_Player.GetName()); + Pkt.WriteBEInt16(a_Player.GetEquippedItem().IsEmpty() ? 0 : a_Player.GetEquippedItem().m_ItemType); + WriteEntityMetadata(Pkt, a_Player); Pkt.WriteBEUInt8(0x7f); // Metadata: end } @@ -3377,11 +3341,15 @@ void cProtocol_1_8_0::WriteEntityMetadata(cPacketizer & a_Pkt, const cEntity & a { auto & Player = static_cast(a_Entity); - // Player health (not handled since players aren't monsters) + // Player name: + a_Pkt.WriteBEUInt8(0x82); + a_Pkt.WriteString(Player.GetName()); + + // Player health: a_Pkt.WriteBEUInt8(0x66); a_Pkt.WriteBEFloat(static_cast(Player.GetHealth())); - // Skin flags + // Skin flags: a_Pkt.WriteBEUInt8(0x0A); a_Pkt.WriteBEUInt8(static_cast(Player.GetSkinParts())); @@ -3815,18 +3783,38 @@ void cProtocol_1_8_0::WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_M void cProtocol_1_8_0::WriteEntityProperties(cPacketizer & a_Pkt, const cEntity & a_Entity) { - if (!a_Entity.IsMob()) + if (a_Entity.IsPlayer()) { - // No properties for anything else than mobs - a_Pkt.WriteBEInt32(0); - return; - } + const auto & Player = static_cast(a_Entity); - // const cMonster & Mob = (const cMonster &)a_Entity; + a_Pkt.WriteBEInt32(1); // Count. + a_Pkt.WriteString("generic.movementSpeed"); + a_Pkt.WriteBEDouble(0.1 * Player.GetNormalMaxSpeed()); // The default game speed is 0.1, multiply that value by the relative speed. + + // It seems the modifiers aren't conditionally activated; their effects are applied immediately! + // We have to keep on re-sending this packet when the client notifies us of sprint start and end, and so on. Strange. + + if (Player.IsSprinting()) + { + a_Pkt.WriteVarInt32(1); // Modifier count. + a_Pkt.WriteBEUInt64(0x662a6b8dda3e4c1c); + a_Pkt.WriteBEUInt64(0x881396ea6097278d); // UUID of the modifier (sprinting speed boost). + a_Pkt.WriteBEDouble(Player.GetSprintingMaxSpeed() - Player.GetNormalMaxSpeed()); + a_Pkt.WriteBEUInt8(2); + } + else + { + a_Pkt.WriteVarInt32(0); + } + } + else + { + // const cMonster & Mob = (const cMonster &)a_Entity; - // TODO: Send properties and modifiers based on the mob type + // TODO: Send properties and modifiers based on the mob type - a_Pkt.WriteBEInt32(0); // NumProperties + a_Pkt.WriteBEInt32(0); + } } diff --git a/src/Protocol/Protocol_1_8.h b/src/Protocol/Protocol_1_8.h index 26fc6e8a8..44168e499 100644 --- a/src/Protocol/Protocol_1_8.h +++ b/src/Protocol/Protocol_1_8.h @@ -95,7 +95,6 @@ public: virtual void SendPlayerListUpdateDisplayName(const cPlayer & a_Player, const AString & a_CustomName) override; virtual void SendPlayerListUpdateGameMode (const cPlayer & a_Player) override; virtual void SendPlayerListUpdatePing () override; - virtual void SendPlayerMaxSpeed (void) override; virtual void SendPlayerMoveLook (void) override; virtual void SendPlayerPosition (void) override; virtual void SendPlayerSpawn (const cPlayer & a_Player) override; diff --git a/src/Protocol/Protocol_1_9.cpp b/src/Protocol/Protocol_1_9.cpp index 0827b8f0b..0ae451117 100644 --- a/src/Protocol/Protocol_1_9.cpp +++ b/src/Protocol/Protocol_1_9.cpp @@ -490,35 +490,6 @@ void cProtocol_1_9_0::SendMapData(const cMap & a_Map, int a_DataStartX, int a_Da -void cProtocol_1_9_0::SendPlayerMaxSpeed(void) -{ - ASSERT(m_State == 3); // In game mode? - - cPacketizer Pkt(*this, pktPlayerMaxSpeed); - cPlayer * Player = m_Client->GetPlayer(); - Pkt.WriteVarInt32(Player->GetUniqueID()); - Pkt.WriteBEInt32(1); // Count - Pkt.WriteString("generic.movementSpeed"); - // The default game speed is 0.1, multiply that value by the relative speed: - Pkt.WriteBEDouble(0.1 * Player->GetNormalMaxSpeed()); - if (Player->IsSprinting()) - { - Pkt.WriteVarInt32(1); // Modifier count - Pkt.WriteBEUInt64(0x662a6b8dda3e4c1c); - Pkt.WriteBEUInt64(0x881396ea6097278d); // UUID of the modifier - Pkt.WriteBEDouble(Player->GetSprintingMaxSpeed() - Player->GetNormalMaxSpeed()); - Pkt.WriteBEUInt8(2); - } - else - { - Pkt.WriteVarInt32(0); // Modifier count - } -} - - - - - void cProtocol_1_9_0::SendPlayerMoveLook(void) { ASSERT(m_State == 3); // In game mode? @@ -690,7 +661,6 @@ UInt32 cProtocol_1_9_0::GetPacketID(cProtocol::ePacketType a_Packet) case pktPlayerAbilities: return 0x2b; case pktPlayerList: return 0x2d; case pktPlayerListHeaderFooter: return 0x48; - case pktPlayerMaxSpeed: return 0x4b; case pktPlayerMoveLook: return 0x2e; case pktPluginMessage: return 0x18; case pktRemoveEntityEffect: return 0x31; @@ -2271,26 +2241,6 @@ void cProtocol_1_9_0::WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_M -void cProtocol_1_9_0::WriteEntityProperties(cPacketizer & a_Pkt, const cEntity & a_Entity) -{ - if (!a_Entity.IsMob()) - { - // No properties for anything else than mobs - a_Pkt.WriteBEInt32(0); - return; - } - - // const cMonster & Mob = (const cMonster &)a_Entity; - - // TODO: Send properties and modifiers based on the mob type - - a_Pkt.WriteBEInt32(0); // NumProperties -} - - - - - //////////////////////////////////////////////////////////////////////////////// // cProtocol_1_9_1: @@ -2320,9 +2270,6 @@ void cProtocol_1_9_1::SendLogin(const cPlayer & a_Player, const cWorld & a_World cPacketizer Pkt(*this, pktDifficulty); Pkt.WriteBEInt8(1); } - - // Send player abilities: - SendPlayerAbilities(); } @@ -2405,7 +2352,6 @@ UInt32 cProtocol_1_9_4::GetPacketID(cProtocol::ePacketType a_Packet) case pktCollectEntity: return 0x48; case pktEntityEffect: return 0x4b; case pktEntityProperties: return 0x4a; - case pktPlayerMaxSpeed: return 0x4a; case pktPlayerListHeaderFooter: return 0x47; case pktTeleportEntity: return 0x49; diff --git a/src/Protocol/Protocol_1_9.h b/src/Protocol/Protocol_1_9.h index be2af147c..190b20005 100644 --- a/src/Protocol/Protocol_1_9.h +++ b/src/Protocol/Protocol_1_9.h @@ -57,7 +57,6 @@ 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 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; @@ -125,9 +124,6 @@ protected: /** Writes the mob-specific metadata for the specified mob */ virtual void WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_Mob) override; - /** Writes the entity properties for the specified entity, including the Count field. */ - virtual void WriteEntityProperties(cPacketizer & a_Pkt, const cEntity & a_Entity) override; - /** Types used within metadata */ enum eMetadataType { -- cgit v1.2.3