1
0

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.
This commit is contained in:
Tiger Wang
2021-01-06 00:35:42 +00:00
parent 9328afe65c
commit 054a89dd9e
21 changed files with 505 additions and 1126 deletions

View File

@@ -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<Int8>(Player->GetInventory().GetEquippedSlotNum()));
Pkt.WriteBEInt8(static_cast<Int8>(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<UInt32>(ClientHandle->GetPing()));
}
cPacketizer Pkt(*this, pktPlayerList);
Pkt.WriteVarInt32(2);
Pkt.WriteVarInt32(1);
Pkt.WriteUUID(a_Player.GetUUID());
Pkt.WriteVarInt32(static_cast<UInt32>(a_Player.GetClientHandle()->GetPing()));
}