Clone of PhatAC @ https://github.com/floaterxk/PhatAC

PacketController.cpp 18KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924
  1. #include "StdAfx.h"
  2. #include "Client.h"
  3. //Network access.
  4. #include "crc.h"
  5. #include "BinaryWriter.h"
  6. #include "BinaryReader.h"
  7. #include "Network.h"
  8. #include "FragStack.h"
  9. #include "PacketController.h"
  10. CPacketController::CPacketController(CClient *client)
  11. {
  12. m_pClient = client;
  13. m_pPeer = client->GetHostAddress();
  14. m_bEvil = FALSE;
  15. GenerateCRCs(0xAC2DAC2D, 0xAC2DAC2D, m_out.servercrc, m_in.clientcrc);
  16. }
  17. CPacketController::~CPacketController()
  18. {
  19. EraseInternal(&m_in.fragstack); //!!FIXME
  20. EraseInternalA(&m_in.blobstack);
  21. EraseInternalA(&m_out.blobcache);
  22. EraseInternalA(&m_out.fragqueue);
  23. }
  24. template<class T>
  25. void CPacketController::EraseInternal(T *data)
  26. {
  27. if (data->empty())
  28. return;
  29. for (T::iterator it = data->begin(); it != data->end(); it++)
  30. {
  31. delete (*it);
  32. }
  33. data->clear();
  34. }
  35. template<class T>
  36. void CPacketController::EraseInternalA(T *data)
  37. {
  38. if (data->empty())
  39. return;
  40. for (T::iterator it = data->begin(); it != data->end(); it++)
  41. {
  42. delete[](*it);
  43. }
  44. data->clear();
  45. }
  46. DWORD CPacketController::GetNextEvent(void)
  47. {
  48. return (++m_out.event_counter);
  49. }
  50. DWORD CPacketController::GetLastEvent(void)
  51. {
  52. return (--m_out.event_counter);
  53. }
  54. void CPacketController::ResetEvent(void)
  55. {
  56. m_out.event_counter = 0;
  57. }
  58. DWORD CPacketController::GetNextSequence(void)
  59. {
  60. return (++m_out.sequence);
  61. }
  62. DWORD CPacketController::GetLastSequence(void)
  63. {
  64. return (--m_out.sequence);
  65. }
  66. BOOL CPacketController::SendNetMessage(void *data, DWORD length, WORD group)
  67. {
  68. DWORD dwRPC = 0x80000000;
  69. if (length >= 4)
  70. {
  71. DWORD dwMessageID = *((DWORD *)data);
  72. switch (dwMessageID)
  73. {
  74. case 0x0000F748: dwRPC = 0x0023CED7; break;
  75. case 0x0000F74C: dwRPC = 0x0023CE75; break;
  76. case 0x0000F658: dwRPC = 0x030BA655; break;
  77. case 0x0000F7E1: dwRPC = 0x030BA656; break;
  78. case 0x0000F7E2: dwRPC = 0x030B5C8D; break;
  79. }
  80. }
  81. //Every fragment has a unique sequence.
  82. DWORD dwFragSequence = ++m_out.fragment_counter;
  83. //Calculate the number of fragments necessary for the message.
  84. WORD wFragCount = (WORD)(length / MAX_FRAGMENT_LEN);
  85. if (length % MAX_FRAGMENT_LEN) wFragCount++;
  86. WORD wFragIndex = 0;
  87. WORD wFragLength = 0;
  88. while (wFragIndex < wFragCount)
  89. {
  90. if (wFragCount != (wFragIndex + 1))
  91. wFragLength = MAX_FRAGMENT_LEN;
  92. else
  93. {
  94. wFragLength = (WORD)(length % MAX_FRAGMENT_LEN);
  95. if (!wFragLength)
  96. wFragLength = MAX_FRAGMENT_LEN;
  97. }
  98. FragHeader_s header;
  99. {
  100. header.dwSequence = dwFragSequence;
  101. header.dwID = dwRPC;
  102. header.wCount = wFragCount;
  103. header.wSize = sizeof(FragHeader_s) + wFragLength;
  104. header.wIndex = wFragIndex;
  105. header.wGroup = group;
  106. }
  107. QueueFragment(&header, &((BYTE *)data)[wFragIndex * MAX_FRAGMENT_LEN]);
  108. wFragIndex++;
  109. }
  110. return TRUE;
  111. }
  112. void CPacketController::QueueFragment(FragHeader_s *header, BYTE *data)
  113. {
  114. FragPacket_s *fragment = (FragPacket_s *)new BYTE[header->wSize];
  115. memcpy(&fragment->header, header, sizeof(FragHeader_s));
  116. memcpy(&fragment->data, data, header->wSize - sizeof(FragHeader_s));
  117. m_out.fragqueue.push_back(fragment);
  118. }
  119. void CPacketController::Cleanup()
  120. {
  121. //Delete and remove whatever has been processed or successful sent.
  122. //The fragments that are complete have already been processed.
  123. for (std::list<FragmentStack *>::iterator it = m_in.fragstack.begin(); it != m_in.fragstack.end();)
  124. {
  125. FragmentStack *poo = *it;
  126. if (poo->IsComplete())
  127. {
  128. delete poo;
  129. it = m_in.fragstack.erase(it);
  130. }
  131. else
  132. it++;
  133. }
  134. for (std::list<BlobPacket_s *>::iterator it = m_in.blobstack.begin(); it != m_in.blobstack.end();)
  135. {
  136. BlobPacket_s *poo = *it;
  137. if (poo->header.dwSequence <= m_in.activesequence)
  138. {
  139. delete[] poo;
  140. it = m_in.blobstack.erase(it);
  141. }
  142. else
  143. it++;
  144. }
  145. //Cached blobs to flush??
  146. for (std::list<BlobPacket_s *>::iterator it = m_out.blobcache.begin(); it != m_out.blobcache.end();)
  147. {
  148. BlobPacket_s *poo = *it;
  149. if (poo->header.dwSequence <= m_in.flushsequence)
  150. {
  151. delete[] poo;
  152. it = m_out.blobcache.erase(it);
  153. }
  154. else
  155. it++;
  156. }
  157. }
  158. void CPacketController::ThinkInbound(void)
  159. {
  160. //Check if we have sequences available for processing.
  161. DWORD dwDesired = m_in.activesequence + 1;
  162. iterate:
  163. if (dwDesired <= m_in.sequence)
  164. {
  165. for (BlobList::iterator it = m_in.blobstack.begin(); it != m_in.blobstack.end(); it++)
  166. {
  167. BlobPacket_s *p = *it;
  168. if (dwDesired == p->header.dwSequence)
  169. {
  170. ProcessBlob(p);
  171. m_in.lastactivity = g_pGlobals->Time();
  172. delete[] p;
  173. m_in.blobstack.erase(it);
  174. m_in.activesequence = dwDesired++;
  175. goto iterate;
  176. }
  177. }
  178. }
  179. if ((dwDesired + 5 <= m_in.sequence) && ((m_in.lastrequest + 3) < g_pGlobals->Time()))
  180. {
  181. //request lost sequences
  182. std::vector<DWORD> lostSequences;
  183. lostSequences.push_back(dwDesired);
  184. DWORD lowBound = dwDesired + 1;
  185. DWORD highBound = m_in.sequence;
  186. for (DWORD check = lowBound; check < highBound; check++)
  187. {
  188. BlobList::iterator it = m_in.blobstack.begin();
  189. for (; it != m_in.blobstack.end(); it++)
  190. {
  191. BlobPacket_s *p = *it;
  192. if (check == p->header.dwSequence)
  193. break;
  194. }
  195. if (it == m_in.blobstack.end())
  196. lostSequences.push_back(check);
  197. }
  198. DWORD dwCount = (DWORD)lostSequences.size();
  199. CREATEBLOB(p, sizeof(DWORD) + dwCount * sizeof(DWORD));
  200. *((DWORD *)p->data) = lostSequences.size();
  201. DWORD *requestPos = ((DWORD *)p->data) + 1;
  202. std::vector<DWORD>::iterator requestIt = lostSequences.begin();
  203. for (; requestIt != lostSequences.end(); requestIt++) {
  204. *requestPos = *requestIt;
  205. requestPos++;
  206. }
  207. g_pNetwork->SendConnectlessBlob(m_pPeer, p, BT_REQUESTLOST, NULL, GetElapsedTime());
  208. DELETEBLOB(p);
  209. m_in.lastrequest = g_pGlobals->Time();
  210. LOG(Network, Verbose, "Requesting %d lost packets for %s..\n", lostSequences.size(), m_pClient->GetDescription());
  211. }
  212. }
  213. void CPacketController::ThinkOutbound(void)
  214. {
  215. //Now for the output
  216. double time = g_pGlobals->Time();
  217. if (0)//m_out.loginsyncs < 2)
  218. {
  219. /*
  220. if (m_out.loginsyncs >= 0)
  221. {
  222. //if ((m_out.lastloginsync + 2.0f) < time)
  223. // PerformLoginSync();
  224. }
  225. */
  226. }
  227. else
  228. {
  229. if ((m_out.lastflush + 3.0f) < time)
  230. FlushPeerCache();
  231. if ((m_out.lasttimeupdate + 3.0f) < time)
  232. UpdatePeerTime();
  233. if (!m_out.fragqueue.empty())
  234. FlushFragments();
  235. }
  236. }
  237. void CPacketController::Think(void)
  238. {
  239. if (!IsAlive())
  240. return;
  241. // Handle the input first.
  242. ThinkInbound();
  243. // Cleanup before we clutter the cache with new stuff.
  244. Cleanup();
  245. // Handle the output last.
  246. ThinkOutbound();
  247. if ((g_pGlobals->Time() - m_in.lastactivity) >= 30.0f)
  248. {
  249. Kill(__FILE__, __LINE__);
  250. }
  251. }
  252. BOOL CPacketController::HasConnection()
  253. {
  254. return TRUE; // (m_out.loginsyncs >= 2) ? TRUE : FALSE;
  255. }
  256. void CPacketController::PerformLoginSync()
  257. {
  258. /* PUT THIS BACK IN?
  259. m_out.lastloginsync = g_pGlobals->Time();
  260. CREATEBLOB( LoginSync, 0xE6 );
  261. memset( &LoginSync->data[8], 0, 0xDE );
  262. *((double *)LoginSync->data) = g_pGlobals->Time();
  263. g_pNetwork->SendConnectlessBlob(m_pPeer, LoginSync, BT_CONNECTIONACK, NULL, GetElapsedTime());
  264. DELETEBLOB( LoginSync );
  265. */
  266. }
  267. void CPacketController::FlushPeerCache()
  268. {
  269. m_out.lastflush = g_pGlobals->Time();
  270. //
  271. CREATEBLOB(p, sizeof(DWORD));
  272. *((DWORD *)p->data) = m_in.activesequence;
  273. g_pNetwork->SendConnectlessBlob(m_pPeer, p, BT_ACKSEQUENCE, m_out.sequence, GetElapsedTime());
  274. DELETEBLOB(p);
  275. }
  276. void CPacketController::UpdatePeerTime()
  277. {
  278. m_out.lasttimeupdate = g_pGlobals->Time();
  279. CREATEBLOB(tupdate, sizeof(double));
  280. *((double *)tupdate->data) = g_pGlobals->Time();
  281. BlobHeader_s *header = &tupdate->header;
  282. header->dwSequence = GetNextSequence();
  283. header->dwFlags = BT_TIMEUPDATE | BT_USES_CRC;
  284. header->dwCRC = 0;
  285. header->wRecID = g_pNetwork->GetServerID();
  286. header->wTime = GetElapsedTime();
  287. header->wTable = 0x01;
  288. DWORD dwXOR = GetSendXORVal(m_out.servercrc);
  289. header->dwCRC = BlobCRC(tupdate, dwXOR);
  290. //Off you go.
  291. g_pNetwork->SendPacket(m_pPeer, tupdate, BLOBLEN(tupdate));
  292. // g_pNetwork->SendConnectlessBlob(m_pPeer, tupdate, BT_TIMEUPDATE, m_out.sequence, GetElapsedTime());
  293. //Cache for later use.
  294. m_out.blobcache.push_back(tupdate);
  295. }
  296. WORD CPacketController::GetElapsedTime()
  297. {
  298. return (WORD)((g_pGlobals->Time() - m_in.logintime) * 2);
  299. }
  300. //This is a generic handler for malicious clients.
  301. void CPacketController::EvilClient(const char* szSource, DWORD dwLine, BOOL bKill)
  302. {
  303. #ifdef _DEBUG
  304. if (szSource)
  305. LOG(Temp, Normal, "Evil client @ %u of %s!!!\n", dwLine, szSource);
  306. #endif
  307. if (bKill && IsAlive())
  308. {
  309. Kill(szSource, dwLine);
  310. }
  311. }
  312. void CPacketController::ProcessBlob(BlobPacket_s *blob)
  313. {
  314. BlobHeader_s *header = &blob->header;
  315. DWORD dwSequence = header->dwSequence;
  316. DWORD dwFlags = header->dwFlags;
  317. DWORD dwCRC = header->dwCRC;
  318. DWORD dwSize = header->wSize;
  319. BYTE* pbData = blob->data;
  320. if (dwFlags & BT_REQUESTLOST) //0x00000002
  321. {
  322. if (dwSize >= 4)
  323. {
  324. //LOG(Temp, Normal, "Client requesting lost packets.\n");
  325. DWORD dwLostPackets = *((DWORD *)pbData);
  326. pbData += sizeof(DWORD);
  327. dwSize -= sizeof(DWORD);
  328. if (dwSize >= (dwLostPackets * sizeof(DWORD)))
  329. {
  330. DWORD dwDenySize = 0;
  331. DWORD dwDenyBlobs[0x50];
  332. for (unsigned int i = 0; i < dwLostPackets; i++)
  333. {
  334. DWORD dwRequested = ((DWORD *)pbData)[i];
  335. if (dwRequested < 2 || dwRequested > m_out.sequence)
  336. {
  337. // Sequence out of range.
  338. FlagEvilClient();
  339. continue;
  340. }
  341. //Find the requested sequence in the cache.
  342. BlobList::iterator it;
  343. for (it = m_out.blobcache.begin(); it != m_out.blobcache.end(); it++)
  344. {
  345. BlobPacket_s *p = *it;
  346. if (dwRequested == p->header.dwSequence)
  347. {
  348. ResendBlob(p);
  349. break;
  350. }
  351. }
  352. if (it == m_out.blobcache.end())
  353. {
  354. if (dwDenySize < 0x50)
  355. {
  356. dwDenyBlobs[dwDenySize] = dwRequested;
  357. dwDenySize++;
  358. }
  359. else
  360. {
  361. // Too many
  362. FlagEvilClient();
  363. }
  364. }
  365. }
  366. if (dwDenySize > 0)
  367. {
  368. DWORD dwLength = dwDenySize * sizeof(DWORD);
  369. CREATEBLOB(p, sizeof(DWORD) + dwLength);
  370. memcpy(p->data, &dwDenySize, sizeof(DWORD));
  371. memcpy(p->data + sizeof(DWORD), dwDenyBlobs, dwLength);
  372. g_pNetwork->SendConnectlessBlob(m_pPeer, p, BT_DENY, NULL, GetElapsedTime());
  373. DELETEBLOB(p);
  374. }
  375. pbData += sizeof(DWORD) * dwLostPackets;
  376. dwSize -= sizeof(DWORD) * dwLostPackets;
  377. }
  378. else
  379. {
  380. FlagEvilClient();
  381. return;
  382. }
  383. }
  384. else
  385. {
  386. FlagEvilClient();
  387. return;
  388. }
  389. }
  390. if (dwFlags & BT_DENY) //0x00000008
  391. {
  392. if (dwSize >= 4)
  393. {
  394. DWORD dwDeniedCount = *((DWORD *)pbData);
  395. pbData += sizeof(DWORD);
  396. dwSize -= sizeof(DWORD);
  397. if (dwSize == (dwDeniedCount * sizeof(DWORD)))
  398. {
  399. unsigned int i = 0;
  400. while (i < dwSize)
  401. {
  402. DWORD dwDenied = ((DWORD *)pbData)[i];
  403. if (dwDenied <= m_in.sequence)
  404. {
  405. if (dwDenied == (m_in.activesequence + 1))
  406. {
  407. m_in.activesequence++;
  408. i = 0;
  409. }
  410. }
  411. //else
  412. // FlagEvilClient(__FILE__, __LINE__);
  413. i++;
  414. }
  415. }
  416. else
  417. FlagEvilClient();
  418. }
  419. else
  420. FlagEvilClient();
  421. return;
  422. }
  423. if (dwFlags & BT_ACKSEQUENCE)
  424. {
  425. if (dwSize < 4)
  426. {
  427. FlagEvilClient();
  428. return;
  429. }
  430. m_in.flushsequence = *((DWORD *)pbData);
  431. dwSize -= 4;
  432. pbData += 4;
  433. }
  434. /*
  435. if (dwFlags & BT_LOGIN)
  436. {
  437. if (m_out.loginsyncs < 0)
  438. m_out.loginsyncs = 0;
  439. return;
  440. }
  441. */
  442. /*
  443. if (dwFlags & BT_CONNECTIONACK) //0x00000040
  444. {
  445. if (m_out.loginsyncs >= 0)
  446. {
  447. m_out.loginsyncs++;
  448. if (m_out.loginsyncs < 2)
  449. {
  450. m_in.lastactivity = g_pGlobals->Time();
  451. // PerformLoginSync();
  452. }
  453. }
  454. return;
  455. }
  456. */
  457. if (dwFlags & BT_TIMEUPDATE) //0x00100000
  458. {
  459. #ifdef _DEBUG
  460. //if (dwFlags & BT_FRAGMENTS)
  461. // LOG(Temp, Normal, "Fragments? %s %u\n", __FILE__, __LINE__);
  462. #endif
  463. if (dwSize < 8)
  464. {
  465. FlagEvilClient();
  466. return;
  467. }
  468. else
  469. {
  470. //Time critical.
  471. /*
  472. const double gear_tolerance = 1.0f; // Cheater!! =)
  473. if ( (g_pGlobals->Time() + gear_tolerance) < *((double *)pbData) )
  474. {
  475. const char* account = m_pClient->GetAccount( );
  476. SOCKADDR_IN *ip = m_pClient->GetHostAddress( );
  477. LOG(Temp, Normal, "Detected client(%s @ %s) using gear. Killing!\n", (account ? account : "???"), (ip ? inet_ntoa(ip->sin_addr) : "???") );
  478. g_pNetwork->KickClient( m_pClient->GetIndex() );
  479. }
  480. return;
  481. */
  482. }
  483. dwSize -= 8;
  484. pbData += 8;
  485. }
  486. if (dwFlags & BT_ECHOREQUEST)
  487. {
  488. if (dwSize < 4)
  489. {
  490. FlagEvilClient();
  491. return;
  492. }
  493. DWORD echoValue = *((DWORD *)pbData);
  494. /*
  495. CREATEBLOB(tupdate, sizeof(DWORD));
  496. *((DWORD *)tupdate->data) = echoValue;
  497. BlobHeader_s *header = &tupdate->header;
  498. header->dwSequence = m_out.sequence;
  499. header->dwFlags = BT_ECHORESPONSE | BT_USES_CRC;
  500. header->dwCRC = 0;
  501. header->wRecID = g_pNetwork->GetServerID();
  502. header->wTime = GetElapsedTime();
  503. header->wTable = 0x01;
  504. DWORD dwXOR = GetSendXORVal(m_out.servercrc);
  505. header->dwCRC = BlobCRC(tupdate, dwXOR);
  506. //Off you go.
  507. g_pNetwork->SendPacket(m_pPeer, tupdate, BLOBLEN(tupdate));
  508. //Cache for later use.
  509. header->dwCRC = dwXOR;
  510. m_out.blobcache.push_back(tupdate);
  511. */
  512. CREATEBLOB(tupdate, sizeof(DWORD));
  513. *((DWORD *)tupdate->data) = echoValue;
  514. g_pNetwork->SendConnectlessBlob(m_pPeer, tupdate, BT_ECHORESPONSE, m_out.sequence, GetElapsedTime());
  515. pbData += sizeof(DWORD);
  516. dwSize -= sizeof(DWORD);
  517. }
  518. if (dwFlags & BT_ECHORESPONSE)
  519. {
  520. if (dwSize < 8)
  521. {
  522. FlagEvilClient();
  523. return;
  524. }
  525. else
  526. {
  527. pbData += sizeof(float);
  528. pbData += sizeof(float);
  529. }
  530. dwSize -= 8;
  531. }
  532. if (dwFlags & BT_FLOW)
  533. {
  534. if (dwSize < 6)
  535. {
  536. FlagEvilClient();
  537. return;
  538. }
  539. else
  540. {
  541. DWORD dwBytes = *((DWORD *)pbData);
  542. pbData += sizeof(DWORD);
  543. WORD wElapsed = *((WORD *)pbData);
  544. pbData += sizeof(WORD);
  545. //LOG(Temp, Normal, "Flow: %u bytes over %u seconds\n", dwBytes, wElapsed );
  546. }
  547. dwSize -= 6;
  548. }
  549. if (dwFlags & BT_FRAGMENTS)
  550. {
  551. while (dwSize >= sizeof(FragHeader_s))
  552. {
  553. FragPacket_s *frag = (FragPacket_s *)pbData;
  554. if (dwSize < frag->header.wSize)
  555. break;
  556. pbData += frag->header.wSize;
  557. dwSize -= frag->header.wSize;
  558. BYTE* data = frag->data;
  559. DWORD length = frag->header.wSize - sizeof(FragHeader_s);
  560. if (frag->header.wCount == 1)
  561. {
  562. ProcessMessage(data, length, frag->header.wGroup);
  563. }
  564. else
  565. {
  566. FragmentList::iterator it;
  567. DWORD dwSequence = frag->header.dwSequence;
  568. DWORD dwLogicalID = frag->header.dwID;
  569. if (dwLogicalID != 0x80000000)
  570. LOG(Temp, Normal, "Client sent ID %08X\n");
  571. bool bCompleted = false;
  572. for (it = m_in.fragstack.begin(); it != m_in.fragstack.end(); it++)
  573. {
  574. FragmentStack *s = *it;
  575. if (s->m_dwSequence == dwSequence && s->m_dwID == dwLogicalID)
  576. {
  577. s->AddFragment(frag);
  578. if (s->IsComplete())
  579. {
  580. ProcessMessage(s->GetData(), s->GetLength(), frag->header.wGroup);
  581. delete s;
  582. m_in.fragstack.erase(it);
  583. bCompleted = true;
  584. }
  585. break;
  586. }
  587. }
  588. if (!bCompleted)
  589. {
  590. if (it == m_in.fragstack.end())
  591. {
  592. // No existing group matches, create one
  593. FragmentStack *s = new FragmentStack(frag);
  594. m_in.fragstack.push_back(s);
  595. }
  596. }
  597. }
  598. }
  599. }
  600. }
  601. void CPacketController::ProcessMessage(BYTE *data, DWORD length, WORD group)
  602. {
  603. if (m_pClient->IsAlive())
  604. m_pClient->ProcessMessage(data, length, group);
  605. }
  606. void CPacketController::IncomingBlob(BlobPacket_s *blob)
  607. {
  608. /*
  609. Client's process goes something like this:
  610. (args: blob, size)
  611. DWORD dwHeaderCRC = CalcTransportCRC( buffer );
  612. blob.crc -= dwHeaderCRC;
  613. DWORD dwFlags = blob.flags;
  614. if ( dwFlags & 0x00000080 ) //account packet
  615. {
  616. //??
  617. UnlockThread();
  618. return 1;
  619. }
  620. else if ( dwFlags & 0x00000008 ) //deny sequences
  621. {
  622. blob.crc -= GetMagicNumber( blob.data, blob.size, FALSE );
  623. if ( !blob.crc )
  624. {
  625. UnlockThread();
  626. return 3;
  627. }
  628. else
  629. return 2;
  630. }
  631. else if ( dwFlags & 0x00100000 ) //update time
  632. {
  633. if ( size >= 8 )
  634. {
  635. }
  636. }
  637. else
  638. {
  639. if ( dwFlags & 0x00800000 ) // error
  640. {
  641. if ( size >= 4 )
  642. {
  643. }
  644. }
  645. else if ( )//etc.
  646. {
  647. }
  648. }
  649. */
  650. //No CRC checks as of yet.
  651. BlobHeader_s *header = &blob->header;
  652. DWORD dwSequence = header->dwSequence;
  653. DWORD dwFlags = header->dwFlags;
  654. DWORD dwCRC = header->dwCRC;
  655. DWORD dwSize = header->wSize;
  656. BYTE* pbData = blob->data;
  657. if (dwSequence > m_in.sequence) m_in.sequence = dwSequence;
  658. if (dwFlags & BT_DISCONNECT)
  659. {
  660. Kill(__FILE__, __LINE__);
  661. return;
  662. }
  663. if (dwFlags & BT_REQUESTLOST)
  664. {
  665. ProcessBlob(blob);
  666. return;
  667. }
  668. /*
  669. if (dwFlags & BT_ACKSEQUENCE)
  670. {
  671. if (dwSize < 4)
  672. FlagEvilClient();
  673. else
  674. m_in.flushsequence = *((DWORD *)blob->data);
  675. if (dwSequence == m_in.activesequence)
  676. {
  677. m_in.lastactivity = g_pGlobals->Time();
  678. }
  679. return;
  680. }
  681. */
  682. if (dwSequence == 0x00000001)
  683. {
  684. //if (dwFlags == BT_NULL)
  685. // return;
  686. }
  687. if (dwSequence == 0x00000002)
  688. {
  689. //if (dwFlags & BT_CRCUPDATE)
  690. // return;
  691. }
  692. if (!dwSequence)
  693. {
  694. ProcessBlob(blob);
  695. return;
  696. }
  697. if (dwSequence <= m_in.activesequence) return;
  698. //Cache this blob, for later use.
  699. DUPEBLOB(p, blob);
  700. m_in.blobstack.push_back(p);
  701. }
  702. void CPacketController::ResendBlob(BlobPacket_s *blob)
  703. {
  704. BlobHeader_s *header = &blob->header;
  705. header->dwFlags |= BT_RESENT;
  706. DWORD dwXOR = header->dwCRC;
  707. header->dwCRC = BlobCRC(blob, dwXOR);
  708. //Off you go.
  709. g_pNetwork->SendPacket(m_pPeer, blob, BLOBLEN(blob));
  710. //Keep in cache.
  711. header->dwCRC = dwXOR;
  712. }
  713. void CPacketController::SendFragmentBlob(BlobPacket_s *blob)
  714. {
  715. BlobHeader_s *header = &blob->header;
  716. header->dwSequence = GetNextSequence();
  717. header->dwFlags = BT_FRAGMENTS | BT_USES_CRC;
  718. header->dwCRC = 0;
  719. header->wRecID = g_pNetwork->GetServerID();
  720. header->wTime = GetElapsedTime();
  721. header->wTable = 0x01;
  722. DWORD dwXOR = GetSendXORVal(m_out.servercrc);
  723. header->dwCRC = BlobCRC(blob, dwXOR);
  724. //Off you go.
  725. g_pNetwork->SendPacket(m_pPeer, blob, BLOBLEN(blob));
  726. //Cache for later use.
  727. header->dwCRC = dwXOR;
  728. m_out.blobcache.push_back(blob);
  729. }
  730. //Sends all the queued fragments.
  731. void CPacketController::FlushFragments(void)
  732. {
  733. BlobPacket_s *blob = (BlobPacket_s *)new BYTE[MAX_BLOB_LEN];
  734. blob->header.wSize = 0;
  735. for (std::list<FragPacket_s *>::iterator it = m_out.fragqueue.begin(); it != m_out.fragqueue.end(); it++)
  736. {
  737. FragPacket_s *edible = *it;
  738. if ((blob->header.wSize + edible->header.wSize) < (MAX_BLOB_LEN - sizeof(BlobHeader_s)))
  739. {
  740. BYTE *dataPos = &blob->data[blob->header.wSize];
  741. WORD wSize = edible->header.wSize;
  742. memcpy(dataPos, edible, wSize);
  743. blob->header.wSize += wSize;
  744. }
  745. else
  746. {
  747. //This one is full, let's send it and make a new one.
  748. SendFragmentBlob(blob);
  749. blob = (BlobPacket_s *)new BYTE[MAX_BLOB_LEN];
  750. WORD wSize = blob->header.wSize = edible->header.wSize;
  751. memcpy(blob->data, edible, wSize);
  752. }
  753. delete[] edible;
  754. }
  755. SendFragmentBlob(blob);
  756. m_out.fragqueue.clear();
  757. }