diff --git a/source/ChunkSender.cpp b/source/ChunkSender.cpp index ed650e1f8..cb4340f25 100644 --- a/source/ChunkSender.cpp +++ b/source/ChunkSender.cpp @@ -67,6 +67,8 @@ void cChunkSender::QueueSendChunkTo(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cC ASSERT(a_Client != NULL); { cCSLock Lock(m_CS); + // It should not be already queued: + ASSERT(std::find(m_SendChunks.begin(), m_SendChunks.end(), sSendChunk(a_ChunkX, a_ChunkY, a_ChunkZ, a_Client)) == m_SendChunks.end()); m_SendChunks.push_back(sSendChunk(a_ChunkX, a_ChunkY, a_ChunkZ, a_Client)); } m_evtQueue.Set(); @@ -144,6 +146,15 @@ void cChunkSender::SendChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cClientHa { ASSERT(m_World != NULL); + // Ask the client if it still wants the chunk: + if (a_Client != NULL) + { + if (!a_Client->WantsSendChunk(a_ChunkX, a_ChunkY, a_ChunkZ)) + { + return; + } + } + // Prepare MapChunk packets: if( !m_World->GetChunkData(a_ChunkX, a_ChunkY, a_ChunkZ, *this) ) { diff --git a/source/ChunkSender.h b/source/ChunkSender.h index b2ada5a09..23cce039b 100644 --- a/source/ChunkSender.h +++ b/source/ChunkSender.h @@ -77,6 +77,16 @@ protected: m_Client(a_Client) { } + + bool operator ==(const sSendChunk & a_Other) + { + return ( + (a_Other.m_ChunkX == m_ChunkX) && + (a_Other.m_ChunkY == m_ChunkY) && + (a_Other.m_ChunkZ == m_ChunkZ) && + (a_Other.m_Client == m_Client) + ); + } }; typedef std::list sSendChunkList; diff --git a/source/cClientHandle.cpp b/source/cClientHandle.cpp index c610f91a3..07be3d4a7 100644 --- a/source/cClientHandle.cpp +++ b/source/cClientHandle.cpp @@ -475,27 +475,6 @@ void cClientHandle::RemoveFromAllChunks() -void cClientHandle::ChunkJustSent(cChunk * a_ChunkCompleted) -{ - cCSLock Lock(m_CSChunkLists); - for (cChunkCoordsList::iterator itr = m_ChunksToSend.begin(); itr != m_ChunksToSend.end(); ++itr) - { - if (((*itr).m_ChunkX == a_ChunkCompleted->GetPosX()) && ((*itr).m_ChunkZ == a_ChunkCompleted->GetPosZ())) - { - m_ChunksToSend.erase(itr); - if ((m_State == csDownloadingWorld) && (m_ChunksToSend.empty())) - { - CheckIfWorldDownloaded(); - } - return; - } - } // for itr - m_ChunksToSend[] -} - - - - - void cClientHandle::HandlePacket(cPacket * a_Packet) { m_TimeLastPacket = cWorld::GetTime(); @@ -1745,6 +1724,7 @@ void cClientHandle::Send(const cPacket & a_Packet, ENUM_PRIORITY a_Priority /* = int ChunkX = ((cPacket_MapChunk &)a_Packet).m_PosX / cChunk::c_ChunkWidth; int ChunkZ = ((cPacket_MapChunk &)a_Packet).m_PosZ / cChunk::c_ChunkWidth; #endif + bool Found = false; cCSLock Lock(m_CSChunkLists); for (cChunkCoordsList::iterator itr = m_ChunksToSend.begin(); itr != m_ChunksToSend.end(); ++itr) { @@ -1752,9 +1732,14 @@ void cClientHandle::Send(const cPacket & a_Packet, ENUM_PRIORITY a_Priority /* = { m_ChunksToSend.erase(itr); CheckIfWorldDownloaded(); + Found = true; break; } } // for itr - m_ChunksToSend[] + if (!Found) + { + return; + } } // Optimize away multiple queued RelativeEntityMoveLook packets: @@ -1874,6 +1859,16 @@ void cClientHandle::SetViewDistance(int a_ViewDistance) +bool cClientHandle::WantsSendChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ) +{ + cCSLock Lock(m_CSChunkLists); + return (std::find(m_ChunksToSend.begin(), m_ChunksToSend.end(), cChunkCoords(a_ChunkX, a_ChunkY, a_ChunkZ)) != m_ChunksToSend.end()); +} + + + + + void cClientHandle::DataReceived(const char * a_Data, int a_Size) { // Data is received from the client diff --git a/source/cClientHandle.h b/source/cClientHandle.h index 2a9833de4..6e1079569 100644 --- a/source/cClientHandle.h +++ b/source/cClientHandle.h @@ -86,8 +86,6 @@ public: // Removes the client from all chunks. Used when switching worlds or destroying the player void RemoveFromAllChunks(void); - void ChunkJustSent(cChunk * a_ChunkSent); // Called by cChunk when it is loaded / generated and sent to all clients registered in it - inline bool IsLoggedIn(void) const { return m_State >= csAuthenticating; } void Tick(float a_Dt); @@ -106,6 +104,9 @@ public: void SetViewDistance(int a_ViewDistance); //tolua_export int GetUniqueID() const { return m_UniqueID; } //tolua_export + + /// Returns true if the client wants the chunk specified to be sent (in m_ChunksToSend) + bool WantsSendChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ); private: diff --git a/source/packets/cPacket_MapChunk.cpp b/source/packets/cPacket_MapChunk.cpp index 7e6ec689b..791b81425 100644 --- a/source/packets/cPacket_MapChunk.cpp +++ b/source/packets/cPacket_MapChunk.cpp @@ -168,7 +168,6 @@ cPacket_MapChunk::cPacket_MapChunk( const cPacket_MapChunk & a_Copy ) void cPacket_MapChunk::Serialize(AString & a_Data) const { - LOG("Sending chunk [%i, %i]", m_PosX, m_PosZ ); AppendByte (a_Data, m_PacketID); #if (MINECRAFT_1_2_2 == 1 )