From 1135b6742f50de20fb4fee241b40ae0d034b1d75 Mon Sep 17 00:00:00 2001 From: "madmaxoft@gmail.com" Date: Thu, 6 Sep 2012 08:33:43 +0000 Subject: ClientHandle: added an overflow buffer for outgoing data, it fixes the "bad packet id" problem with 1.3.2. git-svn-id: http://mc-server.googlecode.com/svn/trunk@837 0a769ca7-a7f5-676a-18bf-c427514a06d6 --- source/cClientHandle.cpp | 37 ++++++++++++++++++++++++++++++++----- source/cClientHandle.h | 1 + 2 files changed, 33 insertions(+), 5 deletions(-) (limited to 'source') diff --git a/source/cClientHandle.cpp b/source/cClientHandle.cpp index c62be45ac..98ca7e92e 100644 --- a/source/cClientHandle.cpp +++ b/source/cClientHandle.cpp @@ -939,13 +939,38 @@ void cClientHandle::SendData(const char * a_Data, int a_Size) { { cCSLock Lock(m_CSOutgoingData); - if (!m_OutgoingData.Write(a_Data, a_Size)) + + // _X 2012_09_06: We need an overflow buffer, usually when streaming the initial chunks + if (m_OutgoingDataOverflow.empty()) + { + // No queued overflow data; if this packet fits into the ringbuffer, put it in, otherwise put it in the overflow buffer: + int CanFit = m_OutgoingData.GetFreeSpace(); + if (CanFit > a_Size) + { + CanFit = a_Size; + } + if (CanFit > 0) + { + m_OutgoingData.Write(a_Data, CanFit); + } + if (a_Size > CanFit) + { + m_OutgoingDataOverflow.append(a_Data + CanFit, a_Size - CanFit); + } + } + else { - // Client has too much outgoing data queued, drop them silently by timing them out: - // (So that they're dropped in the tick thread and not the sender thread) - m_LastPingTime = 0; + // There is a queued overflow. Append to it, then send as much from its front as possible + m_OutgoingDataOverflow.append(a_Data, a_Size); + int CanFit = m_OutgoingData.GetFreeSpace(); + if (CanFit > 128) + { + // No point in moving the data over if it's not large enough - too much effort for too little an effect + m_OutgoingData.Write(m_OutgoingDataOverflow.data(), CanFit); + m_OutgoingDataOverflow.erase(0, CanFit); + } } - } + } // Lock(m_CSOutgoingData) // Notify SocketThreads that we have something to write: cRoot::Get()->GetServer()->NotifyClientWrite(this); @@ -1567,6 +1592,8 @@ void cClientHandle::GetOutgoingData(AString & a_Data) cCSLock Lock(m_CSOutgoingData); m_OutgoingData.ReadAll(a_Data); m_OutgoingData.CommitRead(); + a_Data.append(m_OutgoingDataOverflow); + m_OutgoingDataOverflow.clear(); } // Disconnect player after all packets have been sent diff --git a/source/cClientHandle.h b/source/cClientHandle.h index f5028b0aa..cd0cbeae3 100644 --- a/source/cClientHandle.h +++ b/source/cClientHandle.h @@ -189,6 +189,7 @@ private: cCriticalSection m_CSOutgoingData; cByteBuffer m_OutgoingData; + AString m_OutgoingDataOverflow; //< For data that didn't fit into the m_OutgoingData ringbuffer temporarily cCriticalSection m_CriticalSection; -- cgit v1.2.3