Fixed rev368's ChunkSender, now sends properly even chunks that are loaded. Fixed a deadlock in cClientHandle vs TickThread over cClientHandle::m_CSChunkLists
git-svn-id: http://mc-server.googlecode.com/svn/trunk@371 0a769ca7-a7f5-676a-18bf-c427514a06d6
This commit is contained in:
+91
-22
@@ -62,12 +62,44 @@ void cChunkSender::ChunkReady(int a_ChunkX, int a_ChunkY, int a_ChunkZ)
|
||||
|
||||
|
||||
|
||||
void cChunkSender::QueueSendChunkTo(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cClientHandle * a_Client)
|
||||
{
|
||||
ASSERT(a_Client != NULL);
|
||||
{
|
||||
cCSLock Lock(m_CS);
|
||||
m_SendChunks.push_back(sSendChunk(a_ChunkX, a_ChunkY, a_ChunkZ, a_Client));
|
||||
}
|
||||
m_Event.Set();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cChunkSender::RemoveClient(cClientHandle * a_Client)
|
||||
{
|
||||
cCSLock Lock(m_CS);
|
||||
for (sSendChunkList::iterator itr = m_SendChunks.begin(); itr != m_SendChunks.end();)
|
||||
{
|
||||
if (itr->m_Client == a_Client)
|
||||
{
|
||||
itr = m_SendChunks.erase(itr);
|
||||
continue;
|
||||
}
|
||||
++itr;
|
||||
} // for itr - m_SendChunks[]
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cChunkSender::Execute(void)
|
||||
{
|
||||
while (!mShouldTerminate)
|
||||
{
|
||||
cCSLock Lock(m_CS);
|
||||
while (m_ChunksReady.empty())
|
||||
while (m_ChunksReady.empty() && m_SendChunks.empty())
|
||||
{
|
||||
cCSUnlock Unlock(Lock);
|
||||
m_Event.Wait();
|
||||
@@ -77,28 +109,24 @@ void cChunkSender::Execute(void)
|
||||
}
|
||||
} // while (empty)
|
||||
|
||||
// Take one from the queue:
|
||||
cChunkCoords Coords(m_ChunksReady.front());
|
||||
m_ChunksReady.pop_front();
|
||||
Lock.Unlock();
|
||||
|
||||
ASSERT(m_World != NULL);
|
||||
|
||||
// Send it to anyone waiting:
|
||||
m_World->GetChunkData(Coords.m_ChunkX, Coords.m_ChunkY, Coords.m_ChunkZ, this);
|
||||
cPacket_PreChunk PreChunk(Coords.m_ChunkX, Coords.m_ChunkZ, true);
|
||||
cPacket_MapChunk MapChunk(Coords.m_ChunkX, Coords.m_ChunkY, Coords.m_ChunkZ, m_BlockData);
|
||||
m_World->BroadcastToChunk(Coords.m_ChunkX, Coords.m_ChunkY, Coords.m_ChunkZ, PreChunk);
|
||||
m_World->BroadcastToChunk(Coords.m_ChunkX, Coords.m_ChunkY, Coords.m_ChunkZ, MapChunk);
|
||||
|
||||
// Send entity creation packets:
|
||||
for (PacketList::iterator itr = m_Packets.begin(); itr != m_Packets.end(); ++itr)
|
||||
if (!m_ChunksReady.empty())
|
||||
{
|
||||
m_World->BroadcastToChunk(Coords.m_ChunkX, Coords.m_ChunkY, Coords.m_ChunkZ, **itr);
|
||||
delete *itr;
|
||||
} // for itr - m_Packets
|
||||
m_Packets.clear();
|
||||
|
||||
// Take one from the queue:
|
||||
cChunkCoords Coords(m_ChunksReady.front());
|
||||
m_ChunksReady.pop_front();
|
||||
Lock.Unlock();
|
||||
|
||||
SendChunk(Coords.m_ChunkX, Coords.m_ChunkY, Coords.m_ChunkZ, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Take one from the queue:
|
||||
sSendChunk Chunk(m_SendChunks.front());
|
||||
m_SendChunks.pop_front();
|
||||
Lock.Unlock();
|
||||
|
||||
SendChunk(Chunk.m_ChunkX, Chunk.m_ChunkY, Chunk.m_ChunkZ, Chunk.m_Client);
|
||||
}
|
||||
} // while (!mShouldTerminate)
|
||||
}
|
||||
|
||||
@@ -106,6 +134,47 @@ void cChunkSender::Execute(void)
|
||||
|
||||
|
||||
|
||||
void cChunkSender::SendChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cClientHandle * a_Client)
|
||||
{
|
||||
ASSERT(m_World != NULL);
|
||||
|
||||
// Prepare MapChunk packets:
|
||||
m_World->GetChunkData(a_ChunkX, a_ChunkY, a_ChunkZ, this);
|
||||
cPacket_PreChunk PreChunk(a_ChunkX, a_ChunkZ, true);
|
||||
cPacket_MapChunk MapChunk(a_ChunkX, a_ChunkY, a_ChunkZ, m_BlockData);
|
||||
|
||||
// Send:
|
||||
if (a_Client == NULL)
|
||||
{
|
||||
m_World->BroadcastToChunk(a_ChunkX, a_ChunkY, a_ChunkZ, PreChunk);
|
||||
m_World->BroadcastToChunk(a_ChunkX, a_ChunkY, a_ChunkZ, MapChunk);
|
||||
}
|
||||
else
|
||||
{
|
||||
a_Client->Send(PreChunk);
|
||||
a_Client->Send(MapChunk);
|
||||
}
|
||||
|
||||
// Send entity creation packets:
|
||||
for (PacketList::iterator itr = m_Packets.begin(); itr != m_Packets.end(); ++itr)
|
||||
{
|
||||
if (a_Client == NULL)
|
||||
{
|
||||
m_World->BroadcastToChunk(a_ChunkX, a_ChunkY, a_ChunkZ, **itr);
|
||||
}
|
||||
else
|
||||
{
|
||||
a_Client->Send(**itr);
|
||||
}
|
||||
delete *itr;
|
||||
} // for itr - m_Packets[]
|
||||
m_Packets.clear();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cChunkSender::BlockData(const char * a_Data)
|
||||
{
|
||||
memcpy(m_BlockData, a_Data, cChunk::c_BlockDataSize);
|
||||
|
||||
Reference in New Issue
Block a user