Not sending chunks to the client twice

git-svn-id: http://mc-server.googlecode.com/svn/trunk@399 0a769ca7-a7f5-676a-18bf-c427514a06d6
master
madmaxoft@gmail.com 2012-03-11 10:48:20 +00:00
parent dc8004d5e6
commit af44154ff5
5 changed files with 40 additions and 24 deletions

View File

@ -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) )
{

View File

@ -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<sSendChunk> sSendChunkList;

View File

@ -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

View File

@ -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:

View File

@ -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 )