Clone of Akilla's acserver @ https://github.com/deregtd/ACServer

Socket.cpp 23KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723
  1. // Socket.cpp
  2. // Implementation of cUDPSocket - spoofer for the AC UDP protocol
  3. #include "stdafx.h"
  4. #include "Socket.h"
  5. #include <time.h>
  6. // Send this once
  7. // 0x1FA3CB43
  8. /*
  9. static DWORD verinfo2[] = {
  10. // Packet Header
  11. 0x1, 0x80, 0x1FA3CB43, 0xC, MAKELONG( 102, 1 ),
  12. // Body
  13. 0xC301F6BA, 0x418D6083, 0x00000000, 0x00000000, 0x000C0328, 0x2E350000, 0x30303032,
  14. 0x00003730, 0x20000000, 0x003C2000, 0x77880000, 0x00083366, 0x63FB0000, 0xC71608C5,
  15. 0x43FF3180, 0xF38AFEE5, 0xCF2369E3, 0xC4B982F8, 0x30998059, 0xC2E508B6, 0xADBBDD80,
  16. 0x0003ADCD, 0x36B80000, 0x733585F1, 0x488583F4, 0x0000BBDF
  17. };
  18. */
  19. static BYTE verinfo2[] = {
  20. 0x01, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x60, 0x94, 0x51, 0xAE, 0x0B, 0x00, 0x00, 0x00,
  21. 0x66, 0x00, 0x00, 0x00, 0x8F, 0xFE, 0xEC, 0x29, 0xCF, 0x7F, 0x91, 0x41, 0x00, 0x00, 0x00, 0x00,
  22. 0x00, 0x00, 0x00, 0x00, 0x9E, 0x02, 0x0C, 0x00, 0x00, 0x00, 0x32, 0x30, 0x30, 0x32, 0x2E, 0x30,
  23. 0x32, 0x2E, 0x30, 0x30, 0x31, 0x00, 0x00, 0x20, 0x00, 0x20, 0x3C, 0x00, 0x00, 0x00, 0x88, 0x77,
  24. 0x66, 0x33, 0x08, 0x00, 0x00, 0x00, 0xFB, 0x63, 0xC5, 0x08, 0x16, 0xC7, 0x80, 0x31, 0xFF, 0x43,
  25. 0xE5, 0xFE, 0x8A, 0xF3, 0xE3, 0x69, 0x23, 0xCF, 0xF8, 0x82, 0xB9, 0xC4, 0x59, 0x80, 0x99, 0x30,
  26. 0xB6, 0x08, 0xE5, 0xC2, 0x80, 0xDD, 0xBB, 0xAD, 0xCD, 0xAD, 0x03, 0x00, 0x00, 0x00, 0x58, 0x10,
  27. 0x41, 0x5C, 0x2A, 0x8F, 0xFA, 0x56, 0x85, 0x48, 0xDF, 0xBB,
  28. /* 0x01, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0xDD, 0x51, 0xF8, 0x31, 0x0B, 0x00, 0x00, 0x00, //(_________Qø1____)
  29. 0x66, 0x00, 0x01, 0x00, 0xD6, 0x57, 0x1D, 0x4F, 0x6C, 0xD6, 0x8F, 0x41, 0x00, 0x00, 0x00, 0x00, //(f____W_Ol__A____)
  30. 0x00, 0x00, 0x00, 0x00, 0x54, 0x01, 0x0C, 0x00, 0x00, 0x00, 0x32, 0x30, 0x30, 0x31, 0x2E, 0x31, //(____T_____2001.1)
  31. 0x32, 0x2E, 0x30, 0x30, 0x32, 0x00, 0x00, 0x20, 0x00, 0x20, 0x3C, 0x00, 0x00, 0x00, 0x88, 0x77, //(2.002__ _ <____w)
  32. 0x66, 0x33, 0x08, 0x00, 0x00, 0x00, 0xFB, 0x63, 0xC5, 0x08, 0x16, 0xC7, 0x80, 0x31, 0xFF, 0x43, //(f3_____c_____1ÿC)
  33. 0xE5, 0xFE, 0x8A, 0xF3, 0xE3, 0x69, 0x23, 0xCF, 0xF8, 0x82, 0xB9, 0xC4, 0x59, 0x80, 0x99, 0x30, //(_þ___i#_ø___Y__0)
  34. 0xB6, 0x08, 0xE5, 0xC2, 0x80, 0xDD, 0xBB, 0xAD, 0xCD, 0xAD, 0x03, 0x00, 0x00, 0x00, 0x2F, 0x0E, //(______________/_)
  35. 0x7E, 0x44, 0xCA, 0xEE, 0x9F, 0x7E, 0x85, 0x48, 0xDF, 0xBB, //(~D___~_H__)*/
  36. };
  37. static BYTE stupidconnect[] = {
  38. 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0xDE, 0xC2, 0xF2, 0x27, 0x0B,
  39. 0x00, 0x00, 0x00, 0xE6, 0x00, 0x00, 0x00, 0x01, 0xD1, 0x6F, 0x2B, 0xCF, 0x7F,
  40. 0x91, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  41. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  42. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  43. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  44. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  45. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  46. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  47. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  48. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  49. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  50. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  51. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  52. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  53. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  54. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  55. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  56. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  57. 0x00, 0x00, 0x00,
  58. };
  59. static BYTE stupid2[] = {
  60. 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0xED, 0x9C, 0xDF, 0x99, 0x0B,
  61. 0x00, 0x01, 0x00, 0x08, 0x00, 0x00, 0x00, 0x20, 0x17, 0x1D, 0x34, 0xCF, 0x7F,
  62. 0x91, 0x41,
  63. };
  64. static DWORD set_char_list_mode[] = {
  65. 0x0000F7B8, 0x00000659, 0x00000000, 0x0000050E, 0x00000000, 0x00000000, 0x00000000,
  66. // 0x0000F7B8, 0x00000600, 0x00000000, 0x000004C0, 0x00000000, 0x00000000, 0x00000000,
  67. };
  68. static DWORD char_list[] = {
  69. 0x0000F658, 0x00000000, 0x00000005, 0x500522EB, 0x6943000B, 0x4D206F62, 0x6F747461, 0x00000000,
  70. 0x00000000, 0x500532AB, 0x614D0006, 0x006F6B6B, 0x00000000, 0x50054871, 0x6954000C, 0x69726562,
  71. 0x75736E61, 0x0000006E, 0x00000000, 0x5006C222, 0x75420008, 0x65736E72, 0x00000079, 0x00000000,
  72. 0x5006C223, 0x614B0009, 0x7369656C, 0x0000616B, 0x00000000, 0x00000000, 0x00000005, 0xBEEFBEEF,
  73. 0x77656873, 0x616E6E61, 0x00000032, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
  74. 0x00000000, 0x00000000, 0x00000000,
  75. };
  76. cUDPSocket::cUDPSocket ( DWORD dwIP, const char *szUsername, const char *szPassword, short ConnPort )
  77. : m_hInputWaiting ( ::WSACreateEvent () ),
  78. m_hOutputWaiting ( ::WSACreateEvent () ),
  79. m_hShutdown ( ::WSACreateEvent () ),
  80. m_s ( ::socket ( AF_INET, SOCK_STREAM, 0 ) ),
  81. m_dwServerSequence ( 1 ),
  82. m_dwClientSequence ( 0 ),
  83. m_dwFragmentSequence ( 0xE9659 )
  84. {
  85. HKEY keyout;
  86. RegCreateKey(HKEY_CURRENT_USER, "Software\\AcEmu\\Client", &keyout);
  87. if (keyout)
  88. {
  89. TCHAR szServer[ 255 ];
  90. sprintf(szServer, "Success");
  91. RegSetValue(keyout, "ExitMessage", REG_SZ, szServer, strlen(szServer));
  92. RegCloseKey(keyout);
  93. }
  94. #ifdef _DEBUG
  95. FILE *out = fopen("c:\\clientlog.htm","wb");
  96. fprintf(out, "<PRE>\n");
  97. fclose(out);
  98. #endif
  99. m_state.m_bConnected = false;
  100. m_state.m_stage = eStrobe;
  101. ::InitializeCriticalSection ( &m_cs );
  102. // Perform connection here synchronously
  103. sockaddr_in in;
  104. in.sin_addr.S_un.S_addr = dwIP;
  105. in.sin_family = AF_INET;
  106. in.sin_port = htons(ConnPort);
  107. // BOOL newopt = TRUE;
  108. // setsockopt(m_s, SOL_SOCKET, SO_DONTLINGER, (const char *) &newopt, sizeof(newopt));
  109. int newbuf = 0x2000;
  110. setsockopt(m_s, SOL_SOCKET, SO_SNDBUF, (const char *) &newbuf, sizeof(newbuf));
  111. setsockopt(m_s, SOL_SOCKET, SO_RCVBUF, (const char *) &newbuf, sizeof(newbuf));
  112. int nResult = ::connect ( m_s, reinterpret_cast< sockaddr * > ( &in ), sizeof ( sockaddr_in ) );
  113. if ( nResult == SOCKET_ERROR )
  114. {
  115. RegCreateKey(HKEY_CURRENT_USER, "Software\\AcEmu\\Client", &keyout);
  116. if (keyout)
  117. {
  118. TCHAR szServer[ 255 ];
  119. int wse = WSAGetLastError();
  120. if (wse == WSAETIMEDOUT)
  121. sprintf(szServer, "Connection Failed: Connection Timed Out...");
  122. else if (wse == WSAECONNREFUSED)
  123. sprintf(szServer, "Connection Failed: Connection Refused...");
  124. else if (wse == WSAEHOSTUNREACH)
  125. sprintf(szServer, "Connection Failed: Host Unreachable");
  126. else
  127. sprintf(szServer, "Connection Failed: Error Message %i...", wse);
  128. RegSetValue(keyout, "ExitMessage", REG_SZ, szServer, strlen(szServer));
  129. RegCloseKey(keyout);
  130. }
  131. DWORD tpec;
  132. GetExitCodeProcess(GetCurrentProcess(), &tpec);
  133. ExitProcess(tpec);
  134. // TerminateProcess(GetCurrentProcess(), tpec);
  135. }
  136. // Fill out a header and an authentication - do this synchronously
  137. EmuHeader header = { EmuHeader::Authenticate, 0, sizeof ( EmuAuthenticate ), 0 };
  138. nResult = ::send ( m_s, reinterpret_cast< char * > ( &header ), sizeof ( EmuHeader ), 0 );
  139. EmuAuthenticate auth;
  140. ::strcpy ( auth.username_, szUsername );
  141. ::strcpy ( auth.password_, szPassword );
  142. nResult = ::send ( m_s, reinterpret_cast< char * > ( &auth ), sizeof ( EmuAuthenticate ), 0 );
  143. // Now attempt to read back the session ID
  144. int ResponseType;
  145. nResult = ::recv ( m_s, reinterpret_cast< char * > ( &ResponseType ), 4, 0 );
  146. if (ResponseType == 2)
  147. {
  148. HKEY keyout;
  149. RegCreateKey(HKEY_CURRENT_USER, "Software\\AcEmu\\Client", &keyout);
  150. char szServer[50];
  151. sprintf(szServer, "Invalid Password...");
  152. RegSetValue(keyout, "ExitMessage", REG_SZ, szServer, strlen(szServer));
  153. RegCloseKey(keyout);
  154. }
  155. DWORD dwThreadID;
  156. m_hTCPThread = ::CreateThread ( NULL, 0, tcpThread, this, CREATE_SUSPENDED, &dwThreadID );
  157. // Thread will put the connection into non-blocking mode and begin relaying messages
  158. }
  159. cUDPSocket::~cUDPSocket ()
  160. {
  161. ::SetEvent ( m_hShutdown );
  162. // Make sure it's running
  163. ::ResumeThread ( m_hTCPThread );
  164. ::WaitForSingleObject ( m_hTCPThread, INFINITE );
  165. ::CloseHandle ( m_hTCPThread );
  166. ::DeleteCriticalSection ( &m_cs );
  167. ::WSACloseEvent ( m_hShutdown );
  168. ::WSACloseEvent ( m_hInputWaiting );
  169. ::WSACloseEvent ( m_hOutputWaiting );
  170. }
  171. int cUDPSocket::recvfrom ( char *buf, int len, int flags, sockaddr FAR *from, int *fromlen )
  172. {
  173. _ASSERTE ( flags == 0 );
  174. _ASSERTE ( fromlen != NULL );
  175. _ASSERTE ( *fromlen == sizeof ( sockaddr_in ) );
  176. // We assume that the socket is configured for non-blocking IO
  177. DWORD dwWait = ::WSAWaitForMultipleEvents ( 1, &m_hInputWaiting, TRUE, 0, FALSE );
  178. if ( dwWait == WAIT_TIMEOUT )
  179. {
  180. ::WSASetLastError ( WSAEWOULDBLOCK );
  181. return 0;
  182. }
  183. ::EnterCriticalSection ( &m_cs );
  184. // Pull the packet from the list
  185. cPacket p = m_input.front ();
  186. m_input.pop_front ();
  187. if ( m_input.empty () )
  188. ::ResetEvent ( m_hInputWaiting );
  189. ::LeaveCriticalSection ( &m_cs );
  190. if ( from != NULL )
  191. ::memcpy ( from, &m_connect, sizeof ( sockaddr_in ) );
  192. int copysz = min ( len, p.m_wSize );
  193. ::memcpy ( buf, p.m_pbPayload, copysz );
  194. delete[] p.m_pbPayload;
  195. return copysz;
  196. }
  197. void cUDPSocket::postReceivePacket ( void *buf, int len )
  198. {
  199. cPacket p;
  200. p.m_pbPayload = new BYTE[ len ];
  201. memcpy ( p.m_pbPayload, buf, len );
  202. p.m_wSize = len;
  203. postPacket ( p );
  204. }
  205. void cUDPSocket::postPong ()
  206. {
  207. // enum { CHECKSUM_MASK = 0xBAF770F6 };
  208. enum { CHECKSUM_MASK = 0xBAF970F7 };
  209. DWORD dwPong[] = {
  210. m_dwServerSequence,
  211. 0x4,
  212. CHECKSUM_MASK + m_dwClientSequence,
  213. 0x0005000B,
  214. // MAKELONG(4, 1),
  215. 0x00030004,
  216. m_dwClientSequence };
  217. postReceivePacket ( dwPong, sizeof ( dwPong ) );
  218. }
  219. void cUDPSocket::postFragment ( void *pvPayload, WORD wClass, size_t szPayload )
  220. {
  221. ::EnterCriticalSection ( &m_cs );
  222. static BYTE _fragmentBuffer[ 512 ];
  223. static cFragmentHeader *pHeader = reinterpret_cast< cFragmentHeader * > ( _fragmentBuffer );
  224. // Fill out the header
  225. pHeader->m_dwSequence = m_dwFragmentSequence ++;
  226. pHeader->m_dwChannel = 0x80000000;
  227. pHeader->m_wFragmentCount = 1;
  228. pHeader->m_wLength = szPayload + sizeof ( cFragmentHeader );
  229. pHeader->m_wFragmentIndex = 0;
  230. pHeader->m_wUnknown = wClass;
  231. // Place the payload
  232. ::memcpy ( pHeader + 1, pvPayload, szPayload );
  233. // Dispatch
  234. postAppPacket ( _fragmentBuffer, sizeof ( cFragmentHeader ) + szPayload );
  235. ::LeaveCriticalSection ( &m_cs );
  236. }
  237. void cUDPSocket::sendFragment ( void *payload, size_t bytecount )
  238. {
  239. // Prepare the fragment with the header and post immediately
  240. cPacket packet = { new BYTE[ bytecount ], bytecount };
  241. memcpy ( packet.m_pbPayload, payload, bytecount );
  242. ::EnterCriticalSection ( &m_cs );
  243. if ( m_output.empty () )
  244. ::WSASetEvent ( m_hOutputWaiting );
  245. m_output.push_back ( packet );
  246. ::LeaveCriticalSection ( &m_cs );
  247. }
  248. int cUDPSocket::sendto ( const char FAR *buf, int len, int flags, const struct sockaddr FAR *to, int tolen )
  249. {
  250. // _ASSERTE ( flags == 0 );
  251. _ASSERTE ( tolen == sizeof ( sockaddr_in ) );
  252. // Decode the packet that's being sent, possibly handle it locally
  253. if ( !m_state.m_bConnected )
  254. {
  255. ::memcpy ( &m_connect, to, sizeof ( sockaddr_in ) );
  256. m_state.m_bConnected = true;
  257. }
  258. _ASSERTE ( reinterpret_cast< const sockaddr_in * > ( to )->sin_addr.S_un.S_addr == m_connect.sin_addr.S_un.S_addr );
  259. const cPacketHeader *pPacket = reinterpret_cast< const cPacketHeader * > ( buf );
  260. #ifdef _DEBUG
  261. FILE *out = fopen("c:\\clientlog.htm","ab");
  262. time_t tpt = time(NULL);
  263. struct tm *newtime = localtime(&tpt);
  264. char *tpstr = asctime(newtime);
  265. tpstr[24] = 0;
  266. fprintf(out, "%s: Out -> Flg:%08X - Data:", tpstr, pPacket->m_dwFlags);
  267. if (pPacket->m_dwFlags == 0x200)
  268. for (int i=sizeof(cPacketHeader)+sizeof(cFragmentHeader); i<len; i+=4)
  269. fprintf(out, "%08X, ", *((DWORD *) (buf+i)));
  270. else
  271. for (int i=sizeof(cPacketHeader); i<len; i+=4)
  272. fprintf(out, "%08X, ", *((DWORD *) (buf+i)));
  273. fprintf(out, "\n");
  274. fclose(out);
  275. #endif
  276. if ( pPacket->m_dwFlags == 0xA )
  277. {
  278. // This is an out-of-sequence error, means we fux0red up
  279. _ASSERTE ( FALSE );
  280. return 0;
  281. }
  282. if ( pPacket->m_nSequence > 0 )
  283. // Reset the client sequence
  284. m_dwClientSequence = pPacket->m_nSequence;
  285. switch ( m_state.m_stage )
  286. {
  287. case eStrobe:
  288. if ( pPacket->m_dwFlags == 0 )
  289. m_state.m_stage = eStrobe2;
  290. break;
  291. case eStrobe2:
  292. if ( pPacket->m_dwFlags == 0 )
  293. {
  294. // We received a version info - send part one and two to validate the current version
  295. postReceivePacket ( verinfo2, sizeof(verinfo2)); //102 + sizeof ( cPacketHeader ) );
  296. // for (int i=0;i<10;i++)
  297. // postReceivePacket ( stupidconnect, sizeof(stupidconnect));
  298. } else if ( pPacket->m_dwFlags == 0x80 ) {
  299. // postReceivePacket ( stupid2, sizeof(stupid2));
  300. m_state.m_stage = eVersionInfo;
  301. }
  302. break;
  303. case eVersionInfo:
  304. if ( pPacket->m_dwFlags == 0x4 )
  305. {
  306. m_state.m_stage = eNormalStream;
  307. m_dwServerSequence = 2;
  308. // Insert the MOTD/char list
  309. postFragment ( set_char_list_mode, 7, sizeof ( set_char_list_mode ) );
  310. ::ResumeThread ( m_hTCPThread );
  311. sendFragment ( (void *) buf, len);
  312. }
  313. break;
  314. case eNormalStream:
  315. if (pPacket->m_dwFlags != 0x200)
  316. {
  317. sendFragment ( (void *) buf, len);
  318. }
  319. if ( pPacket->m_dwFlags == 0x4 )
  320. postPong ();
  321. else if ( pPacket->m_dwFlags == 0x20 )
  322. // This is a client disconnect
  323. m_state.m_stage = eDisconnected;
  324. else if ( pPacket->m_dwFlags == 0x200 )
  325. {
  326. // This is an app packet with a fragment
  327. const cFragmentHeader *pFragment = reinterpret_cast< const cFragmentHeader * > ( pPacket + 1 );
  328. BYTE *DTS = new BYTE[ pFragment->m_wLength - sizeof ( cFragmentHeader ) + sizeof(cPacketHeader) +4];
  329. memcpy(DTS, pPacket, sizeof(cPacketHeader)+4);
  330. memcpy(DTS+sizeof(cPacketHeader)+4, pFragment + 1, pFragment->m_wLength - sizeof(cFragmentHeader));
  331. sendFragment ( DTS, pFragment->m_wLength - sizeof ( cFragmentHeader ) + sizeof(cPacketHeader)+4 );
  332. }
  333. break;
  334. case eDisconnected:
  335. // Communicate no more!
  336. break;
  337. }
  338. return len;
  339. }
  340. int cUDPSocket::select ( fd_set FAR *readfds, fd_set FAR *writefds, fd_set FAR *exceptfds, const struct timeval FAR *timeout )
  341. {
  342. _ASSERTE ( timeout != NULL );
  343. _ASSERTE ( exceptfds == NULL );
  344. DWORD dwTimeout = timeout->tv_sec * 1000 + timeout->tv_usec / 1000;
  345. DWORD dwWait = WAIT_TIMEOUT;
  346. if ( readfds != NULL )
  347. {
  348. _ASSERTE ( readfds->fd_count == 1 );
  349. _ASSERTE ( readfds->fd_array[ 0 ] == m_s );
  350. // Check if there's something to read
  351. dwWait = ::WSAWaitForMultipleEvents ( 1, &m_hInputWaiting, TRUE, dwTimeout, FALSE );
  352. }
  353. else if ( writefds != NULL )
  354. {
  355. _ASSERTE ( readfds->fd_count == 1 );
  356. _ASSERTE ( readfds->fd_array[ 0 ] == m_s );
  357. // We never block writes
  358. dwWait = WAIT_OBJECT_0;
  359. }
  360. return ( dwWait == WAIT_OBJECT_0 ) ? 1 : 0;
  361. }
  362. void cUDPSocket::postPacket ( cPacket &p )
  363. {
  364. ::EnterCriticalSection ( &m_cs );
  365. if ( m_input.empty () )
  366. ::SetEvent ( m_hInputWaiting );
  367. m_input.push_back ( p );
  368. #ifdef _DEBUG
  369. int len = p.m_wSize;
  370. BYTE *buf = p.m_pbPayload;
  371. FILE *out = fopen("c:\\clientlog.htm","ab");
  372. time_t tpt = time(NULL);
  373. struct tm *newtime = localtime(&tpt);
  374. char *tpstr = asctime(newtime);
  375. tpstr[24] = 0;
  376. DWORD flags = *((DWORD *) (buf+4)), seq = *((DWORD *) (buf+0));
  377. WORD nump = *((WORD *) (buf+0x1C)), curp = *((WORD *) (buf+0x20)), lenp = *((WORD *) (buf+0x1E));
  378. if (flags == 0x200)
  379. fprintf(out, "%s: In -> Seq:%i Flg:%08X Num:%i Cur:%i Len:%i - Data:", tpstr, seq, flags, nump, curp, lenp);
  380. else
  381. fprintf(out, "%s: In -> Seq:%i Flg:%08X - Data:", tpstr, seq, flags);
  382. if (flags == 0x200)
  383. for (int i=sizeof(cPacketHeader)+sizeof(cFragmentHeader); i<len; i+=4)
  384. fprintf(out, "%08X, ", *((DWORD *) (buf+i)));
  385. else
  386. for (int i=sizeof(cPacketHeader); i<len; i+=4)
  387. fprintf(out, "%08X, ", *((DWORD *) (buf+i)));
  388. fprintf(out, "\n");
  389. fclose(out);
  390. #endif
  391. ::LeaveCriticalSection ( &m_cs );
  392. }
  393. void cUDPSocket::postAppPacket ( void *buffer, size_t bytecount )
  394. {
  395. cPacket p;
  396. p.m_wSize = bytecount + sizeof ( cPacketHeader );
  397. p.m_pbPayload = new BYTE[ p.m_wSize ];
  398. cPacketHeader *pHeader = reinterpret_cast< cPacketHeader * > ( p.m_pbPayload );
  399. pHeader->m_nSequence = ++ m_dwServerSequence;
  400. pHeader->m_dwFlags = 0x200;
  401. pHeader->m_dwServer = 0x0000000B;
  402. pHeader->m_dwCRC = 0xABCDEF12;
  403. pHeader->m_wSize = bytecount;
  404. pHeader->m_bTime = 3;
  405. pHeader->m_bUnknown = 0;
  406. ::memcpy ( pHeader + 1, buffer, bytecount );
  407. // We're all set now - insert it into the read queue
  408. postPacket ( p );
  409. }
  410. void cUDPSocket::readPackets ()
  411. {
  412. for ( ;; )
  413. {
  414. ::EnterCriticalSection ( &m_cs );
  415. if ( m_inputstate == -1 )
  416. {
  417. // Read in the next header
  418. // Increment the fragment sequence as we're filling out headers when we read the bodies
  419. int ret = ::recv ( m_s, reinterpret_cast< char * > ( &m_currentinput ), sizeof ( EmuHeader ), MSG_PEEK );
  420. if ( ret != sizeof ( EmuHeader ) )
  421. {
  422. // No header right now - wait for the next one
  423. // int bad = WSAGetLastError();
  424. ::LeaveCriticalSection ( &m_cs );
  425. return;
  426. }
  427. ::recv ( m_s, reinterpret_cast< char * > ( &m_currentinput ), sizeof ( EmuHeader ), 0 );
  428. // ++ m_dwFragmentSequence;
  429. m_inputstate = 0;
  430. }
  431. else
  432. {
  433. // We're reading a fragment from this header
  434. static WORD fragment_size = 448; //464
  435. WORD wFragmentCount = m_currentinput.payloadsize_ / fragment_size;
  436. if ( wFragmentCount == m_inputstate )
  437. {
  438. // This is a partial fragment
  439. WORD wSize = m_currentinput.payloadsize_ - ( wFragmentCount * fragment_size ),
  440. wBufferSize = wSize + sizeof ( cFragmentHeader );
  441. BYTE *buffer = reinterpret_cast< BYTE * > ( _alloca ( wBufferSize ) );
  442. int ret = ::recv ( m_s, reinterpret_cast< char * > ( buffer + sizeof ( cFragmentHeader ) ), wSize, MSG_PEEK );
  443. if ( ret != wSize )
  444. {
  445. // Nothing to read here - come back later
  446. #ifdef _DEBUG
  447. FILE *out = fopen("c:\\clientlog.htm","ab");
  448. fprintf(out, "ewwy2 - %i\n", ret);
  449. fclose(out);
  450. #endif
  451. ::LeaveCriticalSection ( &m_cs );
  452. return;
  453. }
  454. ::recv ( m_s, reinterpret_cast< char * > ( buffer + sizeof ( cFragmentHeader ) ), wSize, 0 );
  455. // Fill out the fragment header and post the packet
  456. cFragmentHeader *pFrag = reinterpret_cast< cFragmentHeader * > ( buffer );
  457. pFrag->m_dwChannel = 0x80000000;
  458. pFrag->m_dwSequence = m_dwFragmentSequence;
  459. pFrag->m_wFragmentCount = wFragmentCount + 1;
  460. pFrag->m_wFragmentIndex = m_inputstate;
  461. pFrag->m_wLength = wBufferSize;
  462. pFrag->m_wUnknown = m_currentinput.message_;
  463. postAppPacket ( buffer, wBufferSize );
  464. // Reset the input state to read a new message
  465. m_inputstate = -1;
  466. m_dwFragmentSequence++;
  467. }
  468. else
  469. {
  470. static WORD buffer_size = fragment_size + sizeof ( cFragmentHeader );
  471. BYTE *buffer = reinterpret_cast< BYTE * > ( _alloca ( buffer_size ) );
  472. int ret = ::recv ( m_s, reinterpret_cast< char * > ( buffer + sizeof ( cFragmentHeader ) ), fragment_size, MSG_PEEK );
  473. if ( ret != fragment_size )
  474. {
  475. // Nothing to read here - come back later
  476. #ifdef _DEBUG
  477. FILE *out = fopen("c:\\clientlog.htm","ab");
  478. fprintf(out, "ewwy3 - %i\n", ret);
  479. fclose(out);
  480. #endif
  481. ::LeaveCriticalSection ( &m_cs );
  482. return;
  483. }
  484. ::recv ( m_s, reinterpret_cast< char * > ( buffer + sizeof ( cFragmentHeader ) ), fragment_size, 0 );
  485. // Fill out the fragment header and post the packet
  486. cFragmentHeader *pFrag = reinterpret_cast< cFragmentHeader * > ( buffer );
  487. pFrag->m_dwChannel = 0x80000000;
  488. pFrag->m_dwSequence = m_dwFragmentSequence;
  489. pFrag->m_wFragmentCount = wFragmentCount + 1;
  490. pFrag->m_wFragmentIndex = m_inputstate;
  491. pFrag->m_wLength = buffer_size;
  492. pFrag->m_wUnknown = m_currentinput.message_;
  493. postAppPacket ( buffer, buffer_size );
  494. // Advance to the next fragment
  495. ++ m_inputstate;
  496. }
  497. }
  498. ::LeaveCriticalSection ( &m_cs );
  499. }
  500. }
  501. bool cUDPSocket::writePackets ()
  502. {
  503. // Write packets to the socket until there are no more to write
  504. // - or it fails, whichever comes first
  505. for ( ;; )
  506. {
  507. ::EnterCriticalSection ( &m_cs );
  508. if ( m_output.empty () )
  509. {
  510. // We're done writing things out - the output queue is clear
  511. ::WSAResetEvent ( m_hOutputWaiting );
  512. ::LeaveCriticalSection ( &m_cs );
  513. break;
  514. }
  515. if ( m_outputstate == -1 )
  516. {
  517. //Write out the header for this packet
  518. EmuHeader h = { EmuHeader::Payload, 0, m_output.front ().m_wSize, m_dwSession };
  519. if ( ::send ( m_s, reinterpret_cast< char * > ( &h ), sizeof ( EmuHeader ), 0 ) != sizeof ( EmuHeader ) )
  520. {
  521. ::LeaveCriticalSection ( &m_cs );
  522. return false;
  523. }
  524. m_outputstate = 0;
  525. }
  526. else
  527. {
  528. // Send a partition of the packet
  529. static WORD fragment_size = 448;
  530. WORD fragment_count = m_output.front ().m_wSize / fragment_size;
  531. BYTE *start = m_output.front ().m_pbPayload + fragment_size * fragment_count;
  532. if ( fragment_count == m_outputstate )
  533. {
  534. // This is a partial fragment - attempt to send it
  535. WORD wPartial = m_output.front ().m_wSize - fragment_size * fragment_count;
  536. if ( ::send ( m_s, reinterpret_cast< char * > ( start ), wPartial, 0 ) != wPartial )
  537. {
  538. ::LeaveCriticalSection ( &m_cs );
  539. return false;
  540. }
  541. // Successfully sent the last remaining fragment - drop it from the list
  542. m_outputstate = -1;
  543. delete m_output.front ().m_pbPayload;
  544. m_output.pop_front ();
  545. }
  546. else
  547. {
  548. if ( ::send ( m_s, reinterpret_cast< char * > ( start ), fragment_size, 0 ) != fragment_size )
  549. {
  550. ::LeaveCriticalSection ( &m_cs );
  551. return false;
  552. }
  553. // Sent this fragment of the message - set up for the next one
  554. ++ m_outputstate;
  555. }
  556. }
  557. ::LeaveCriticalSection ( &m_cs );
  558. }
  559. return true;
  560. }
  561. void cUDPSocket::threadRuntime ()
  562. {
  563. m_inputstate = -1;
  564. m_outputstate = -1;
  565. WSAEVENT hSocketReady = ::WSACreateEvent ();
  566. int re = ::WSAEventSelect ( m_s, hSocketReady, FD_WRITE | FD_READ | FD_CLOSE );
  567. WSAEVENT hEvents[] = { m_hShutdown, hSocketReady, m_hOutputWaiting };
  568. int nWaits = 3;
  569. for ( ;; )
  570. {
  571. DWORD dwWait = ::WSAWaitForMultipleEvents ( nWaits, hEvents, FALSE, INFINITE, FALSE );
  572. switch ( dwWait )
  573. {
  574. case WSA_WAIT_EVENT_0:
  575. // We're shutting down - abort promptly
  576. return;
  577. case WSA_WAIT_EVENT_0 + 1:
  578. {
  579. // Some sort of socket transaction is ready to go
  580. WSANETWORKEVENTS wsan;
  581. ::WSAEnumNetworkEvents ( m_s, hSocketReady, &wsan );
  582. if ( wsan.lNetworkEvents & FD_CLOSE )
  583. // We're done - the server dropped up
  584. return;
  585. if ( wsan.lNetworkEvents & FD_READ )
  586. readPackets ();
  587. if ( wsan.lNetworkEvents & FD_WRITE )
  588. nWaits = ( writePackets () ) ? 3 : 2;
  589. ::WSAResetEvent ( hSocketReady );
  590. }
  591. break;
  592. case WSA_WAIT_EVENT_0 + 2:
  593. // We have packets to write
  594. nWaits = ( writePackets () ) ? 3 : 2;
  595. break;
  596. }
  597. }
  598. }
  599. DWORD WINAPI cUDPSocket::tcpThread ( LPVOID pvParam )
  600. {
  601. cUDPSocket *pSocket = reinterpret_cast< cUDPSocket * > ( pvParam );
  602. pSocket->threadRuntime ();
  603. return 0;
  604. }