From 054a89dd9e5d6819adede9d7ba781b69f98ff2f4 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Wed, 6 Jan 2021 00:35:42 +0000 Subject: Clarify cClientHandle, cPlayer ownership semantics + A cPlayer, once created, has a strong pointer to the cClientHandle. The player ticks the clienthandle. If he finds the handle destroyed, he destroys himself in turn. Nothing else can kill the player. * The client handle has a pointer to the player. Once a player is created, the client handle never outlasts the player, nor does it manage the player's lifetime. The pointer is always safe to use after FinishAuthenticate, which is also the point where cProtocol is put into the Game state that allows player manipulation. + Entities are once again never lost by constructing a chunk when they try to move into one that doesn't exist. * Fixed a forgotten Super invocation in cPlayer::OnRemoveFromWorld. * Fix SaveToDisk usage in destructor by only saving things cPlayer owns, instead of accessing cWorld. --- src/Protocol/ChunkDataSerializer.cpp | 4 ++-- src/Protocol/ChunkDataSerializer.h | 4 ++-- src/Protocol/Protocol_1_8.cpp | 17 ++++++----------- 3 files changed, 10 insertions(+), 15 deletions(-) (limited to 'src/Protocol') diff --git a/src/Protocol/ChunkDataSerializer.cpp b/src/Protocol/ChunkDataSerializer.cpp index a16cce02b..2c45eea58 100644 --- a/src/Protocol/ChunkDataSerializer.cpp +++ b/src/Protocol/ChunkDataSerializer.cpp @@ -74,7 +74,7 @@ cChunkDataSerializer::cChunkDataSerializer(const eDimension a_Dimension) : void cChunkDataSerializer::SendToClients(const int a_ChunkX, const int a_ChunkZ, const cChunkData & a_Data, const unsigned char * a_BiomeData, const ClientHandles & a_SendTo) { - for (const auto Client : a_SendTo) + for (const auto & Client : a_SendTo) { switch (static_cast(Client->GetProtocolVersion())) { @@ -133,7 +133,7 @@ void cChunkDataSerializer::SendToClients(const int a_ChunkX, const int a_ChunkZ, -inline void cChunkDataSerializer::Serialize(cClientHandle * a_Client, const int a_ChunkX, const int a_ChunkZ, const cChunkData & a_Data, const unsigned char * a_BiomeData, const CacheVersion a_CacheVersion) +inline void cChunkDataSerializer::Serialize(const ClientHandles::value_type & a_Client, const int a_ChunkX, const int a_ChunkZ, const cChunkData & a_Data, const unsigned char * a_BiomeData, const CacheVersion a_CacheVersion) { auto & Cache = m_Cache[static_cast(a_CacheVersion)]; if (Cache.Engaged) diff --git a/src/Protocol/ChunkDataSerializer.h b/src/Protocol/ChunkDataSerializer.h index ea0b0be11..47d92e2ee 100644 --- a/src/Protocol/ChunkDataSerializer.h +++ b/src/Protocol/ChunkDataSerializer.h @@ -21,7 +21,7 @@ Caches the serialized data for as long as this object lives, so that the same da other clients using the same protocol. */ class cChunkDataSerializer { - using ClientHandles = std::unordered_set; + using ClientHandles = std::vector>; /** Enum to collapse protocol versions into a contiguous index. */ enum class CacheVersion @@ -55,7 +55,7 @@ private: /** Serialises the given chunk, storing the result into the given cache entry, and sends the data. If the cache entry is already present, simply re-uses it. */ - inline void Serialize(cClientHandle * a_Client, int a_ChunkX, int a_ChunkZ, const cChunkData & a_Data, const unsigned char * a_BiomeData, CacheVersion a_CacheVersion); + inline void Serialize(const ClientHandles::value_type & a_Client, int a_ChunkX, int a_ChunkZ, const cChunkData & a_Data, const unsigned char * a_BiomeData, CacheVersion a_CacheVersion); inline void Serialize47 (int a_ChunkX, int a_ChunkZ, const cChunkData & a_Data, const unsigned char * a_BiomeData); // Release 1.8 inline void Serialize107(int a_ChunkX, int a_ChunkZ, const cChunkData & a_Data, const unsigned char * a_BiomeData); // Release 1.9 diff --git a/src/Protocol/Protocol_1_8.cpp b/src/Protocol/Protocol_1_8.cpp index 12e2d441c..be855678e 100644 --- a/src/Protocol/Protocol_1_8.cpp +++ b/src/Protocol/Protocol_1_8.cpp @@ -670,8 +670,7 @@ void cProtocol_1_8_0::SendHeldItemChange(int a_ItemIndex) ASSERT((a_ItemIndex >= 0) && (a_ItemIndex <= 8)); // Valid check cPacketizer Pkt(*this, pktHeldItemChange); - cPlayer * Player = m_Client->GetPlayer(); - Pkt.WriteBEInt8(static_cast(Player->GetInventory().GetEquippedSlotNum())); + Pkt.WriteBEInt8(static_cast(a_ItemIndex)); } @@ -1021,15 +1020,11 @@ void cProtocol_1_8_0::SendPlayerListUpdatePing(const cPlayer & a_Player) { ASSERT(m_State == 3); // In game mode? - auto ClientHandle = a_Player.GetClientHandlePtr(); - if (ClientHandle != nullptr) - { - cPacketizer Pkt(*this, pktPlayerList); - Pkt.WriteVarInt32(2); - Pkt.WriteVarInt32(1); - Pkt.WriteUUID(a_Player.GetUUID()); - Pkt.WriteVarInt32(static_cast(ClientHandle->GetPing())); - } + cPacketizer Pkt(*this, pktPlayerList); + Pkt.WriteVarInt32(2); + Pkt.WriteVarInt32(1); + Pkt.WriteUUID(a_Player.GetUUID()); + Pkt.WriteVarInt32(static_cast(a_Player.GetClientHandle()->GetPing())); } -- cgit v1.2.3