@@ -745,6 +745,7 @@ void BotManagerImpl::handleRead (std::size_t const count_) noexcept
745745 // move end pointer
746746 m_inEndOffset += static_cast <unsigned > (count_);
747747
748+ bool partial = false ;
748749 assert (m_inEndOffset >= m_inStartOffset);
749750 while (m_inEndOffset - m_inStartOffset >= 4 ) [[likely]] // need to read complete header
750751 {
@@ -771,14 +772,49 @@ void BotManagerImpl::handleRead (std::size_t const count_) noexcept
771772 }
772773
773774 // partial message
775+ partial = true ;
774776 break ;
775777 }
776778
777- handleMessage (std::move (message));
779+ auto const type = message.type ();
780+ if (type == MessageType::BallPrediction || type == MessageType::GamePacket)
781+ {
782+ std::erase_if (
783+ m_inputQueue, [type] (auto const &message_) { return message_.type () == type; });
784+ }
785+
786+ m_inputQueue.emplace_back (std::move (message));
778787
779788 m_inStartOffset += size;
780789 }
781790
791+ if (!partial)
792+ {
793+ // process all messages
794+ for (auto &message : m_inputQueue)
795+ handleMessage (std::move (message));
796+ m_inputQueue.clear ();
797+ }
798+ else
799+ {
800+ // process messages until first ball pred or game packet
801+ auto it = std::begin (m_inputQueue);
802+ while (it != std::end (m_inputQueue))
803+ {
804+ auto const &message = *it;
805+ if (message.type () == MessageType::BallPrediction ||
806+ message.type () == MessageType::GamePacket)
807+ {
808+ break ;
809+ }
810+
811+ handleMessage (std::move (message));
812+ ++it;
813+ }
814+
815+ m_inputQueue.erase (std::begin (m_inputQueue), it);
816+ }
817+
782818 if (m_inStartOffset == m_inEndOffset) [[likely]]
783819 {
784820 // complete packet read so start next read on a new buffer to avoid partial reads
0 commit comments