PacketBase* NetManager::DuplicatePacket(PacketBase& pkt) { PacketBase* pPktTmp = (PacketBase*)PacketFactory::Instance().New( pkt.GetPacketID() ); if( pPktTmp == NULL ) return 0; #if PACKET_USE_INDEX_DATA bool bOri = pkt.IsUseIndex(); pkt.IsUseIndex(false); pPktTmp->IsUseIndex(false); #endif char buffer[PACKET_MAX_SIZE]; pkt.WritePacket(buffer); pPktTmp->ReadPacket(buffer); #if PACKET_USE_INDEX_DATA pkt.IsUseIndex(bOri); #endif return pPktTmp; }
bool NetChannel::FillPackets2Block(DataBufferArg& arg) { const uint32 cbHeader = sizeof(BlockHeadT); uint32 cbBuffer = CBBUFF; if( arg.cbBuffer < cbBuffer ) cbBuffer = arg.cbBuffer; if( cbBuffer > BLOCK_SIZE_MASK ) cbBuffer = BLOCK_SIZE_MASK; if( cbBuffer > SOCKET_MY_MAX_DATA_BLOCK_SIZE ) cbBuffer = SOCKET_MY_MAX_DATA_BLOCK_SIZE; char* pBuffer = m_sendPacketBuffer + cbHeader; char* pBuffer2 = m_SendPacketBuffer2 + cbHeader; cbBuffer -= cbHeader; uint32 cbData = 0; // 开始合并数据包处理 bool bFirstPacket = true; bool bEncrypt = true; PacketList& list = m_queueSendingPacket; int64 nPacketSend = 0; PacketBase* pPkt = list.Pop_Head(); while ( pPkt != NULL ) { pPkt->IsUseIndex( m_pMgr->UseIndexWhenSend() ); pPkt->SetPacketIndex( m_nIndexOfSend ); const uint32 PacketAttr = pPkt->GetStaticAttribute(); if( PacketBase::IsDisconnectCommand( PacketAttr ) ) { DisConnect(); FACTORY_DEL_PACKET( pPkt ); return false; } if( bFirstPacket ) { bEncrypt = PacketBase::ShouldEncrypt( PacketAttr ); bFirstPacket = false; } else { if( bEncrypt != PacketBase::ShouldEncrypt( PacketAttr ) ) break; } char pktContent[PACKET_MAX_SIZE]; size_t nPktSize = pPkt->WritePacket( pktContent ) - pktContent; assert( nPktSize < PACKET_MAX_SIZE && nPktSize > 0); if(cbData + nPktSize > cbBuffer) break; memcpy( pBuffer + cbData, pktContent, nPktSize); nPacketSend++; ++m_nIndexOfSend; cbData += (uint32)nPktSize; FACTORY_DEL_PACKET( pPkt ); pPkt = list.Pop_Head(); } m_pMgr->PacketsSend().Add(nPacketSend); if(pPkt != NULL) list.Push_Head(pPkt); if( cbData == 0 ) return false; bool bCompress = false; BlockHeadT blockFlag = 0; #if LZO_COMPRESS if( m_pGLZOCompressor ) { if( bCompress && cbData > 56 ) { uint32 dstLen = cbBuffer; if(!m_pGLZOCompressor->Compress( pBuffer, cbData, pBuffer2, dstLen) ) { assert(false); MyLog::error("Socket send packet size error, Compress Fail! sockid=[%d] size=[%u]!Will disconnect", GetID(), cbData); DisConnect(); return false; } if( dstLen < cbData ) { blockFlag |= BLOCK_FLAG_LZO; std::swap( pBuffer, pBuffer2); cbData = dstLen; } } } #endif #if USE_MY_BLOWFISH if(m_pBlowFishCipher) { if(bEncrypt) { blockFlag |= Block_FLAG_ENC; m_pBlowFishCipher->Encrypt( pBuffer, pBuffer2, nDataLen); std::swap( pBuffer, pBuffer2); } } #endif if( cbData > BLOCK_SIZE_MASK ) { MyLog::error("NetChannel::FillPackets2Block() Error , cbData > BLOCK_SIZE_MASK\n"); } arg.pBuffer = pBuffer - cbHeader; arg.cbData = cbHeader + cbData; BlockHeadT blockHead = (BlockHeadT)(cbData); blockHead |= blockFlag; memcpy( arg.pBuffer, &blockHead, cbHeader); return true; }
bool NetChannel::ParsePacketsInBlock(BlockHeadT blockHead, char* pBuffer, uint32 nBlockSize) { char* pTempBuffer = m_recvPacketBuffer; #if LZO_COMPRESS if( m_pGLZOCompressor && ( 0 != (blockHead & BLOCK_FLAG_LZO))) { uint32 nDestLen = CBBUFF; if( !m_pGLZOCompressor->DeCompress( pBuffer, nBlockSize, pTempBuffer, nDestLen)) { MyLog::message("NetChannel::ParsePacketsInBlock Fail to DeCompress"); return false; } nBlockSize = nDestLen; std::swap( pBuffer, pTempBuffer); } #endif uint32 nDataLen = nBlockSize; int64 nPacketRecved = 0; bool bError = false; while( nDataLen > 0 && !bError ) { const int32 nPktID = *((int32*)pBuffer); PacketBase* pPkt = (PacketBase*)PacketFactory::Instance().New(nPktID); if(pPkt) { #if PACKET_USE_INDEX_DATA pPkt->IsUseIndex( m_pMgr->UseIndexWhenRecv()); #endif ++nPacketRecved; IRecvPacketFilter* pFilter = m_pMgr->GetRecvPacketFilter(); if( pFilter && (!pFilter->Thread_CheckPacketTypeValid(*pPkt))) { bError = true; const char* pPktName = pPkt->GetClassName(); MyLog::error("NetChannel::RecvPacket() Packet Type Check Failed, Will Disconnect Socket! pktName=[%s] pktID=[%d]", \ pPktName ? pPktName : "UNKOWN", pPkt->GetPacketID()); } if(!bError) { char* pPacketEnd = pPkt->ReadPacket(pBuffer); if( 0 == pPacketEnd ) { bError = true; const char* pPktName = pPkt->ReadPacket(pBuffer); MyLog::message("NetChannel::RecvPacket() Read Packet Failed, Will Disconnect Socket! pktName=[%s] pktID=[%d]", \ pPktName ? pPktName : "UNKOWN", pPkt->GetPacketID()); } else { uint32 nPktDataLen = uint32(pPacketEnd - pBuffer); if( nPktDataLen > nDataLen ) { bError = true; const char* pPktName = pPkt->GetClassName(); MyLog::message("NetChannel::RecvPacket() Read Packet Failed, Will Disconnect Socket! pktName=[%s] pktID=[%d]", \ pPktName ? pPktName : "UNKOWN", pPkt->GetPacketID()); } else { pBuffer += nPktDataLen; nDataLen -= nPktDataLen; } } } if(!bError) { MyLog::message("Recv Packet sock= %d id= %d \n", m_nID, nPktID); pPkt->SetSocketID( m_nID ); #if PACKET_USE_INDEX_DATA if( pPkt->IsUseIndex() && ( pPkt->GetPacketIndex() != m_nIndexOfRecv++ )) { MyLog::error("NetChannel::ParsePacketsInBlock Bad Index Recv! sock = [%d],pkt=[%s]", GetID(), pPkt->GetClass()); bError = true; FACTORY_DEL_PACKET(pPkt); } else #endif { OnPacketParsed(pPkt); } } else { FACTORY_DEL_PACKET(pPkt); } } else { bError = true; FactoryBase_Arg0* pFactory = PacketFactory::Instance().GetFactoryByPacketID(nPktID); if(pFactory) { MyLog::error("Packet Factory Create Packet name [%s] id[%d] fail", pFactory->ClassName(), nPktID); } else { MyLog::error("Packet Factroy Create Packet id[%d] fail", nPktID); } } } m_pMgr->PacketsRecv().Add(nPacketRecved); if(bError) DisConnect(); return !bError; }