00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00023 #ifndef __PACKETPIPE_H
00024 #define __PACKETPIPE_H
00025
00026 #include <list>
00027
00028 #include "Message.h"
00029 #include "CRC_Module.h"
00030
00031
00032 typedef struct cFragment {
00033 BYTE m_pbData[MAX_PACKET_SIZE];
00034 WORD m_wSize;
00035 DWORD m_dwSeed;
00036
00037 cFragment( BYTE *pbData, WORD wSize )
00038 : m_wSize( wSize + 36 )
00039 {
00040 CopyMemory( &m_pbData[36], pbData, wSize );
00041 }
00042
00043 cFragment( )
00044 : m_wSize( 0 )
00045 {
00046 }
00047
00048 ~cFragment( ) {}
00049
00050 } cFragment;
00051
00052 typedef struct cIgnoreRequest
00053 {
00054 DWORD m_dwZero;
00055 DWORD m_dwEight;
00056 DWORD m_dwCRC;
00057 DWORD m_dwNum;
00058 WORD m_wUnk1;
00059 WORD m_wUnk2;
00060 WORD m_wSize;
00061 WORD m_wTable;
00062
00063 cIgnoreRequest( )
00064 {
00065 m_dwZero = 0;
00066 m_dwEight = 8;
00067 m_wSize = 8;
00068 m_wTable = 2;
00069 }
00070 } cIgnoreRequest;
00071
00072 template< class _Type >
00073 class cPacketPipe : public _Type
00074 {
00075 friend class cClient;
00076 friend class cMasterServer;
00077
00078 public:
00079 cPacketPipe ( ) {}
00080 ~cPacketPipe( )
00081 {
00082 while ( !m_lstQueuedPackets.empty( ) )
00083 {
00084 SAFEDELETE( m_lstQueuedPackets.front( ) )
00085 m_lstQueuedPackets.pop_front( );
00086 }
00087
00088 while ( !m_lstSentPackets.empty( ) )
00089 {
00090 SAFEDELETE( m_lstSentPackets.front( ) )
00091 m_lstSentPackets.pop_front( );
00092 }
00093 }
00094
00098 inline void Initialize( )
00099 {
00100 m_dwSendSequence = 1;
00101 m_dwRecvSequence = 1;
00102 m_dwMsgID = 1;
00103 m_wTime = 12;
00104 m_pdwSendCRC = m_lpdwSendCRC;
00105 m_pdwRecvCRC = m_lpdwRecvCRC;
00106
00107 ResetCRCs( );
00108 }
00112 inline void Reset( )
00113 {
00114 m_dwSendSequence = 1;
00115 m_dwRecvSequence = 1;
00116 m_dwMsgID = 1;
00117 m_wTime = 12;
00118
00119 ResetCRCs( );
00120 }
00121
00122 inline void SetSendSequence( DWORD dwSendSequence )
00123 {
00124 m_dwSendSequence = dwSendSequence;
00125 }
00126
00135 static inline DWORD CalcCRC( BYTE *pbSendBuffer, int iSize )
00136 {
00137 DWORD dwCrc1, dwCrc2, *pdwCrc;
00138
00139 pdwCrc = (DWORD *)&pbSendBuffer[8];
00140 *pdwCrc = 0xBADD70DD;
00141 dwCrc1 = GetMagicNumber( &pbSendBuffer[0x00], 0x14, TRUE );
00142 dwCrc2 = GetMagicNumber( &pbSendBuffer[0x14], iSize, FALSE );
00143 *pdwCrc = dwCrc1 + dwCrc2;
00144
00145 return (dwCrc1 + dwCrc2);
00146 }
00147
00148 private:
00156 void AddPacket( BYTE *pbData, WORD wSize, WORD wGroup )
00157 {
00158 if ( !wSize || !pbData )
00159 return ;
00160
00161 WORD wDataSize;
00162 cFragment *pcFragment;
00163
00164 if ( FindSpaceInQueue( pbData, wSize, wGroup ) )
00165 return ;
00166
00167 WORD wSizeLeft = wSize;
00168 WORD wFragmentCount = wSize / MAX_DATA_SIZE;
00169 WORD wFragmentIndex = 0;
00170 BYTE *pbCurData = pbData;
00171
00172 if ( wSize % MAX_DATA_SIZE )
00173 ++wFragmentCount;
00174
00175 wDataSize = wSizeLeft > MAX_DATA_SIZE ? MAX_DATA_SIZE : wSizeLeft;
00176 pcFragment = new cFragment( pbCurData, wDataSize );
00177
00178 for ( ; wFragmentIndex < wFragmentCount; ++wFragmentIndex )
00179 {
00180 AddFragmentHeader( pcFragment->m_pbData + sizeof( cTransportHeader ), wDataSize, wFragmentIndex, wFragmentCount, wGroup );
00181
00182 pbCurData = pbCurData + wDataSize;
00183 wSizeLeft -= wDataSize;
00184 wDataSize = wSizeLeft > MAX_DATA_SIZE ? MAX_DATA_SIZE : wSizeLeft;
00185
00186 m_lstQueuedPackets.push_back( pcFragment );
00187
00188 if ( wDataSize )
00189 pcFragment = new cFragment( pbCurData, wDataSize );
00190 }
00191
00192 ++m_dwMsgID;
00193
00194 }
00200 void SendQueuedPackets( SOCKADDR_IN& saSockAddr )
00201 {
00202 cTransportHeader *pcTH;
00203 cFragment *pcFragment;
00204
00205 while ( !m_lstQueuedPackets.empty( ) )
00206 {
00207 pcFragment = m_lstQueuedPackets.front( );
00208
00209 pcTH = reinterpret_cast< cTransportHeader * >( pcFragment->m_pbData );
00210
00211 pcTH->m_dwSequence = ++m_dwSendSequence;
00212 pcTH->m_dwFlags = 0x0200;
00213 pcTH->m_wLogicalID = m_wLogicalID;
00214 pcTH->m_wTime = m_wTime;
00215 pcTH->m_wTotalSize = pcFragment->m_wSize - sizeof( cTransportHeader );
00216 pcTH->m_wTable = 0x0000;
00217
00218 DWORD dwNewCRC, dwXorVal;
00219
00220
00221 dwNewCRC = GetMagicNumber(pcFragment->m_pbData + sizeof(cTransportHeader),pcTH->m_wTotalSize,1);
00222
00223 dwXorVal = GetSendXORVal( m_pdwSendCRC );
00224 dwNewCRC ^= dwXorVal;
00225
00226 pcTH->m_dwCRC = 0xBADD70DD;
00227
00228
00229
00230 dwNewCRC += GetMagicNumber(pcFragment->m_pbData, sizeof(cTransportHeader),1);
00231
00232 pcTH->m_dwCRC = dwNewCRC;
00233
00234 sendto( m_Socket, (char *)pcFragment->m_pbData, pcFragment->m_wSize, NULL, (sockaddr *)&saSockAddr, sizeof( SOCKADDR ) );
00235
00236 pcFragment->m_dwSeed = dwXorVal;
00237
00238 m_lstSentPackets.push_back( pcFragment );
00239 m_lstQueuedPackets.pop_front( );
00240 }
00241 }
00249 static inline DWORD Calc200_CRC( BYTE *pbPacket )
00250 {
00251 BYTE *pbPacketEnd = pbPacket + reinterpret_cast< cTransportHeader * > ( pbPacket )->m_wTotalSize + sizeof ( cTransportHeader );
00252 DWORD dwCrc = 0;
00253
00254 for ( BYTE *pbFragment = pbPacket + sizeof ( cTransportHeader ); pbFragment < pbPacketEnd; )
00255 {
00256 WORD wLength = reinterpret_cast< cFragmentHeader * > ( pbFragment )->m_wFragmentLength;
00257
00258 dwCrc += GetMagicNumber ( pbFragment, sizeof ( cFragmentHeader ), 1 ) + GetMagicNumber ( pbFragment + sizeof ( cFragmentHeader ), wLength - sizeof ( cFragmentHeader ), TRUE );
00259 pbFragment += wLength;
00260 }
00261
00262 return dwCrc;
00263 }
00271 static inline DWORD CalcTransportCRC( DWORD *pdwWoot )
00272 {
00273 DWORD dwOrg = pdwWoot[2];
00274 DWORD dwCrc = 0;
00275
00276 pdwWoot[2] = 0xBADD70DD;
00277 dwCrc += GetMagicNumber( (BYTE *)pdwWoot, 20, TRUE );
00278 pdwWoot[2] = dwOrg;
00279
00280 return dwCrc;
00281 }
00291 static DWORD GetMagicNumber( BYTE *pbBuf, WORD wSize, BOOL fIncludeSize )
00292 {
00293 DWORD dwCS = 0;
00294 int i;
00295
00296 if ( fIncludeSize )
00297 dwCS += wSize << 16;
00298
00299
00300 for (i = 0; i < (wSize >> 2); ++i )
00301 dwCS += ((DWORD *)pbBuf)[i];
00302
00303
00304 int iShift = 3;
00305 for ( i = (i << 2); i < wSize; ++i )
00306 {
00307 dwCS += pbBuf[i] << (iShift * 8);
00308 --iShift;
00309 }
00310
00311 return dwCS;
00312 }
00318 void ReturnPing( SOCKADDR_IN& saSockAddr )
00319 {
00320 char szSendBuffer[0x40];
00321
00322 DWORD *last = (DWORD *)&szSendBuffer[0x14];
00323
00324 cTransportHeader *pcTH;
00325 pcTH = reinterpret_cast< cTransportHeader * >( szSendBuffer );
00326 pcTH->m_dwSequence = m_dwSendSequence;
00327 pcTH->m_dwFlags = 0x00000004;
00328 pcTH->m_wLogicalID = m_wLogicalID;
00329 pcTH->m_wTime = m_wTime;
00330 pcTH->m_wTotalSize = 4;
00331 pcTH->m_wTable = 0;
00332
00333 *last = m_dwRecvSequence;
00334
00335 CalcCRC( (BYTE *)szSendBuffer, 4 );
00336 sendto( m_Socket, (char *)szSendBuffer, 24, NULL, (SOCKADDR *)&saSockAddr, sizeof( SOCKADDR ) );
00337 }
00344 inline void AddPacket( cMessage& cmPacket, WORD wGroup )
00345 {
00346 WORD wSize = cmPacket.getSize( );
00347
00348 BYTE *pbData = new BYTE[wSize];
00349 cmPacket.getData( 0, wSize, pbData );
00350
00351 AddPacket( pbData, wSize, wGroup );
00352
00353 SAFEDELETE_ARRAY( pbData )
00354 }
00362 BOOL FindSpaceInQueue( BYTE *pbData, WORD wSize, WORD wGroup )
00363 {
00364 cFragment *pcFragment;
00365
00366 std::list< cFragment * >::iterator itFragment = m_lstQueuedPackets.begin( );
00367 for ( ; itFragment != m_lstQueuedPackets.end( ); ++itFragment )
00368 {
00369 pcFragment = *itFragment;
00370
00371 if ( pcFragment->m_wSize + wSize + sizeof( cFragmentHeader ) <= MAX_PACKET_SIZE )
00372 {
00373 CopyMemory( &pcFragment->m_pbData[pcFragment->m_wSize + sizeof( cFragmentHeader )], pbData, wSize );
00374 AddFragmentHeader( &pcFragment->m_pbData[pcFragment->m_wSize], wSize, 0, 1, wGroup );
00375 pcFragment->m_wSize += wSize + sizeof( cFragmentHeader );
00376 return TRUE;
00377 }
00378 }
00379 return FALSE;
00380 }
00390 inline void AddFragmentHeader( BYTE *pbStart, WORD wSize, WORD wFragmentIndex, WORD wFragmentCount, WORD wGroup )
00391 {
00392 cFragmentHeader *pcFH = reinterpret_cast< cFragmentHeader * >( pbStart );
00393
00394 pcFH->m_dwSequence = m_dwMsgID;
00395 pcFH->m_dwObjectID = 0x80000000;
00396 pcFH->m_wFragmentIndex = wFragmentIndex;
00397 pcFH->m_wFragmentLength = wSize + sizeof( cFragmentHeader );
00398 pcFH->m_wFragmentCount = wFragmentCount;
00399 pcFH->m_wFragmentGroup = wGroup;
00400 }
00408 void ProcessLostPackets( DWORD dwNumLostPackets, DWORD *pdwMissingPackets, SOCKADDR_IN& saSockAddr )
00409 {
00410
00411 DWORD dwNumIgnored = 0;
00412
00413 std::vector< DWORD > vIgnoreList;
00414 vIgnoreList.reserve( dwNumLostPackets );
00415
00416 cFragment *pcFragment;
00417
00418 for ( DWORD dwCurrentPacket = 0; dwCurrentPacket < dwNumLostPackets; ++dwCurrentPacket )
00419 {
00420 std::list< cFragment * >::iterator itFragment = m_lstSentPackets.begin( );
00421 for ( ; itFragment != m_lstSentPackets.end( ); ++itFragment )
00422 {
00423 pcFragment = *itFragment;
00424 if ( *((DWORD *)pcFragment->m_pbData) == pdwMissingPackets[dwCurrentPacket] )
00425 break;
00426 }
00427
00428 if ( itFragment != m_lstSentPackets.end( ) )
00429 {
00430 cTransportHeader *pcTH = reinterpret_cast< cTransportHeader * >( pcFragment->m_pbData );
00431
00432 pcTH->m_dwFlags = 0x00000201;
00433 pcTH->m_wTime = m_wTime;
00434
00435 DWORD dwNewCRC;
00436 dwNewCRC = Calc200_CRC( pcFragment->m_pbData );
00437 dwNewCRC ^= pcFragment->m_dwSeed;
00438 dwNewCRC += CalcTransportCRC( (DWORD *)pcFragment->m_pbData );
00439
00440 pcTH->m_dwCRC = dwNewCRC;
00441
00442 sendto( m_Socket, (char *)pcFragment->m_pbData, pcFragment->m_wSize, NULL, (SOCKADDR *)&saSockAddr, sizeof( SOCKADDR ) );
00443 }
00444 else
00445 {
00446 vIgnoreList.push_back( pdwMissingPackets[dwCurrentPacket] );
00447 ++dwNumIgnored;
00448 }
00449 }
00450
00451 if ( !vIgnoreList.empty( ) )
00452 {
00453 BYTE pbSendBuffer[0x1E4];
00454
00455 cIgnoreRequest irOut;
00456 irOut.m_dwNum = dwNumIgnored;
00457 irOut.m_wUnk1 = m_wLogicalID;
00458 irOut.m_wUnk2 = m_wTime;
00459 irOut.m_wSize = 4 + dwNumIgnored * 4;
00460
00461 CopyMemory( pbSendBuffer, &irOut, sizeof( cIgnoreRequest ) );
00462
00463 std::vector< DWORD >::iterator itIgnore = vIgnoreList.begin( );
00464 for ( DWORD dwCount = 0; itIgnore != vIgnoreList.end( ); ++itIgnore, ++dwCount )
00465 CopyMemory( pbSendBuffer + sizeof( irOut ) + dwCount * 4, &itIgnore, sizeof( DWORD ) );
00466
00467 irOut.m_dwCRC = CalcCRC( pbSendBuffer, 4 + dwNumIgnored * 4 );
00468
00469 sendto( m_Socket, (char*)pbSendBuffer, sizeof( irOut ) + dwNumIgnored * 4, NULL, (SOCKADDR *)&saSockAddr, sizeof( SOCKADDR ) );
00470
00471 vIgnoreList.clear( );
00472 }
00473
00474 }
00480 inline void ClearSentPackets( DWORD dwLastGoodSeq )
00481 {
00482 cFragment *pcFragment;
00483
00484 while ( !m_lstSentPackets.empty( ) )
00485 {
00486 pcFragment = m_lstSentPackets.front( );
00487
00488 if ( *((DWORD *)pcFragment->m_pbData) > dwLastGoodSeq )
00489 break;
00490 else
00491 {
00492 m_lstSentPackets.pop_front( );
00493 SAFEDELETE( pcFragment )
00494 }
00495 }
00496 }
00497 inline void ResetCRCs( )
00498 {
00499 GenerateCRCs( m_dwSendCRCSeed, m_dwRecvCRCSeed, m_pdwSendCRC, m_pdwRecvCRC );
00500 }
00501
00502 DWORD m_lpdwSendCRC[3];
00503 DWORD m_lpdwRecvCRC[3];
00504 DWORD *m_pdwSendCRC;
00505 DWORD *m_pdwRecvCRC;
00506 DWORD m_dwSendSequence;
00507 DWORD m_dwRecvSequence;
00508 DWORD m_dwMsgID;
00509 WORD m_wTime;
00510
00511
00512 std::list< cFragment * > m_lstQueuedPackets;
00513 std::list< cFragment * > m_lstSentPackets;
00514 };
00515
00516 #endif // #ifndef __PACKETPIPE_H