1
0

Fixed player moving between worlds.

Fixes FS #407.
Also fixes a few possible deadlocks between SocketThreads and TickThread

git-svn-id: http://mc-server.googlecode.com/svn/trunk@1641 0a769ca7-a7f5-676a-18bf-c427514a06d6
This commit is contained in:
madmaxoft@gmail.com
2013-07-03 07:47:35 +00:00
parent 2f8eebaad1
commit f7b8a301f8
5 changed files with 96 additions and 32 deletions

View File

@@ -406,6 +406,11 @@ void cClientHandle::RemoveFromAllChunks()
cCSLock Lock(m_CSChunkLists);
m_LoadedChunks.clear();
m_ChunksToSend.clear();
// Also reset the LastStreamedChunk coords to bogus coords,
// so that all chunks are streamed in subsequent StreamChunks() call (FS #407)
m_LastStreamedChunkX = 0x7fffffff;
m_LastStreamedChunkZ = 0x7fffffff;
}
}
@@ -898,18 +903,11 @@ void cClientHandle::HandlePlaceBlock(int a_BlockX, int a_BlockY, int a_BlockZ, c
void cClientHandle::HandleChat(const AString & a_Message)
{
AString Message(a_Message);
if (!cRoot::Get()->GetServer()->Command(*this, Message))
{
AString Msg;
Printf(Msg, "<%s%s%s> %s",
m_Player->GetColor().c_str(),
m_Player->GetName().c_str(),
cChatColor::White.c_str(),
Message.c_str()
);
m_Player->GetWorld()->BroadcastChat(Msg);
}
// We need to process messages in the Tick thread, to avoid deadlocks resulting from player-commands being processed
// in the SocketThread and waiting for acquiring the ChunkMap CS with Plugin CS locked
cCSLock Lock(m_CSMessages);
m_PendingMessages.push_back(a_Message);
}
@@ -1292,8 +1290,8 @@ void cClientHandle::Tick(float a_Dt)
m_ShouldCheckDownloaded = false;
}
// Send a ping packet:
cTimer t1;
// Send ping packet
if (
(m_Player != NULL) && // Is logged in?
(m_LastPingTime + cClientHandle::PING_TIME_MS <= t1.GetNowTime())
@@ -1324,6 +1322,9 @@ void cClientHandle::Tick(float a_Dt)
m_CurrentExplosionTick = (m_CurrentExplosionTick + 1) % ARRAYCOUNT(m_NumExplosionsPerTick);
m_RunningSumExplosions -= m_NumExplosionsPerTick[m_CurrentExplosionTick];
m_NumExplosionsPerTick[m_CurrentExplosionTick] = 0;
// Process the queued messages:
ProcessPendingMessages();
}
@@ -1944,6 +1945,46 @@ void cClientHandle::AddWantedChunk(int a_ChunkX, int a_ChunkZ)
void cClientHandle::ProcessPendingMessages(void)
{
while (true)
{
AString Message;
// Extract one message from the PendingMessages buffer:
{
cCSLock Lock(m_CSMessages);
if (m_PendingMessages.empty())
{
// No more messages in the buffer, bail out
return;
}
Message = m_PendingMessages.front();
m_PendingMessages.pop_front();
} // Lock(m_CSMessages)
// If a command, perform it:
if (cRoot::Get()->GetServer()->Command(*this, Message))
{
continue;
}
// Not a command, broadcast as a simple message:
AString Msg;
Printf(Msg, "<%s%s%s> %s",
m_Player->GetColor().c_str(),
m_Player->GetName().c_str(),
cChatColor::White.c_str(),
Message.c_str()
);
m_Player->GetWorld()->BroadcastChat(Msg);
} // while (true)
}
void cClientHandle::PacketBufferFull(void)
{
// Too much data in the incoming queue, the server is probably too busy, kick the client: