Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

3393 lines
96 KiB

  1. // =================================================================
  2. //
  3. // Direct Play Network Methods
  4. //
  5. // Functions to manage communications over a network.
  6. //
  7. //
  8. // =================================================================
  9. #ifndef WIN32_LEAN_AND_MEAN
  10. #define WIN32_LEAN_AND_MEAN
  11. #endif
  12. #include <windows.h>
  13. #include <windowsx.h>
  14. #include <winsock.h>
  15. #ifndef _MT
  16. #define _MT
  17. #endif
  18. #include <process.h>
  19. #include <string.h>
  20. #include "dpspimp.h"
  21. #include "logit.h"
  22. #define lmalloc(a) LocalAlloc(LMEM_FIXED, (a))
  23. #define lfree(a) LocalFree((HLOCAL)(a))
  24. CImpIDP_SP *pDirectPlayObject = NULL; // We only allow one object
  25. // to be created currently - see below.
  26. HANDLE hOnlyOneTCP = NULL;
  27. HANDLE hOnlyOneIPX = NULL;
  28. extern "C" VOID InternalCleanUp()
  29. {
  30. if (pDirectPlayObject)
  31. pDirectPlayObject->Close(DPLAY_CLOSE_INTERNAL);
  32. pDirectPlayObject = NULL;
  33. }
  34. extern BOOL CreateQueue(DWORD dwElements, DWORD dwmaxMsg, DWORD dwMaxPlayers);
  35. extern BOOL DeleteQueue();
  36. GUID DPLAY_NETWORK_TCP = { /* 8cab4650-b1b6-11ce-920c-00aa006c4972 */
  37. 0x8cab4650,
  38. 0xb1b6,
  39. 0x11ce,
  40. {0x92, 0x0c, 0x00, 0xaa, 0x00, 0x6c, 0x49, 0x72}
  41. };
  42. GUID DPLAY_NETWORK_IPX = { /* 8cab4651-b1b6-11ce-920c-00aa006c4972 */
  43. 0x8cab4651,
  44. 0xb1b6,
  45. 0x11ce,
  46. {0x92, 0x0c, 0x00, 0xaa, 0x00, 0x6c, 0x49, 0x72}
  47. };
  48. GUID NULL_GUID = {
  49. 0x00000000,
  50. 0x0000,
  51. 0x0000,
  52. {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
  53. };
  54. extern BOOL bNetIsUp;
  55. HRESULT CImpIDP_SP::Initialize(LPGUID lpguid)
  56. {
  57. TSHELL_INFO(TEXT("Already Initialized."));
  58. return(DPERR_ALREADYINITIALIZED);
  59. }
  60. void *CImpIDP_SP::operator new( size_t size )
  61. {
  62. return(LocalAlloc(LMEM_FIXED, size));
  63. }
  64. void CImpIDP_SP::operator delete( void *ptr )
  65. {
  66. LocalFree((HLOCAL)ptr);
  67. }
  68. // ----------------------------------------------------------
  69. // CImpIDP_SP constructor - create a new DCO object
  70. // along with a queue of receive buffers.
  71. // ----------------------------------------------------------
  72. USHORT CImpIDP_SP::NextSequence()
  73. {
  74. m_usSeq %= 51001;
  75. m_usSeq++;
  76. return(m_usSeq);
  77. }
  78. USHORT CImpIDP_SP::UpdateSequence(USHORT us)
  79. {
  80. if (us > m_usSeq)
  81. m_usSeq = us;
  82. return(NextSequence());
  83. }
  84. CImpIDP_SP::CImpIDP_SP()
  85. {
  86. m_bConnected = FALSE;
  87. m_bPlayer0 = FALSE;
  88. m_dwPingSent = 0;
  89. m_hBlockingEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
  90. m_hEnumBlkEventMain = CreateEvent(NULL, TRUE, FALSE, NULL);
  91. m_hEnumBlkEventRead = CreateEvent(NULL, TRUE, FALSE, NULL);
  92. m_hPlayerBlkEventMain = CreateEvent(NULL, TRUE, FALSE, NULL);
  93. m_hPlayerBlkEventRead = CreateEvent(NULL, TRUE, FALSE, NULL);
  94. m_dwNextPlayer = 1;
  95. m_bEnablePlayerAdd = TRUE;
  96. m_fpEnumSessions = NULL;
  97. m_bRunEnumReceiveLoop = FALSE;
  98. m_fpEnumPlayers = NULL;
  99. m_lpvSessionContext = NULL;
  100. m_lpvPlayersContext = NULL;
  101. memset( m_aPlayer, 0x00, sizeof(PLAYER_RECORD) * MAX_PLAYERS);
  102. m_iPlayerIndex = -1;
  103. memset(&m_dpDesc, 0x00, sizeof(DPSESSIONDESC));
  104. // Initialize ref count
  105. m_refCount = 1;
  106. InitializeCriticalSection( &m_critSection );
  107. InitializeCriticalSection( &m_critSectionPlayer );
  108. InitializeCriticalSection( &m_critSectionParanoia );
  109. memset(&m_dpcaps, 0x00, sizeof(DPCAPS));
  110. m_dpcaps.dwSize = sizeof(DPCAPS);
  111. m_dpcaps.dwFlags = 0;
  112. m_dpcaps.dwMaxQueueSize = 64;
  113. m_dpcaps.dwMaxPlayers = MAX_PLAYERS;
  114. m_dpcaps.dwHundredBaud = 100000;
  115. m_hNewPlayerEvent = NULL;
  116. m_ppSessionArray = 0;
  117. m_dwSessionPrev = 0;
  118. m_dwSessionAlloc = 0;
  119. m_af = 0;
  120. m_remoteaddrlen = 0;
  121. m_chComputerName[0] = '\0';
  122. m_bShutDown = FALSE;
  123. m_hNSThread = NULL;
  124. m_dwNSId = 0;
  125. m_usGamePort = 0;
  126. m_usGameCookie = 0;
  127. m_hClientThread = NULL;
  128. m_dwClientId = 0;
  129. m_hEnumThread = NULL;
  130. m_dwEnumId = 0;
  131. m_ServerSocket = INVALID_SOCKET;
  132. m_bClientSocket = FALSE; m_EnumSocket = INVALID_SOCKET;
  133. m_bEnumSocket = FALSE; m_ClientSocket = INVALID_SOCKET;
  134. m_dwSession = 0;
  135. memset( (LPVOID) &m_NSSockAddr, 0x00, sizeof(SOCKADDR));
  136. m_SessionAddrLen = 0;
  137. memset( (LPVOID) &m_GameSockAddr, 0x00, sizeof(SOCKADDR));
  138. m_usSeq = 1;
  139. m_usSeqSys = 0;
  140. m_aMachineAddr = NULL;
  141. m_cMachines = 0;
  142. m_dwUnique = 1;
  143. memset( (LPVOID) &m_spmsgEnum, 0x00, sizeof(SPMSG_ENUM));
  144. memset( (LPVOID) &m_spmsgAddPlayer, 0x00, sizeof(SPMSG_ADDPLAYER));
  145. }
  146. DWORD WINAPI StartClientThreadProc(LPVOID lpvParam)
  147. {
  148. CImpIDP_SP *pIDP = (CImpIDP_SP *) lpvParam;
  149. return(pIDP->ClientThreadProc());
  150. }
  151. CImpIDP_SP *CImpIDP_SP::NewCImpIDP_SP(int af)
  152. {
  153. CImpIDP_SP *pImp = NULL;
  154. HANDLE hEvent = NULL;
  155. if (InitializeWinSock() != 0)
  156. {
  157. TSHELL_INFO( TEXT("DPWsock failed initializing winsock."));
  158. return(NULL);
  159. }
  160. if (!CreateQueue(64, MAX_MSG, MAX_PLAYERS))
  161. {
  162. TSHELL_INFO(TEXT("Couldn't initialize queue."));
  163. return(NULL);
  164. }
  165. pImp = new CImpIDP_SP;
  166. if (!pImp)
  167. return(NULL);
  168. pImp->m_dpcaps.dwMaxBufferSize = 512;
  169. pImp->m_af = af;
  170. return(pImp);
  171. }
  172. // ----------------------------------------------------------
  173. // CreateNewDirectPlay - DCO object creation entry point
  174. // called by the DCO interface functions to create a new
  175. // DCO object.
  176. // ----------------------------------------------------------
  177. IDirectPlaySP * _cdecl CreateNewDirectPlay( LPGUID lpGuid )
  178. {
  179. int af;
  180. //
  181. // One object at a time, please.
  182. //
  183. if (pDirectPlayObject != NULL)
  184. {
  185. TSHELL_INFO(TEXT("We already have an object."));
  186. return(NULL);
  187. }
  188. if (IsEqualGUID((REFGUID) DPLAY_NETWORK_TCP, (REFGUID) *lpGuid))
  189. af = AF_INET;
  190. else if (IsEqualGUID((REFGUID) DPLAY_NETWORK_IPX, (REFGUID) *lpGuid))
  191. af = AF_IPX;
  192. else
  193. return(NULL);
  194. pDirectPlayObject = CImpIDP_SP::NewCImpIDP_SP(af);
  195. if (!pDirectPlayObject)
  196. return(NULL);
  197. else
  198. return(pDirectPlayObject);
  199. }
  200. // Begin: IUnknown interface implementation
  201. HRESULT CImpIDP_SP::QueryInterface(
  202. REFIID iid,
  203. LPVOID *ppvObj
  204. )
  205. {
  206. HRESULT retVal = DPERR_GENERIC;
  207. //
  208. // BUGBUG
  209. //
  210. if (ppvObj && ! IsBadWritePtr(ppvObj, 4))
  211. {
  212. AddRef();
  213. *ppvObj = this;
  214. return(DP_OK);
  215. }
  216. else
  217. return(DPERR_INVALIDPARAM);
  218. }
  219. ULONG CImpIDP_SP::AddRef( void)
  220. {
  221. ULONG newRefCount;
  222. m_refCount++;
  223. newRefCount = m_refCount;
  224. DBG_INFO((DBGARG, TEXT("newRefCount = %lu"), newRefCount));
  225. return( newRefCount );
  226. }
  227. ULONG CImpIDP_SP::Release( void )
  228. {
  229. ULONG newRefCount;
  230. m_refCount--;
  231. newRefCount = m_refCount;
  232. if (newRefCount == 0)
  233. {
  234. Close(DPLAY_CLOSE_INTERNAL);
  235. delete this;
  236. }
  237. DBG_INFO((DBGARG, TEXT("newRefCount = %lu"), newRefCount));
  238. return( newRefCount );
  239. }
  240. // End : IUnknown interface implementation
  241. // ----------------------------------------------------------
  242. // CImpDirectPlay destructor -
  243. // ----------------------------------------------------------
  244. CImpIDP_SP::~CImpIDP_SP()
  245. {
  246. DWORD ii;
  247. if (m_ppSessionArray)
  248. {
  249. for (ii = 0; ii < m_dwSessionPrev; ii++)
  250. lfree(m_ppSessionArray[ii]);
  251. lfree(m_ppSessionArray);
  252. m_dwSessionPrev = 0;
  253. m_dwSessionAlloc = 0;
  254. }
  255. if (m_aMachineAddr)
  256. lfree(m_aMachineAddr);
  257. DeleteCriticalSection( &m_critSection );
  258. DeleteCriticalSection( &m_critSectionPlayer );
  259. DeleteCriticalSection( &m_critSectionParanoia );
  260. CloseHandle(m_hBlockingEvent);
  261. CloseHandle(m_hEnumBlkEventMain);
  262. CloseHandle(m_hEnumBlkEventRead);
  263. CloseHandle(m_hPlayerBlkEventMain);
  264. CloseHandle(m_hPlayerBlkEventRead);
  265. ShutdownWinSock();
  266. pDirectPlayObject = NULL;
  267. DeleteQueue();
  268. }
  269. void CImpIDP_SP::EnumDataLock( void )
  270. {
  271. EnterCriticalSection( &m_critSection );
  272. }
  273. void CImpIDP_SP::EnumDataUnlock( void )
  274. {
  275. LeaveCriticalSection( &m_critSection );
  276. }
  277. void CImpIDP_SP::PlayerDataLock( void )
  278. {
  279. EnterCriticalSection( &m_critSectionPlayer );
  280. }
  281. void CImpIDP_SP::PlayerDataUnlock( void )
  282. {
  283. LeaveCriticalSection( &m_critSectionPlayer );
  284. }
  285. void CImpIDP_SP::ParanoiaLock( void )
  286. {
  287. EnterCriticalSection( &m_critSectionParanoia );
  288. }
  289. void CImpIDP_SP::ParanoiaUnlock( void )
  290. {
  291. LeaveCriticalSection( &m_critSectionParanoia );
  292. }
  293. DWORD WINAPI StartServerThreadProc(LPVOID lpvParam)
  294. {
  295. CImpIDP_SP *pIDP = (CImpIDP_SP *) lpvParam;
  296. return(pIDP->ServerThreadProc());
  297. }
  298. BOOL CImpIDP_SP::GetSockAddress(SOCKADDR *pSAddr,
  299. LPINT pSAddrLen,
  300. USHORT usPort,
  301. SOCKET *pSocket,
  302. BOOL bBroadcast
  303. )
  304. {
  305. PSOCKADDR_IN pSockAddrIn;
  306. PSOCKADDR_IPX pSockAddrIPX;
  307. UINT uErr;
  308. memset(pSAddr, 0, sizeof(SOCKADDR));
  309. pSAddr->sa_family = (USHORT)m_af;
  310. switch (m_af)
  311. {
  312. case AF_INET:
  313. pSockAddrIn = (PSOCKADDR_IN) pSAddr;
  314. pSockAddrIn->sin_port = htons(usPort);
  315. if (bBroadcast)
  316. pSockAddrIn->sin_addr.s_addr = INADDR_BROADCAST;
  317. break;
  318. case AF_IPX:
  319. pSockAddrIPX = (PSOCKADDR_IPX) pSAddr;
  320. pSockAddrIPX->sa_socket = htons(usPort);
  321. if (bBroadcast)
  322. memset(&pSockAddrIPX->sa_nodenum, 0xff, sizeof(pSockAddrIPX->sa_nodenum));
  323. break;
  324. default:
  325. return (FALSE);
  326. }
  327. if (!bBroadcast)
  328. {
  329. *pSAddrLen = sizeof(SOCKADDR);
  330. if ((uErr = InitializeSocket(m_af, pSAddr, pSAddrLen, pSocket)) != 0)
  331. {
  332. DBG_INFO((DBGARG, TEXT("Init Socket Failed %8x"), uErr));
  333. return(FALSE);
  334. }
  335. }
  336. return(TRUE);
  337. }
  338. DWORD CImpIDP_SP::ClientThreadProc()
  339. {
  340. HRESULT hr = DP_OK;
  341. char chRBuffer[2048];
  342. SOCKADDR SockAddr;
  343. UINT BufferLen;
  344. INT SockAddrLen;
  345. BOOL bNoConnection = TRUE;
  346. DPHDR *pHdr = (DPHDR *) chRBuffer;
  347. UINT err;
  348. const char ttl = 32;
  349. TSHELL_INFO(TEXT("Client Thread starts."));
  350. memset(&SockAddr, 0, sizeof(SOCKADDR));
  351. SockAddr.sa_family = (USHORT)m_af;
  352. if (m_fpEnumSessions == NULL && m_usGamePort == 0)
  353. return(0);
  354. SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL);
  355. if (m_usGamePort)
  356. {
  357. if (GetSockAddress(&SockAddr, &SockAddrLen, m_usGamePort, (SOCKET *)&m_ClientSocket, FALSE))
  358. {
  359. m_bClientSocket = TRUE;
  360. }
  361. else
  362. {
  363. TSHELL_INFO(TEXT("Thread Exit."));
  364. SetEvent(m_hBlockingEvent);
  365. return(0);
  366. }
  367. SetEvent(m_hBlockingEvent);
  368. TSHELL_INFO(TEXT("Client Thread with game port looping."));
  369. while (!m_bShutDown)
  370. {
  371. //
  372. // Do a blocking receive from anyone. Once we return from here,
  373. // we could either have a real request in our buffer, or our
  374. // socket's been closed in which case we'll have an error in err.
  375. //
  376. BufferLen = sizeof(chRBuffer);
  377. if (!(ReceiveAny(m_ClientSocket, &SockAddr, &SockAddrLen, chRBuffer, &BufferLen)))
  378. {
  379. // TSHELL_INFO(TEXT("Got a message in Client Game thread."));
  380. if ( pHdr->dwConnect1 == DPSYS_KYRA
  381. && pHdr->dwConnect2 == DPSYS_HALL)
  382. {
  383. UpdateSequence(pHdr->usSeq);
  384. // TSHELL_INFO(TEXT("Handle connect message."));
  385. HandleConnect(pHdr, (DWORD) BufferLen, &SockAddr, SockAddrLen);
  386. }
  387. else if ( pHdr->usCookie == DPSYS_USER
  388. || pHdr->usCookie == DPSYS_SYS
  389. || pHdr->usCookie == DPSYS_HIGH)
  390. {
  391. UpdateSequence(pHdr->usSeq);
  392. TSHELL_INFO(TEXT("Handle server message Client Thread."));
  393. HandleMessage(pHdr, (DWORD) BufferLen, &SockAddr, SockAddrLen);
  394. }
  395. }
  396. }
  397. ParanoiaLock();
  398. if (m_ClientSocket != INVALID_SOCKET)
  399. CloseSocket(m_ClientSocket, 2);
  400. m_ClientSocket = INVALID_SOCKET;
  401. TSHELL_INFO(TEXT("Client Thread Exit."));
  402. ParanoiaUnlock();
  403. }
  404. else
  405. {
  406. if ((err = InitializeSocket(m_af, NULL, NULL, (SOCKET *) &m_EnumSocket)) != 0)
  407. {
  408. DBG_INFO((DBGARG, TEXT("THREAD EXIT on ENUM INIT %d."), err));
  409. SetEvent(m_hBlockingEvent);
  410. return(0);
  411. }
  412. else
  413. m_bEnumSocket = TRUE;
  414. // if (setsockopt(m_EnumSocket, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl)))
  415. // {
  416. // DBG_INFO((DBGARG, TEXT("SetSocket Option for multicast failed. %d"), GetLastError()));
  417. // }
  418. SetEvent(m_hBlockingEvent);
  419. // TSHELL_INFO(TEXT("Looping in EnumThread."));
  420. SockAddrLen = sizeof(SockAddr);
  421. getsockname(m_EnumSocket, &SockAddr, &SockAddrLen);
  422. while (m_bRunEnumReceiveLoop)
  423. {
  424. BufferLen = sizeof(chRBuffer);
  425. SockAddrLen = sizeof(SockAddr);
  426. if (!(ReceiveAny(m_EnumSocket, &SockAddr, &SockAddrLen, chRBuffer, &BufferLen)))
  427. {
  428. // TSHELL_INFO(TEXT("Message in EnumThread."));
  429. if ( pHdr->dwConnect1 == DPSYS_KYRA
  430. && pHdr->dwConnect2 == DPSYS_HALL)
  431. {
  432. UpdateSequence(pHdr->usSeq);
  433. // TSHELL_INFO(TEXT("Handle connect message."));
  434. HandleConnect((LPVOID) pHdr, (DWORD) BufferLen, &SockAddr, SockAddrLen);
  435. #ifdef DEBUG
  436. if (!m_fpEnumSessions)
  437. TSHELL_INFO(TEXT("m_fpEnumSessions is NULL."));
  438. #endif
  439. }
  440. else if ( pHdr->usCookie == DPSYS_SYS
  441. && pHdr->usCount == SIZE_ADDPLAYER
  442. && ((SPMSG_GENERIC *)pHdr)->sMsg.dwType == DPSYS_ENUMPLAYERRESP)
  443. {
  444. HandleMessage(pHdr, (DWORD) BufferLen, &SockAddr, SockAddrLen);
  445. }
  446. else
  447. {
  448. TSHELL_INFO(TEXT("Enum function got an illegal non-connect message."));
  449. DBG_INFO((DBGARG, TEXT("Non-connect was %8x %8x Length %d"),
  450. pHdr->dwConnect1,
  451. pHdr->dwConnect2,
  452. BufferLen));
  453. }
  454. }
  455. }
  456. EnumDataLock();
  457. if (m_EnumSocket != INVALID_SOCKET)
  458. CloseSocket(m_EnumSocket, 2);
  459. m_EnumSocket = INVALID_SOCKET;
  460. EnumDataUnlock();
  461. TSHELL_INFO(TEXT("Enum Thread Exit."));
  462. }
  463. return(hr);
  464. }
  465. DWORD CImpIDP_SP::ServerThreadProc()
  466. {
  467. SOCKADDR SockAddr;
  468. HRESULT hr = DP_OK;
  469. DWORD dw;
  470. UINT BufferLen;
  471. INT SockAddrLen;
  472. char chRBuffer[2048];
  473. DWORD dwTicks;
  474. DWORD dwCountIt;
  475. DWORD ii;
  476. LPBYTE lpByte;
  477. DPHDR *pHdr = (DPHDR *) chRBuffer;
  478. UINT err;
  479. TSHELL_INFO(TEXT("Server Thread Starts."));
  480. m_bPlayer0 = FALSE;
  481. memset(&SockAddr, 0, sizeof(SOCKADDR));
  482. SockAddr.sa_family = (USHORT)m_af;
  483. if (! GetSockAddress(&SockAddr, &SockAddrLen, DPNS_PORT, (SOCKET *) &m_ServerSocket, FALSE))
  484. {
  485. hr = DPERR_GENERIC;
  486. m_hNSThread = NULL;
  487. SetEvent(m_hBlockingEvent);
  488. goto abort;
  489. }
  490. //
  491. // Now let's initialize our SDB structure for use in the future.
  492. // This includes stuff like computer name, address length, etc.
  493. //
  494. SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL);
  495. m_remoteaddrlen = sizeof(SOCKADDR);
  496. dw = sizeof(m_chComputerName);
  497. GetComputerName(m_chComputerName, &dw);
  498. SockAddrLen = m_remoteaddrlen;
  499. m_bPlayer0 = TRUE;
  500. lpByte = (LPBYTE) &m_dpDesc;
  501. dwCountIt = 0;
  502. for (ii = 0; ii < sizeof(m_dpDesc); ii++)
  503. dwCountIt += lpByte[ii] & 0x000000ff;
  504. dwTicks = GetCurrentTime();
  505. m_usGamePort = (USHORT) (2000 + (((dwCountIt % 75) + 1) * ((dwTicks % 75) + 1)));
  506. m_usGameCookie = (USHORT) (((dwCountIt % 235) + 1) * ((dwTicks % 235) + 1));
  507. GetSockAddress(&m_GameSockAddr, NULL, m_usGamePort, NULL, TRUE);
  508. // Let create function go ...
  509. //
  510. SetEvent(m_hBlockingEvent);
  511. TSHELL_INFO(TEXT("Server Thread Looping."));
  512. while (!m_bShutDown)
  513. {
  514. //
  515. // Do a blocking receive from anyone. Once we return from here,
  516. // we could either have a real request in our buffer, or our
  517. // socket's been closed in which case we'll have an error in err.
  518. //
  519. BufferLen = sizeof(chRBuffer);
  520. if (!(err = ReceiveAny(m_ServerSocket, &SockAddr, &SockAddrLen, chRBuffer, &BufferLen)))
  521. {
  522. TSHELL_INFO(TEXT("Got a NS message."));
  523. if ( pHdr->dwConnect1 == DPSYS_KYRA
  524. && pHdr->dwConnect2 == DPSYS_HALL)
  525. {
  526. UpdateSequence(pHdr->usSeq);
  527. TSHELL_INFO(TEXT("Handle connect message."));
  528. HandleConnect(pHdr, (DWORD) BufferLen, &SockAddr, SockAddrLen);
  529. }
  530. else if ( pHdr->usCookie == DPSYS_USER
  531. || pHdr->usCookie == DPSYS_SYS
  532. || pHdr->usCookie == DPSYS_HIGH)
  533. {
  534. UpdateSequence(pHdr->usSeq);
  535. TSHELL_INFO(TEXT("Handle server message."));
  536. HandleMessage(pHdr, (DWORD) BufferLen, &SockAddr, SockAddrLen);
  537. }
  538. }
  539. else
  540. {
  541. m_bShutDown = TRUE;
  542. ParanoiaLock();
  543. DBG_INFO((DBGARG, TEXT("Server closeing down with value %d"), err));
  544. if( m_ServerSocket == INVALID_SOCKET )
  545. {
  546. CloseSocket(m_ServerSocket, 2);
  547. }
  548. m_ServerSocket = INVALID_SOCKET;
  549. ParanoiaUnlock();
  550. }
  551. }
  552. //
  553. // Clean up everything related to this thread and return
  554. // to caller which will implicitly call ExitThread.
  555. //
  556. abort:
  557. return(hr);
  558. }
  559. // ----------------------------------------------------------
  560. // GetCaps - return info about the connection media
  561. // ----------------------------------------------------------
  562. //
  563. // Return our caps immediately if we have a valid latency value.
  564. // if we haven't gotten latency yet, send a DPSYS_PING. Latency is
  565. // the time it takes to get a response DPSYS_PING / 2.
  566. //
  567. HRESULT CImpIDP_SP::GetCaps(
  568. LPDPCAPS lpDPCaps // buffer to receive capabilities
  569. )
  570. {
  571. *lpDPCaps = m_dpcaps;
  572. if (m_dpcaps.dwLatency == 0)
  573. SendPing();
  574. return(DP_OK);
  575. }
  576. // ----------------------------------------------------------
  577. // Connect - establishes communications with underlying transport,
  578. // and initializes name services and network entities
  579. // ----------------------------------------------------------
  580. BOOL CImpIDP_SP::SetSession(DWORD dw)
  581. {
  582. return(FALSE);
  583. }
  584. DWORD CImpIDP_SP::BlockNicely(DWORD dwTimeout)
  585. {
  586. DWORD dwStart;
  587. DWORD dwEnd;
  588. DWORD dwNow;
  589. DWORD dwRet;
  590. MSG msg;
  591. if (m_hBlockingEvent)
  592. {
  593. dwStart = GetTickCount();
  594. dwEnd = dwStart + dwTimeout;
  595. dwNow = GetTickCount();
  596. do
  597. {
  598. dwRet = MsgWaitForMultipleObjects(1,
  599. &m_hBlockingEvent,
  600. FALSE,
  601. dwEnd - dwNow,
  602. QS_ALLINPUT);
  603. switch (dwRet)
  604. {
  605. case WAIT_OBJECT_0:
  606. {
  607. ResetEvent(m_hBlockingEvent);
  608. return(WAIT_OBJECT_0);
  609. }
  610. case WAIT_TIMEOUT:
  611. return(WAIT_TIMEOUT);
  612. case WAIT_OBJECT_0 + 1:
  613. {
  614. while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
  615. {
  616. TranslateMessage(&msg);
  617. DispatchMessage(&msg);
  618. if (dwEnd < (dwNow = GetTickCount()))
  619. {
  620. return(WAIT_TIMEOUT);
  621. }
  622. }
  623. }
  624. }
  625. dwNow = GetTickCount();
  626. } while (dwNow < dwEnd);
  627. dwRet = WaitForSingleObject(m_hBlockingEvent, 0);
  628. ResetEvent(m_hBlockingEvent);
  629. return(dwRet);
  630. }
  631. else
  632. {
  633. return(WAIT_ABANDONED);
  634. }
  635. }
  636. HRESULT CImpIDP_SP::Open(
  637. LPDPSESSIONDESC lpSDesc, HANDLE lpHandle
  638. )
  639. {
  640. TSHELL_INFO(TEXT("SP Open"));
  641. DWORD ii;
  642. if (m_hEnumThread)
  643. {
  644. m_bRunEnumReceiveLoop = FALSE;
  645. SetThreadPriority(m_hEnumThread, THREAD_PRIORITY_NORMAL);
  646. TSHELL_INFO(TEXT("EnumSessions:: Closing Socket."));
  647. EnumDataLock();
  648. if (m_EnumSocket)
  649. CloseSocket(m_EnumSocket, 2);
  650. m_EnumSocket = INVALID_SOCKET;
  651. EnumDataUnlock();
  652. TSHELL_INFO(TEXT("EnumSessions:: Socket Closed."));
  653. if (WaitForSingleObject(m_hEnumThread, 4000) == WAIT_TIMEOUT)
  654. TerminateThread(m_hEnumThread, 0);
  655. m_bEnumSocket = FALSE;
  656. m_hEnumThread = NULL;
  657. }
  658. if (lpSDesc->dwFlags & DPOPEN_CREATESESSION)
  659. {
  660. if (hOnlyOneTCP || hOnlyOneIPX)
  661. {
  662. TSHELL_INFO(TEXT("We already have a server active!"));
  663. return(DPERR_GENERIC);
  664. }
  665. else
  666. {
  667. if (m_af == AF_INET)
  668. {
  669. hOnlyOneTCP = CreateEvent(NULL, TRUE, TRUE, "KyraHallTCP");
  670. if (hOnlyOneTCP == NULL || GetLastError() == ERROR_ALREADY_EXISTS)
  671. {
  672. if (hOnlyOneTCP)
  673. CloseHandle(hOnlyOneTCP);
  674. hOnlyOneTCP = NULL;
  675. return(DPERR_GENERIC);
  676. }
  677. }
  678. else
  679. {
  680. hOnlyOneIPX = CreateEvent(NULL, TRUE, TRUE, "KyraHallIPX");
  681. if (hOnlyOneIPX == NULL || GetLastError() == ERROR_ALREADY_EXISTS)
  682. {
  683. if (hOnlyOneIPX)
  684. CloseHandle(hOnlyOneIPX);
  685. hOnlyOneIPX = NULL;
  686. return(DPERR_GENERIC);
  687. }
  688. }
  689. }
  690. if (m_hNSThread || m_aMachineAddr)
  691. {
  692. TSHELL_INFO(TEXT("Globals indicate we already have opened a game."));
  693. return(DPERR_GENERIC);
  694. }
  695. m_aMachineAddr = (SOCKADDR *) lmalloc(sizeof(SOCKADDR) * MAX_PLAYERS);
  696. m_cMachines = 0;
  697. memcpy( &m_dpDesc, lpSDesc, sizeof(m_dpDesc));
  698. m_dpDesc.dwCurrentPlayers = 0;
  699. m_dpDesc.dwReserved1 = 0;
  700. m_dpDesc.dwReserved2 = 0;
  701. ResetEvent(m_hBlockingEvent);
  702. m_hNSThread = CreateThread(NULL, 0, StartServerThreadProc,
  703. (LPVOID) this, 0, &m_dwNSId);
  704. if (m_hNSThread == NULL)
  705. {
  706. TSHELL_INFO(TEXT("StartServerThreadProc failed."));
  707. return(DPERR_GENERIC);
  708. }
  709. if (WaitForSingleObject(m_hBlockingEvent, INFINITE) == WAIT_TIMEOUT)
  710. {
  711. TSHELL_INFO(TEXT("INFINITITY Reached. Notify Nobel Committee."));
  712. return(DPERR_GENERIC);
  713. }
  714. ResetEvent(m_hBlockingEvent);
  715. if (m_bPlayer0 != TRUE)
  716. {
  717. TSHELL_INFO(TEXT("We aren't player 0 for some reason."));
  718. return(DPERR_GENERIC);
  719. }
  720. m_hClientThread = CreateThread(NULL, 0, StartClientThreadProc,
  721. (LPVOID) this, 0, &m_dwClientId);
  722. return(DP_OK);
  723. }
  724. else if (lpSDesc->dwFlags & DPOPEN_OPENSESSION)
  725. {
  726. if (GetSessionData(lpSDesc->dwSession))
  727. {
  728. SPMSG_ENUM Msg;
  729. UINT BufferLen;
  730. if (m_bPlayer0 || m_usGamePort == 0)
  731. return(DPERR_GENERIC);
  732. ResetEvent(m_hBlockingEvent);
  733. m_hClientThread = CreateThread(NULL, 0, StartClientThreadProc,
  734. (LPVOID) this, 0, &m_dwClientId);
  735. if (WaitForSingleObject(m_hBlockingEvent, 9000) == WAIT_TIMEOUT)
  736. return(DPERR_GENERIC);
  737. Msg.dpHdr.dwConnect1 = DPSYS_KYRA;
  738. Msg.dpHdr.dwConnect2 = DPSYS_HALL;
  739. Msg.dpHdr.usSeq = NextSequence();
  740. Msg.dwType = DPSYS_OPEN;
  741. Msg.dpSessionDesc = *lpSDesc;
  742. Msg.usPort = m_usGamePort;
  743. Msg.dwUnique = m_dwUnique;
  744. Msg.usVerMajor = DPVERSION_MAJOR;
  745. Msg.usVerMinor = DPVERSION_MINOR;
  746. BufferLen = sizeof(SPMSG_ENUM);
  747. ResetEvent(m_hBlockingEvent);
  748. if (SendTo(m_ClientSocket, &m_NSSockAddr,
  749. m_SessionAddrLen, (char *) &Msg, &BufferLen) != 0)
  750. {
  751. TSHELL_INFO(TEXT("Enum SendTo failed."));
  752. }
  753. if (WaitForSingleObject(m_hBlockingEvent, 9000) == WAIT_TIMEOUT)
  754. {
  755. TSHELL_INFO(TEXT("We timed out."));
  756. }
  757. EnumDataLock();
  758. if (m_ppSessionArray)
  759. {
  760. for (ii = 0; ii < m_dwSessionPrev; ii++)
  761. lfree(m_ppSessionArray[ii]);
  762. lfree(m_ppSessionArray);
  763. m_ppSessionArray = NULL;
  764. m_dwSessionPrev = 0;
  765. m_dwSessionAlloc = 0;
  766. }
  767. EnumDataUnlock();
  768. if (m_bConnected == FALSE)
  769. return(DPERR_GENERIC);
  770. return(DP_OK);
  771. }
  772. else
  773. {
  774. return(DPERR_UNAVAILABLE);
  775. }
  776. }
  777. else
  778. {
  779. TSHELL_INFO(TEXT("Unhandled Open flags."));
  780. return(DPERR_UNSUPPORTED);
  781. }
  782. }
  783. // ----------------------------------------------------------
  784. // CreatePlayer - registers new player, N.B. may fail if
  785. // not currently connected to name server
  786. // ----------------------------------------------------------
  787. LONG CImpIDP_SP::FindInvalidIndex()
  788. {
  789. DWORD ii;
  790. ParanoiaLock();
  791. for (ii = 0; ii < MAX_PLAYERS; ii++)
  792. if (m_aPlayer[ii].bValid == FALSE)
  793. {
  794. ParanoiaUnlock();
  795. return(ii);
  796. }
  797. ParanoiaUnlock();
  798. return(-1);
  799. }
  800. VOID CImpIDP_SP::LocalMsg(LONG iIndex, LPVOID lpv, DWORD dwSize)
  801. {
  802. LONG ii;
  803. ParanoiaLock();
  804. for (ii = 0; ii < MAX_PLAYERS; ii++)
  805. if ( ii != iIndex
  806. && m_aPlayer[ii].bValid
  807. && m_aPlayer[ii].bLocal
  808. && m_aPlayer[ii].bPlayer)
  809. AddMessage(lpv, dwSize, m_aPlayer[ii].pid, 0, 0);
  810. ParanoiaUnlock();
  811. }
  812. //
  813. // Obsolete? [johnhall]
  814. //
  815. VOID CImpIDP_SP::RemoteMsg(LONG iIndex, LPVOID lpv, DWORD dwSize)
  816. {
  817. SPMSG_GENERIC Msg;
  818. DWORD dwTotal = dwSize + sizeof(DPHDR);
  819. DWORD ii;
  820. if (!m_bConnected)
  821. return;
  822. Msg.dpHdr.usCookie = DPSYS_SYS;
  823. Msg.dpHdr.to = 0;
  824. Msg.dpHdr.from = 0;
  825. Msg.dpHdr.usCount = (USHORT) dwSize;
  826. Msg.dpHdr.usGame = (USHORT) m_usGameCookie;
  827. Msg.dpHdr.usSeq = NextSequence();
  828. memcpy( (LPVOID) &Msg.sMsg, lpv, dwSize);
  829. ParanoiaLock();
  830. for (ii = 0; ii < MAX_PLAYERS; ii++)
  831. if ( ii != (DWORD) iIndex
  832. && m_aPlayer[ii].bValid
  833. && m_aPlayer[ii].bLocal == FALSE
  834. && m_aPlayer[ii].bPlayer)
  835. {
  836. PostPlayerMessage( (LONG) ii, (LPVOID) &Msg, dwTotal);
  837. TSHELL_INFO(TEXT("Post Player Message in RemoteMsg."));
  838. }
  839. ParanoiaUnlock();
  840. }
  841. BOOL CImpIDP_SP::PostGameMessage(LPVOID lpv, DWORD dw)
  842. {
  843. DWORD ii;
  844. ParanoiaLock();
  845. for (ii = 0; ii < m_cMachines; ii++)
  846. if (SendTo(m_ClientSocket, &m_aMachineAddr[ii], sizeof(SOCKADDR), (char *) lpv, (LPUINT) &dw) != 0)
  847. {
  848. TSHELL_INFO(TEXT("Send Failed"));
  849. }
  850. else
  851. {
  852. LPDWORD lpdw = (LPDWORD) &m_aMachineAddr[ii];
  853. DBG_INFO((DBGARG, TEXT("Machine %d Addr %8x %8x %8x %8x"), ii,
  854. lpdw[0], lpdw[1], lpdw[2], lpdw[3]));
  855. }
  856. ParanoiaUnlock();
  857. return(TRUE);
  858. }
  859. BOOL CImpIDP_SP::PostPlayerMessage(LONG iIndex, LPVOID lpv, DWORD dw)
  860. {
  861. UINT err;
  862. if ((err = SendTo(m_ClientSocket, &m_aPlayer[iIndex].sockaddr, sizeof(SOCKADDR), (char *) lpv, (LPUINT) &dw)) != 0)
  863. {
  864. DBG_INFO((DBGARG, TEXT("Send Failed %d"), err));
  865. return(FALSE);
  866. }
  867. return(TRUE);
  868. }
  869. BOOL CImpIDP_SP::PostNSMessage(LPVOID lpv, DWORD dw)
  870. {
  871. if (SendTo(m_ClientSocket, &m_NSSockAddr, sizeof(SOCKADDR), (char *) lpv, (LPUINT) &dw) != 0)
  872. {
  873. TSHELL_INFO(TEXT("Send Failed"));
  874. return(FALSE);
  875. }
  876. return(TRUE);
  877. }
  878. extern BOOL SetupLocalPlayer(DPID pid, HANDLE hEvent);
  879. HRESULT CImpIDP_SP::CreatePlayer(
  880. LPDPID pPlayerID,
  881. LPSTR pNickName,
  882. LPSTR pFullName,
  883. LPHANDLE lpReceiveEvent,
  884. BOOL bPlayer
  885. )
  886. {
  887. DWORD jj;
  888. SPMSG_ADDPLAYER *pMsg;
  889. HANDLE hEvent = NULL;
  890. BOOL bb = TRUE;
  891. HRESULT hr = DP_OK;
  892. LONG iIndex;
  893. DPMSG_ADDPLAYER dpAdd;
  894. SPMSG_ADDPLAYER spmsg_addplayer;
  895. USHORT usLocalSeq;
  896. // TSHELL_INFO(TEXT("Enter Create Player"));
  897. if (m_bConnected == FALSE)
  898. if (m_bPlayer0 != TRUE)
  899. return(DPERR_NOCONNECTION);
  900. if (m_bEnablePlayerAdd == FALSE && bPlayer == TRUE)
  901. return(DPERR_CANTCREATEPLAYER);
  902. if (m_dpDesc.dwMaxPlayers <= m_dpDesc.dwCurrentPlayers)
  903. {
  904. DBG_INFO((DBGARG, TEXT("CreatePlayer: at max players already. %d"),
  905. m_dpDesc.dwMaxPlayers));
  906. return(DPERR_CANTADDPLAYER);
  907. }
  908. if (m_iPlayerIndex != -1)
  909. {
  910. TSHELL_INFO(TEXT("Player index not -1, create already in progress."));
  911. return(DPERR_GENERIC);
  912. }
  913. if (m_hNewPlayerEvent)
  914. return(DPERR_GENERIC);
  915. if (!(hEvent = CreateEvent(NULL, TRUE, FALSE, NULL)))
  916. {
  917. TSHELL_INFO(TEXT("CreatePlayer: CreateEvent failure."));
  918. return(DPERR_GENERIC);
  919. }
  920. else
  921. {
  922. ; // DBG_INFO((DBGARG, TEXT("CreatePlayer %8x Event"), hEvent));
  923. }
  924. ParanoiaLock();
  925. iIndex = FindInvalidIndex();
  926. if (iIndex == -1)
  927. {
  928. ParanoiaUnlock();
  929. return(DPERR_GENERIC);
  930. }
  931. dpAdd.dwType = DPSYS_ADDPLAYER;
  932. dpAdd.dwPlayerType = bPlayer;
  933. dpAdd.dpId = 0;
  934. dpAdd.dwCurrentPlayers = m_dpDesc.dwCurrentPlayers;
  935. lstrcpy( dpAdd.szShortName, pNickName);
  936. lstrcpy( dpAdd.szLongName , pFullName);
  937. pMsg = &spmsg_addplayer;
  938. usLocalSeq = NextSequence();
  939. pMsg->dpHdr.usCookie = DPSYS_SYS;
  940. pMsg->dpHdr.to = 0;
  941. pMsg->dpHdr.from = 0;
  942. pMsg->dpHdr.usCount = SIZE_ADDPLAYER;
  943. pMsg->dpHdr.usGame = (USHORT) m_usGameCookie;
  944. pMsg->dpHdr.usSeq = usLocalSeq;
  945. pMsg->dwUnique = m_dwUnique;
  946. memset(&pMsg->sockaddr, 0x00, sizeof(SOCKADDR));
  947. if (m_bPlayer0)
  948. {
  949. if (!bPlayer)
  950. {
  951. m_aPlayer[iIndex].aGroup = (DPID *) lmalloc(sizeof(DPID) * MAX_PLAYERS);
  952. if (m_aPlayer[iIndex].aGroup == NULL)
  953. {
  954. ParanoiaUnlock();
  955. return(DPERR_NOMEMORY);
  956. }
  957. else
  958. memset(m_aPlayer[iIndex].aGroup, 0x00, sizeof(DPID) * MAX_PLAYERS);
  959. }
  960. m_dpDesc.dwCurrentPlayers++;
  961. m_aPlayer[iIndex].pid = (DPID) m_dwNextPlayer++;
  962. lstrcpy( m_aPlayer[iIndex].chNickName, pNickName);
  963. lstrcpy( m_aPlayer[iIndex].chFullName, pFullName);
  964. m_aPlayer[iIndex].bValid = TRUE;
  965. m_aPlayer[iIndex].bPlayer = bPlayer;
  966. m_aPlayer[iIndex].hEvent = hEvent;
  967. m_aPlayer[iIndex].bLocal = TRUE;
  968. memset(&m_aPlayer[iIndex].sockaddr, 0x00, sizeof(SOCKADDR));
  969. dpAdd.dpId = m_aPlayer[iIndex].pid;
  970. dpAdd.dwCurrentPlayers = m_dpDesc.dwCurrentPlayers;
  971. LocalMsg( iIndex, (LPVOID) &dpAdd, sizeof(DPMSG_ADDPLAYER));
  972. memcpy( (LPVOID) &pMsg->sMsg, &dpAdd, sizeof(DPMSG_ADDPLAYER));
  973. PostGameMessage((LPVOID) pMsg, sizeof(SPMSG_ADDPLAYER));
  974. hEvent = NULL;
  975. *pPlayerID = m_aPlayer[iIndex].pid;
  976. if (lpReceiveEvent)
  977. *lpReceiveEvent = m_aPlayer[iIndex].hEvent;
  978. SetupLocalPlayer(m_aPlayer[iIndex].pid, m_aPlayer[iIndex].hEvent);
  979. ParanoiaUnlock();
  980. return(DP_OK);
  981. }
  982. ParanoiaUnlock();
  983. m_hNewPlayerEvent = hEvent;
  984. //
  985. // BUGBUG for now, try once in Net provider.
  986. //
  987. for (jj = 0; jj < 1; jj++)
  988. {
  989. TSHELL_INFO(TEXT("Post AddPlayer message from a Client"));
  990. memcpy( (LPVOID) &pMsg->sMsg, &dpAdd, sizeof(DPMSG_ADDPLAYER));
  991. PostNSMessage( (LPVOID) pMsg, sizeof(SPMSG_ADDPLAYER));
  992. pMsg = NULL;
  993. if (WaitForSingleObject(m_hNewPlayerEvent, 1500) != WAIT_TIMEOUT)
  994. {
  995. if (m_iPlayerIndex != -1)
  996. {
  997. SetupLocalPlayer(m_aPlayer[m_iPlayerIndex].pid, m_hNewPlayerEvent);
  998. m_aPlayer[m_iPlayerIndex].hEvent = m_hNewPlayerEvent;
  999. if (lpReceiveEvent)
  1000. *lpReceiveEvent = m_aPlayer[m_iPlayerIndex].hEvent;
  1001. m_hNewPlayerEvent = NULL;
  1002. *pPlayerID = m_aPlayer[m_iPlayerIndex].pid;
  1003. m_iPlayerIndex = -1;
  1004. DBG_INFO((DBGARG, TEXT("Player Index %d Pid %d Current %d"),
  1005. iIndex, m_aPlayer[iIndex].pid, m_dpDesc.dwCurrentPlayers));
  1006. return(DP_OK);
  1007. }
  1008. }
  1009. ResetEvent(m_hNewPlayerEvent);
  1010. }
  1011. hr = DPERR_CANTADDPLAYER;
  1012. m_hNewPlayerEvent = NULL;
  1013. if (pMsg)
  1014. lfree((HLOCAL) pMsg);
  1015. if (hEvent)
  1016. CloseHandle(hEvent);
  1017. return(hr);
  1018. }
  1019. LONG CImpIDP_SP::GetPlayerIndex(DPID playerID)
  1020. {
  1021. DWORD ii;
  1022. DPID pid = playerID;
  1023. ParanoiaLock();
  1024. for (ii = 0; ii < MAX_PLAYERS; ii++)
  1025. {
  1026. if (m_aPlayer[ii].bValid)
  1027. if (m_aPlayer[ii].pid == pid)
  1028. {
  1029. ParanoiaUnlock();
  1030. return(ii);
  1031. }
  1032. }
  1033. ParanoiaUnlock();
  1034. return(-1);
  1035. }
  1036. // ----------------------------------------------------------
  1037. // DestroyPlayer
  1038. // ----------------------------------------------------------
  1039. HRESULT CImpIDP_SP::DestroyPlayer( DPID playerID, BOOL bPlayer)
  1040. {
  1041. LONG iIndex;
  1042. DWORD ii, jj;
  1043. DPMSG_GETPLAYER dpGet;
  1044. SPMSG_GETPLAYER spmsg_getplayer;
  1045. SPMSG_GETPLAYER *pMsg;
  1046. HANDLE hEvent = NULL;
  1047. HRESULT hr = DP_OK;
  1048. ParanoiaLock();
  1049. if ( (iIndex = GetPlayerIndex(playerID)) == -1
  1050. || m_aPlayer[iIndex].bPlayer != bPlayer)
  1051. {
  1052. ParanoiaUnlock();
  1053. return(DPERR_INVALIDPLAYER);
  1054. }
  1055. if (bPlayer)
  1056. {
  1057. dpGet.dwType = DPSYS_DELETEPLAYER;
  1058. }
  1059. else
  1060. {
  1061. dpGet.dwType = DPSYS_DELETEGROUP;
  1062. }
  1063. dpGet.dpId = m_aPlayer[iIndex].pid;
  1064. if (m_aPlayer[iIndex].bLocal)
  1065. {
  1066. CloseHandle(m_aPlayer[iIndex].hEvent);
  1067. FlushQueue(playerID);
  1068. }
  1069. m_aPlayer[iIndex].bValid = FALSE;
  1070. m_dpDesc.dwCurrentPlayers--;
  1071. if (m_aPlayer[iIndex].aGroup)
  1072. lfree(m_aPlayer[iIndex].aGroup);
  1073. LocalMsg(iIndex, (LPVOID) &dpGet, sizeof(DPMSG_GETPLAYER));
  1074. pMsg = &spmsg_getplayer;
  1075. pMsg->dpHdr.usCookie = DPSYS_SYS;
  1076. pMsg->dpHdr.to = 0;
  1077. pMsg->dpHdr.from = 0;
  1078. pMsg->dpHdr.usCount = sizeof(DPMSG_GETPLAYER);
  1079. pMsg->dpHdr.usGame = (USHORT) m_usGameCookie;
  1080. memcpy( (LPVOID) &pMsg->sMsg, (LPVOID) &dpGet, sizeof(DPMSG_GETPLAYER));
  1081. if (m_bPlayer0)
  1082. {
  1083. PostGameMessage((LPVOID) pMsg, sizeof(SPMSG_GETPLAYER));
  1084. }
  1085. else
  1086. {
  1087. PostNSMessage( (LPVOID) pMsg, sizeof(SPMSG_GETPLAYER));
  1088. }
  1089. for (ii = 0; ii < MAX_PLAYERS; ii++)
  1090. {
  1091. if ( m_aPlayer[ii].bValid == TRUE
  1092. && m_aPlayer[ii].bPlayer == FALSE
  1093. && m_aPlayer[ii].aGroup)
  1094. {
  1095. for (jj = 0; jj < MAX_PLAYERS; jj++)
  1096. {
  1097. if (m_aPlayer[ii].aGroup[jj] == playerID)
  1098. {
  1099. m_aPlayer[ii].aGroup[jj] = 0;
  1100. break;
  1101. }
  1102. }
  1103. }
  1104. }
  1105. ParanoiaUnlock();
  1106. return(DP_OK);
  1107. }
  1108. // ----------------------------------------------------------
  1109. // Close - close the connection
  1110. // ----------------------------------------------------------
  1111. HRESULT CImpIDP_SP::Close( DWORD dwFlag)
  1112. {
  1113. DWORD ii;
  1114. DWORD dwTickBegin;
  1115. dwTickBegin = GetTickCount();
  1116. ParanoiaLock();
  1117. for (ii = 0; ii < MAX_PLAYERS; ii++)
  1118. {
  1119. if (m_aPlayer[ii].bValid)
  1120. {
  1121. if ( ( m_aPlayer[ii].bLocal && m_aPlayer[ii].bPlayer == TRUE))
  1122. {
  1123. DestroyPlayer(m_aPlayer[ii].pid, TRUE);
  1124. }
  1125. m_aPlayer[ii].bValid = FALSE;
  1126. }
  1127. }
  1128. m_bShutDown = TRUE;
  1129. m_bConnected = FALSE;
  1130. m_bPlayer0 = FALSE;
  1131. m_fpEnumSessions = NULL;
  1132. m_bRunEnumReceiveLoop = FALSE;
  1133. m_fpEnumPlayers = NULL;
  1134. TSHELL_INFO(TEXT("Close:: Closing Socket."));
  1135. if (m_hNSThread && m_ServerSocket != INVALID_SOCKET)
  1136. CloseSocket(m_ServerSocket, 2);
  1137. m_ServerSocket = INVALID_SOCKET;
  1138. if (m_hClientThread && m_ClientSocket != INVALID_SOCKET)
  1139. CloseSocket(m_ClientSocket, 2);
  1140. m_ClientSocket = INVALID_SOCKET;
  1141. TSHELL_INFO(TEXT("Close:: Socket Closed."));
  1142. ParanoiaUnlock();
  1143. if (m_aMachineAddr)
  1144. {
  1145. lfree(m_aMachineAddr);
  1146. m_aMachineAddr = NULL;
  1147. m_cMachines = 0;
  1148. }
  1149. if (m_hNSThread)
  1150. {
  1151. if (WaitForSingleObject(m_hNSThread, 4000) == WAIT_TIMEOUT)
  1152. {
  1153. TSHELL_INFO(TEXT("Terminating m_hNSThread"));
  1154. TerminateThread(m_hNSThread, 0);
  1155. }
  1156. m_hNSThread = NULL;
  1157. }
  1158. if (m_hEnumThread)
  1159. {
  1160. SetThreadPriority(m_hEnumThread, THREAD_PRIORITY_NORMAL);
  1161. TSHELL_INFO(TEXT("EnumSessions:: Closing Socket."));
  1162. EnumDataLock();
  1163. if (m_EnumSocket)
  1164. CloseSocket(m_EnumSocket, 2);
  1165. m_EnumSocket = INVALID_SOCKET;
  1166. EnumDataUnlock();
  1167. TSHELL_INFO(TEXT("EnumSessions:: Socket Closed."));
  1168. if (WaitForSingleObject(m_hEnumThread, 4000) == WAIT_TIMEOUT)
  1169. TerminateThread(m_hEnumThread, 0);
  1170. m_bEnumSocket = FALSE;
  1171. m_hEnumThread = NULL;
  1172. }
  1173. if (m_hClientThread)
  1174. {
  1175. SetThreadPriority(m_hClientThread, THREAD_PRIORITY_NORMAL);
  1176. if (WaitForSingleObject(m_hClientThread, 4000) == WAIT_TIMEOUT)
  1177. {
  1178. TSHELL_INFO(TEXT("Terminating m_hClientThread"));
  1179. TerminateThread(m_hClientThread, 0);
  1180. }
  1181. m_bClientSocket = FALSE;
  1182. m_hClientThread = NULL;
  1183. }
  1184. ShutdownWinSock();
  1185. _try
  1186. {
  1187. if (hOnlyOneTCP)
  1188. {
  1189. CloseHandle(hOnlyOneTCP);
  1190. }
  1191. if (hOnlyOneIPX)
  1192. {
  1193. CloseHandle(hOnlyOneIPX);
  1194. }
  1195. }
  1196. _except(EXCEPTION_EXECUTE_HANDLER)
  1197. {
  1198. TSHELL_INFO(TEXT("Exception closing handle."));
  1199. }
  1200. hOnlyOneTCP = NULL;
  1201. hOnlyOneIPX = NULL;
  1202. if (dwFlag == DPLAY_CLOSE_USER)
  1203. {
  1204. InitializeWinSock();
  1205. m_bShutDown = FALSE;
  1206. }
  1207. DBG_INFO((DBGARG, TEXT("Close Took %d Ticks"), GetTickCount() - dwTickBegin));
  1208. return(DP_OK);
  1209. }
  1210. // ----------------------------------------------------------
  1211. // GetName -
  1212. // ----------------------------------------------------------
  1213. HRESULT CImpIDP_SP::GetPlayerName(
  1214. DPID dpID,
  1215. LPSTR lpNickName, // buffer to hold name
  1216. LPDWORD pdwNickNameLength, // length of name buffer
  1217. LPSTR lpFullName,
  1218. LPDWORD pdwFullNameLength
  1219. )
  1220. {
  1221. LONG iIndex;
  1222. HRESULT hr = DP_OK;
  1223. DPID pid = (DPID) dpID;
  1224. ParanoiaLock();
  1225. if ((iIndex = GetPlayerIndex(dpID)) != -1)
  1226. {
  1227. if (m_aPlayer[iIndex].pid == dpID)
  1228. {
  1229. lstrcpy( lpNickName, m_aPlayer[iIndex].chNickName);
  1230. lstrcpy( lpFullName, m_aPlayer[iIndex].chFullName);
  1231. *pdwNickNameLength = lstrlen(lpNickName) + 1;
  1232. *pdwFullNameLength = lstrlen(lpFullName) + 1;
  1233. }
  1234. else
  1235. hr = DPERR_INVALIDPID;
  1236. }
  1237. else
  1238. {
  1239. hr = DPERR_INVALIDPID;
  1240. }
  1241. ParanoiaUnlock();
  1242. return(hr);
  1243. }
  1244. HRESULT CImpIDP_SP::EnumGroupPlayers(
  1245. DPID dwGroupPid,
  1246. LPDPENUMPLAYERSCALLBACK EnumCallback,
  1247. LPVOID pContext,
  1248. DWORD dwFlags)
  1249. {
  1250. DWORD ii;
  1251. HRESULT hr = DP_OK;
  1252. LONG iIndexG;
  1253. LONG iIndexP;
  1254. DPID pid;
  1255. ParanoiaLock();
  1256. iIndexG = GetPlayerIndex(dwGroupPid);
  1257. if (iIndexG == -1 || m_aPlayer[iIndexG].pid != dwGroupPid)
  1258. hr = DPERR_INVALIDPID;
  1259. if (m_aPlayer[iIndexG].bPlayer)
  1260. hr = DPERR_INVALIDPID;
  1261. if (hr == DP_OK)
  1262. for (ii = 0; ii < MAX_PLAYERS; ii++)
  1263. {
  1264. if ((pid = m_aPlayer[iIndexG].aGroup[ii]) != 0)
  1265. {
  1266. iIndexP = GetPlayerIndex(pid);
  1267. if (iIndexP != -1)
  1268. {
  1269. (EnumCallback)((DPID) m_aPlayer[iIndexP].pid,
  1270. m_aPlayer[iIndexP].chNickName,
  1271. m_aPlayer[iIndexP].chFullName,
  1272. ((m_aPlayer[iIndexP].bLocal ) ? DPENUMPLAYERS_LOCAL : DPENUMPLAYERS_REMOTE)
  1273. | ((!m_aPlayer[iIndexP].bPlayer) ? DPENUMPLAYERS_GROUP : 0),
  1274. pContext);
  1275. }
  1276. else
  1277. {
  1278. m_aPlayer[iIndexG].aGroup[ii] = 0;
  1279. }
  1280. }
  1281. }
  1282. ParanoiaUnlock();
  1283. return(hr);
  1284. }
  1285. // ----------------------------------------------------------
  1286. // EnumPlayers - return info on peer connections.
  1287. // ----------------------------------------------------------
  1288. HRESULT CImpIDP_SP::EnumPlayers(
  1289. DWORD dwSessionId,
  1290. LPDPENUMPLAYERSCALLBACK EnumCallback,
  1291. LPVOID pContext,
  1292. DWORD dwFlags)
  1293. {
  1294. DWORD ii;
  1295. HRESULT hr = DP_OK;
  1296. BOOL bDone = FALSE;
  1297. BOOL bFound = FALSE;
  1298. DWORD dwTimeout;
  1299. if (dwFlags & DPENUMPLAYERS_PREVIOUS)
  1300. {
  1301. return(DPERR_UNSUPPORTED);
  1302. }
  1303. if (dwFlags & DPENUMPLAYERS_SESSION)
  1304. {
  1305. //
  1306. // We can't let them call us inside a enumsessions callback anymore.
  1307. //
  1308. if (m_bConnected || m_fpEnumSessions || m_bPlayer0 )
  1309. {
  1310. TSHELL_INFO(TEXT("EnumPlayers: Unsupported."));
  1311. return(DPERR_UNSUPPORTED);
  1312. }
  1313. if (GetSessionData(dwSessionId))
  1314. {
  1315. SPMSG_GENERIC pMsg;
  1316. UINT BufferLen = sizeof(SPMSG_GENERIC);
  1317. TSHELL_INFO(TEXT("We are trying to retrieve player info."));
  1318. m_fpEnumPlayers = EnumCallback;
  1319. m_lpvPlayersContext = pContext;
  1320. pMsg.dpHdr.usCookie = DPSYS_SYS;
  1321. pMsg.dpHdr.to = 0;
  1322. pMsg.dpHdr.from = 0;
  1323. pMsg.dpHdr.usCount = (USHORT) sizeof(DPMSG_GENERIC);
  1324. pMsg.dpHdr.usGame = 0;
  1325. pMsg.dpHdr.usSeq = NextSequence();
  1326. pMsg.sMsg.dwType = DPSYS_ENUMALLPLAYERS;
  1327. if (SendTo(m_EnumSocket, &m_NSSockAddr,
  1328. m_SessionAddrLen, (char *) &pMsg, &BufferLen) != 0)
  1329. {
  1330. TSHELL_INFO(TEXT("Enum SendTo failed."));
  1331. }
  1332. memset( (LPVOID) &m_spmsgAddPlayer, 0x00, sizeof(SPMSG_ADDPLAYER));
  1333. ResetEvent(m_hPlayerBlkEventMain);
  1334. ResetEvent(m_hPlayerBlkEventRead);
  1335. //
  1336. // Hard code timeout.
  1337. //
  1338. dwTimeout = 1000;
  1339. while (!bDone)
  1340. {
  1341. DWORD dwRet;
  1342. //
  1343. // Wait for DPSYS_ENUMPLAYERRESP to wake us up.
  1344. //
  1345. dwRet = WaitForSingleObject(m_hPlayerBlkEventMain, dwTimeout);
  1346. //
  1347. // Prevent another DPSYS_ENUMPLAYERRESP before we've processed this one.
  1348. //
  1349. PlayerDataLock();
  1350. //
  1351. // Reset our wait, and tell DPSYS_ENUMPLAYERRESP it can continue and
  1352. // pick another reply packet up.
  1353. //
  1354. ResetEvent(m_hPlayerBlkEventMain);
  1355. SetEvent(m_hPlayerBlkEventRead);
  1356. //
  1357. // Only process if our enum sessions is still valid.
  1358. //
  1359. if (m_fpEnumPlayers)
  1360. {
  1361. if( dwRet == WAIT_TIMEOUT)
  1362. {
  1363. m_fpEnumPlayers = NULL;
  1364. bDone = TRUE;
  1365. TSHELL_INFO(TEXT("End EnumPlayers on Timeout."));
  1366. }
  1367. else
  1368. {
  1369. bFound = TRUE;
  1370. TSHELL_INFO(TEXT("Found a remote player."));
  1371. _try
  1372. {
  1373. if ((m_fpEnumPlayers)(m_spmsgAddPlayer.sMsg.dpId,
  1374. (LPSTR) m_spmsgAddPlayer.sMsg.szShortName,
  1375. (LPSTR) m_spmsgAddPlayer.sMsg.szLongName,
  1376. 0,
  1377. m_lpvPlayersContext) == FALSE)
  1378. {
  1379. m_fpEnumPlayers = NULL;
  1380. bDone = TRUE;
  1381. TSHELL_INFO(TEXT("End EnumPlayers."));
  1382. }
  1383. else
  1384. dwTimeout = 250;
  1385. }
  1386. _except(EXCEPTION_EXECUTE_HANDLER)
  1387. {
  1388. m_fpEnumPlayers = NULL;
  1389. bDone = TRUE;
  1390. TSHELL_INFO(TEXT("End EnumPlayers."));
  1391. }
  1392. }
  1393. }
  1394. else
  1395. {
  1396. bDone = TRUE;
  1397. }
  1398. PlayerDataUnlock();
  1399. }
  1400. return(DP_OK);
  1401. }
  1402. else
  1403. {
  1404. TSHELL_INFO(TEXT("EnumPlayers: bad session ID"));
  1405. return(DPERR_INVALIDOBJECT);
  1406. }
  1407. }
  1408. ParanoiaLock();
  1409. for (ii = 0; ii < MAX_PLAYERS; ii++)
  1410. if (m_aPlayer[ii].bValid
  1411. && ( (m_aPlayer[ii].bPlayer == FALSE && (dwFlags & DPENUMPLAYERS_GROUP))
  1412. || (m_aPlayer[ii].bPlayer == TRUE && !(dwFlags & DPENUMPLAYERS_NOPLAYERS))))
  1413. {
  1414. if ((EnumCallback)((DPID) m_aPlayer[ii].pid,
  1415. m_aPlayer[ii].chNickName,
  1416. m_aPlayer[ii].chFullName,
  1417. ((m_aPlayer[ii].bLocal ) ? DPENUMPLAYERS_LOCAL : DPENUMPLAYERS_REMOTE)
  1418. | ((!m_aPlayer[ii].bPlayer) ? DPENUMPLAYERS_GROUP : 0),
  1419. pContext) == FALSE)
  1420. {
  1421. break;
  1422. }
  1423. }
  1424. ParanoiaUnlock();
  1425. return(DP_OK);
  1426. }
  1427. HRESULT CImpIDP_SP::EnumSessions(
  1428. LPDPSESSIONDESC lpSDesc,
  1429. DWORD dwTimeout,
  1430. LPDPENUMSESSIONSCALLBACK EnumCallback,
  1431. LPVOID lpvContext,
  1432. DWORD dwFlags)
  1433. {
  1434. SPMSG_ENUM Msg;
  1435. UINT BufferLen;
  1436. SOCKADDR SockAddr;
  1437. DWORD dwTimeBegin = GetTickCount();
  1438. DWORD dwTimeNow;
  1439. BOOL bFound = FALSE;
  1440. BOOL bDone = FALSE;
  1441. DWORD ii;
  1442. if (dwFlags & DPENUMSESSIONS_PREVIOUS)
  1443. return(DPERR_UNSUPPORTED);
  1444. if (m_bConnected || m_bPlayer0)
  1445. return(DPERR_UNSUPPORTED);
  1446. EnumDataLock();
  1447. if (m_ppSessionArray)
  1448. {
  1449. for (ii = 0; ii < m_dwSessionPrev; ii++)
  1450. lfree(m_ppSessionArray[ii]);
  1451. lfree(m_ppSessionArray);
  1452. m_ppSessionArray = NULL;
  1453. m_dwSessionPrev = 0;
  1454. m_dwSessionAlloc = 0;
  1455. }
  1456. if (m_bRunEnumReceiveLoop == FALSE)
  1457. {
  1458. m_usGamePort = 0;
  1459. memset(&m_NSSockAddr, 0x00, sizeof(SOCKADDR));
  1460. ResetEvent(m_hBlockingEvent);
  1461. m_fpEnumSessions = EnumCallback;
  1462. m_bRunEnumReceiveLoop = TRUE;
  1463. m_lpvSessionContext = lpvContext;
  1464. m_dwSession = 1;
  1465. m_hEnumThread = CreateThread(NULL, 0, StartClientThreadProc,
  1466. (LPVOID) this, 0, &m_dwEnumId);
  1467. if ( WaitForSingleObject(m_hBlockingEvent, 9000) == WAIT_TIMEOUT
  1468. || !m_bEnumSocket)
  1469. {
  1470. EnumDataUnlock();
  1471. return(DPERR_GENERIC);
  1472. }
  1473. }
  1474. else
  1475. {
  1476. m_fpEnumSessions = EnumCallback;
  1477. m_lpvSessionContext = lpvContext;
  1478. }
  1479. EnumDataUnlock();
  1480. Msg.dpHdr.dwConnect1 = DPSYS_KYRA;
  1481. Msg.dpHdr.dwConnect2 = DPSYS_HALL;
  1482. Msg.dwType = DPSYS_ENUM;
  1483. Msg.dpSessionDesc = *lpSDesc;
  1484. Msg.usPort = 0;
  1485. Msg.dwUnique = 0;
  1486. Msg.usVerMajor = DPVERSION_MAJOR;
  1487. Msg.usVerMinor = DPVERSION_MINOR;
  1488. memset(&SockAddr, 0, sizeof(SOCKADDR));
  1489. // Depending on the address family specified, we'll try to find the
  1490. // Name Server just a little differently.
  1491. //
  1492. if (GetSockAddress(&SockAddr, NULL, DPNS_PORT, NULL, TRUE))
  1493. {
  1494. BufferLen = sizeof(SPMSG_ENUM);
  1495. memset( (LPVOID) &m_spmsgEnum, 0x00, sizeof(SPMSG_ENUM));
  1496. ResetEvent(m_hEnumBlkEventMain);
  1497. ResetEvent(m_hEnumBlkEventRead);
  1498. if (SendTo(m_EnumSocket, &SockAddr, sizeof(SockAddr), (char *) &Msg, &BufferLen) != 0)
  1499. {
  1500. TSHELL_INFO(TEXT("Enum SendTo failed."));
  1501. }
  1502. // TSHELL_INFO(TEXT("Enum SendTo success."));
  1503. }
  1504. else
  1505. {
  1506. TSHELL_INFO(TEXT("Didn't get a proper sock address."));
  1507. return(DPERR_GENERIC);
  1508. }
  1509. while(!bDone)
  1510. {
  1511. DWORD dwRet;
  1512. //
  1513. // Wait for DPSYS_ENUM_REPLY to wake us up.
  1514. //
  1515. dwRet = WaitForSingleObject(m_hEnumBlkEventMain, dwTimeout);
  1516. //
  1517. // Prevent another DPSYS_ENUM_REPLY before we've processed this one.
  1518. //
  1519. EnumDataLock();
  1520. DBG_INFO((DBGARG, TEXT("Tick %d"), GetTickCount()));
  1521. //
  1522. // Reset our wait, and tell DPSYS_ENUM_REPLY it can continue and
  1523. // pick another reply packet up.
  1524. //
  1525. ResetEvent(m_hEnumBlkEventMain);
  1526. SetEvent(m_hEnumBlkEventRead);
  1527. //
  1528. // Only process if our enum sessions is still valid.
  1529. //
  1530. if (m_fpEnumSessions)
  1531. {
  1532. if( dwRet == WAIT_TIMEOUT)
  1533. {
  1534. memset( (LPVOID) &m_spmsgEnum, 0x00, sizeof(SPMSG_ENUM));
  1535. _try
  1536. {
  1537. if ((m_fpEnumSessions)(NULL, m_lpvSessionContext, &dwTimeout, DPESC_TIMEDOUT) == FALSE)
  1538. {
  1539. m_fpEnumSessions = NULL;
  1540. bDone = TRUE;
  1541. TSHELL_INFO(TEXT("End EnumSessions."));
  1542. }
  1543. else
  1544. {
  1545. dwTimeBegin = GetTickCount();
  1546. }
  1547. }
  1548. _except(EXCEPTION_EXECUTE_HANDLER)
  1549. {
  1550. m_fpEnumSessions = NULL;
  1551. bDone = TRUE;
  1552. TSHELL_INFO(TEXT("Exception encountered."));
  1553. }
  1554. }
  1555. else
  1556. {
  1557. bFound = TRUE;
  1558. DBG_INFO((DBGARG, TEXT("Session %d Name %s"),
  1559. m_spmsgEnum.dpSessionDesc.dwSession,
  1560. m_spmsgEnum.dpSessionDesc.szSessionName));
  1561. _try
  1562. {
  1563. if ((m_fpEnumSessions)((LPDPSESSIONDESC) &m_spmsgEnum.dpSessionDesc,
  1564. m_lpvSessionContext, NULL, 0 ) == FALSE)
  1565. {
  1566. m_fpEnumSessions = NULL;
  1567. bDone = TRUE;
  1568. TSHELL_INFO(TEXT("End EnumSessions."));
  1569. }
  1570. else
  1571. {
  1572. if (dwTimeout != 0xffffffff)
  1573. {
  1574. dwTimeNow = GetTickCount();
  1575. if ( (dwTimeNow - dwTimeBegin) > dwTimeout)
  1576. dwTimeout = 0;
  1577. else
  1578. {
  1579. dwTimeout -= (dwTimeNow - dwTimeBegin);
  1580. dwTimeBegin = dwTimeNow;
  1581. }
  1582. }
  1583. }
  1584. }
  1585. _except(EXCEPTION_EXECUTE_HANDLER)
  1586. {
  1587. m_fpEnumSessions = NULL;
  1588. bDone = TRUE;
  1589. TSHELL_INFO(TEXT("Exception encountered."));
  1590. }
  1591. }
  1592. }
  1593. else
  1594. {
  1595. bDone = TRUE;
  1596. }
  1597. EnumDataUnlock();
  1598. DBG_INFO((DBGARG, TEXT("Tick %d"), GetTickCount()));
  1599. }
  1600. return((bFound) ? DP_OK : DPERR_NOSESSIONS);
  1601. }
  1602. VOID CImpIDP_SP::ISend(
  1603. LONG iFrom,
  1604. LONG iTo,
  1605. DWORD dwFlags,
  1606. LPVOID lpvBuffer,
  1607. DWORD dwBuffSize)
  1608. {
  1609. MSG_BUILDER *pMsg;
  1610. DWORD ii;
  1611. LONG iIndexT;
  1612. ParanoiaLock();
  1613. if (m_aPlayer[iTo].bPlayer == FALSE)
  1614. {
  1615. for (ii = 0; ii < MAX_PLAYERS; ii++)
  1616. {
  1617. if (m_aPlayer[iTo].aGroup[ii])
  1618. {
  1619. if ((iIndexT = GetPlayerIndex(m_aPlayer[iTo].aGroup[ii])) != -1)
  1620. ISend(iFrom, iIndexT, dwFlags, lpvBuffer, dwBuffSize);
  1621. }
  1622. }
  1623. }
  1624. else
  1625. {
  1626. if (m_aPlayer[iTo].bLocal)
  1627. {
  1628. AddMessage(lpvBuffer,
  1629. dwBuffSize,
  1630. m_aPlayer[iTo].pid,
  1631. m_aPlayer[iFrom].pid,
  1632. dwFlags & DPSEND_HIGHPRIORITY);
  1633. }
  1634. else
  1635. {
  1636. char chBuffer[MAX_MSG];
  1637. pMsg = (MSG_BUILDER *) chBuffer;
  1638. pMsg->dpHdr.usCookie = (dwFlags & DPSEND_HIGHPRIORITY) ? DPSYS_HIGH : DPSYS_USER;
  1639. pMsg->dpHdr.to = (USHORT) m_aPlayer[iTo].pid;
  1640. pMsg->dpHdr.from = (USHORT) m_aPlayer[iFrom].pid;
  1641. pMsg->dpHdr.usCount = (USHORT) dwBuffSize;
  1642. pMsg->dpHdr.usGame = (USHORT) m_usGameCookie;
  1643. memcpy( pMsg->chMsgCompose, lpvBuffer, dwBuffSize);
  1644. PostPlayerMessage( iTo, (LPVOID) pMsg, sizeof(DPHDR) + dwBuffSize);
  1645. }
  1646. }
  1647. ParanoiaUnlock();
  1648. }
  1649. // ----------------------------------------------------------
  1650. // Send - transmit data over socket.
  1651. // ----------------------------------------------------------
  1652. HRESULT CImpIDP_SP::Send(
  1653. DPID from,
  1654. DPID to,
  1655. DWORD dwFlags,
  1656. LPVOID lpvBuffer,
  1657. DWORD dwBuffSize)
  1658. {
  1659. DWORD ii;
  1660. LONG iFrom;
  1661. BOOL bSent = FALSE;
  1662. if (from == 0)
  1663. {
  1664. return(DPERR_INVALIDPID);
  1665. }
  1666. if (dwBuffSize > MAX_MSG)
  1667. return(DPERR_SENDTOOBIG);
  1668. ParanoiaLock();
  1669. iFrom = GetPlayerIndex(from);
  1670. #ifdef DEBUG
  1671. DBG_INFO((DBGARG, TEXT("Send From Pid %d Player Index %d"), from, iFrom));
  1672. if (iFrom == -1)
  1673. for (ii = 0; ii < MAX_PLAYERS; ii++)
  1674. {
  1675. DBG_INFO((DBGARG, TEXT("Index %d Valid %d Pid %d Local %d"),
  1676. ii,
  1677. m_aPlayer[ii].bValid,
  1678. m_aPlayer[ii].pid,
  1679. m_aPlayer[ii].bLocal));
  1680. }
  1681. #endif
  1682. if (iFrom == -1 || ! m_aPlayer[iFrom].bLocal)
  1683. {
  1684. ParanoiaUnlock();
  1685. return(DPERR_INVALIDPID);
  1686. }
  1687. for (ii = 0; ii < MAX_PLAYERS; ii++)
  1688. if (m_aPlayer[ii].bValid && m_aPlayer[ii].pid != from)
  1689. {
  1690. if ( (to == 0 && m_aPlayer[ii].bPlayer == TRUE)
  1691. || m_aPlayer[ii].pid == to)
  1692. {
  1693. ISend(iFrom, ii, dwFlags, lpvBuffer, dwBuffSize);
  1694. bSent = TRUE;
  1695. }
  1696. }
  1697. ParanoiaUnlock();
  1698. return(bSent ? DP_OK : DPERR_INVALIDPID);
  1699. }
  1700. // ----------------------------------------------------------
  1701. // Receive - receive message
  1702. // ----------------------------------------------------------
  1703. HRESULT CImpIDP_SP::Receive(
  1704. LPDPID pidfrom,
  1705. LPDPID pidto,
  1706. DWORD dwFlags,
  1707. LPVOID lpvBuffer,
  1708. LPDWORD lpdwSize)
  1709. {
  1710. HRESULT hr;
  1711. LONG iIndex;
  1712. BOOL bb;
  1713. ParanoiaLock();
  1714. bb = TRUE;
  1715. if (dwFlags & DPRECEIVE_TOPLAYER)
  1716. {
  1717. iIndex = GetPlayerIndex(*pidto);
  1718. if (iIndex == -1 || m_aPlayer[iIndex].bPlayer == FALSE)
  1719. bb = FALSE;
  1720. }
  1721. if ((dwFlags & DPRECEIVE_FROMPLAYER) && *pidfrom != 0)
  1722. {
  1723. iIndex = GetPlayerIndex(*pidfrom);
  1724. if (iIndex == -1 || m_aPlayer[iIndex].bPlayer == FALSE)
  1725. bb = FALSE;
  1726. }
  1727. ParanoiaUnlock();
  1728. if (bb == FALSE)
  1729. {
  1730. return(DPERR_INVALIDPID);
  1731. }
  1732. hr = GetQMessage(lpvBuffer, lpdwSize, pidto, pidfrom, dwFlags,
  1733. dwFlags & DPRECEIVE_PEEK);
  1734. return(hr);
  1735. }
  1736. HRESULT CImpIDP_SP::SetPlayerName(
  1737. DPID pid,
  1738. LPSTR lpFriendlyName,
  1739. LPSTR lpFormalName,
  1740. BOOL bPlayer)
  1741. {
  1742. SPMSG_ADDPLAYER spmsg_addplayer;
  1743. SPMSG_ADDPLAYER *pMsg;
  1744. //
  1745. // Send DPSYS_SETPLAYER to nameserver.
  1746. //
  1747. ParanoiaLock();
  1748. LONG iIndex = GetPlayerIndex(pid);
  1749. if (iIndex == -1 || m_aPlayer[iIndex].bPlayer != bPlayer)
  1750. {
  1751. ParanoiaUnlock();
  1752. return(DPERR_INVALIDPLAYER);
  1753. }
  1754. lstrcpyn( m_aPlayer[iIndex].chNickName, lpFriendlyName, DPSHORTNAMELEN);
  1755. lstrcpyn( m_aPlayer[iIndex].chFullName, lpFormalName , DPLONGNAMELEN);
  1756. pMsg = &spmsg_addplayer;
  1757. pMsg->dpHdr.usCookie = DPSYS_SYS;
  1758. pMsg->dpHdr.to = 0;
  1759. pMsg->dpHdr.from = 0;
  1760. pMsg->dpHdr.usCount = SIZE_ADDPLAYER;
  1761. pMsg->dpHdr.usGame = (USHORT) m_usGameCookie;
  1762. pMsg->sMsg.dwType = DPSYS_SETPLAYER;
  1763. pMsg->sMsg.dwPlayerType = bPlayer;
  1764. pMsg->sMsg.dpId = m_aPlayer[iIndex].pid;
  1765. pMsg->sMsg.dwCurrentPlayers = m_dpDesc.dwCurrentPlayers;
  1766. lstrcpy( pMsg->sMsg.szShortName, lpFriendlyName);
  1767. lstrcpy( pMsg->sMsg.szLongName, lpFormalName);
  1768. memcpy( &pMsg->sockaddr, &m_aPlayer[iIndex].sockaddr, sizeof(SOCKADDR));
  1769. if (m_bPlayer0)
  1770. {
  1771. LocalMsg( iIndex, (LPVOID) pMsg, sizeof(DPMSG_ADDPLAYER));
  1772. PostGameMessage( (LPVOID) pMsg, sizeof(SPMSG_ADDPLAYER));
  1773. }
  1774. else
  1775. {
  1776. PostNSMessage( pMsg, sizeof(SPMSG_ADDPLAYER));
  1777. }
  1778. ParanoiaUnlock();
  1779. return(DP_OK);
  1780. }
  1781. HRESULT CImpIDP_SP::SaveSession(LPVOID lpv, LPDWORD lpdw)
  1782. {
  1783. return(DPERR_UNSUPPORTED);
  1784. }
  1785. HRESULT CImpIDP_SP::SetPrevSession(LPSTR lpName, LPVOID lpv, DWORD dw)
  1786. {
  1787. return(DPERR_UNSUPPORTED);
  1788. }
  1789. HRESULT CImpIDP_SP::SetPrevPlayer(LPSTR lpName, LPVOID lpv, DWORD dw)
  1790. {
  1791. //
  1792. //
  1793. // This doesn't make sense for a serial point to point SP.
  1794. //
  1795. TSHELL_INFO( TEXT("not currently supported") );
  1796. return(DPERR_UNSUPPORTED);
  1797. }
  1798. HRESULT CImpIDP_SP::EnableNewPlayers(BOOL bEnable)
  1799. {
  1800. //
  1801. // Implementation not set, and won't follow this calling convention.
  1802. // ignore for now.
  1803. //
  1804. SPMSG_ENABLEPLAYER spmsg_enableplayer;
  1805. SPMSG_ENABLEPLAYER *pMsg = &spmsg_enableplayer;
  1806. m_bEnablePlayerAdd = bEnable;
  1807. pMsg->dpHdr.usCookie = DPSYS_SYS;
  1808. pMsg->dpHdr.to = 0;
  1809. pMsg->dpHdr.from = 0;
  1810. pMsg->dpHdr.usCount = sizeof(DPMSG_ENABLEPLAYER);
  1811. pMsg->dpHdr.usGame = (USHORT) m_usGameCookie;
  1812. pMsg->sMsg.dwType = DPSYS_ENABLEPLAYER;
  1813. pMsg->sMsg.bEnable = bEnable;
  1814. if (! m_bPlayer0)
  1815. PostNSMessage( pMsg, sizeof(SPMSG_ENABLEPLAYER));
  1816. else
  1817. PostGameMessage( pMsg, sizeof(SPMSG_ENABLEPLAYER));
  1818. return(DP_OK);
  1819. }
  1820. HRESULT CImpIDP_SP::GetPlayerCaps(
  1821. DPID pid,
  1822. LPDPCAPS lpDPCaps)
  1823. {
  1824. LONG iIndex = GetPlayerIndex(pid);
  1825. if (iIndex == -1 || m_aPlayer[iIndex].bPlayer == FALSE)
  1826. return(DPERR_INVALIDPID);
  1827. *lpDPCaps = m_dpcaps;
  1828. if (m_aPlayer[iIndex].bLocal)
  1829. lpDPCaps->dwLatency = 1;
  1830. return(DP_OK);
  1831. }
  1832. HRESULT CImpIDP_SP::GetMessageCount(DPID pid, LPDWORD lpdw )
  1833. {
  1834. //
  1835. // Return count for this pid, if it is a local player we have
  1836. // been tracking with Interlock calls.
  1837. //
  1838. LONG iIndex = GetPlayerIndex((DPID) pid);
  1839. if (iIndex == -1 || m_aPlayer[iIndex].bPlayer == FALSE)
  1840. return(DPERR_INVALIDPLAYER);
  1841. if (m_aPlayer[iIndex].bLocal == FALSE)
  1842. return(DPERR_INVALIDPLAYER);
  1843. *lpdw = GetPlayerCount((DPID) pid);
  1844. return(DP_OK);
  1845. }
  1846. HRESULT CImpIDP_SP::AddPlayerToGroup(
  1847. DPID dpIdGroup,
  1848. DPID dpIdPlayer)
  1849. {
  1850. DPMSG_GROUPADD dpGAdd;
  1851. LONG iIndexG;
  1852. LONG iIndexP;
  1853. DWORD ii;
  1854. SPMSG_GROUPADD spmsg_groupadd;
  1855. SPMSG_GROUPADD *pMsg = &spmsg_groupadd;
  1856. ParanoiaLock();
  1857. iIndexG = GetPlayerIndex(dpIdGroup);
  1858. iIndexP = GetPlayerIndex(dpIdPlayer);
  1859. if ( iIndexG == -1
  1860. || m_aPlayer[iIndexG].bPlayer == TRUE
  1861. || iIndexP == -1
  1862. || m_aPlayer[iIndexP].bPlayer == FALSE)
  1863. {
  1864. ParanoiaUnlock();
  1865. return(DPERR_INVALIDPID);
  1866. }
  1867. for (ii = 0; ii < MAX_PLAYERS; ii++)
  1868. {
  1869. if (m_aPlayer[iIndexG].aGroup[ii] == m_aPlayer[iIndexP].pid)
  1870. {
  1871. ParanoiaUnlock();
  1872. return(DPERR_INVALIDPID);
  1873. }
  1874. }
  1875. for (ii = 0; ii < MAX_PLAYERS; ii++)
  1876. {
  1877. if (m_aPlayer[iIndexG].aGroup[ii] == 0)
  1878. {
  1879. dpGAdd.dwType = DPSYS_ADDPLAYERTOGROUP;
  1880. dpGAdd.dpIdGroup = m_aPlayer[iIndexG].pid;
  1881. dpGAdd.dpIdPlayer = m_aPlayer[iIndexP].pid;
  1882. ParanoiaUnlock();
  1883. pMsg->dpHdr.usCookie = DPSYS_SYS;
  1884. pMsg->dpHdr.to = 0;
  1885. pMsg->dpHdr.from = 0;
  1886. pMsg->dpHdr.usCount = sizeof(DPMSG_GROUPADD);
  1887. pMsg->dpHdr.usGame = (USHORT) m_usGameCookie;
  1888. memcpy( (LPVOID) &pMsg->sMsg, (LPVOID) &dpGAdd, sizeof(DPMSG_GROUPADD));
  1889. if (m_bPlayer0)
  1890. {
  1891. m_aPlayer[iIndexG].aGroup[ii] = m_aPlayer[iIndexP].pid;
  1892. LocalMsg(iIndexG, (LPVOID) &dpGAdd, sizeof(DPMSG_GROUPADD));
  1893. PostGameMessage( (LPVOID) pMsg, sizeof(SPMSG_GROUPADD));
  1894. }
  1895. else
  1896. {
  1897. PostNSMessage( pMsg, sizeof(SPMSG_GROUPADD));
  1898. }
  1899. return(DP_OK);
  1900. }
  1901. }
  1902. ParanoiaUnlock();
  1903. return(DPERR_GENERIC);
  1904. }
  1905. HRESULT CImpIDP_SP::DeletePlayerFromGroup(
  1906. DPID dpIdGroup,
  1907. DPID dpIdPlayer)
  1908. {
  1909. DPMSG_GROUPADD dpGAdd;
  1910. LONG iIndexG;
  1911. LONG iIndexP;
  1912. DWORD ii;
  1913. SPMSG_GROUPADD spmsg_groupadd;
  1914. SPMSG_GROUPADD *pMsg = &spmsg_groupadd;
  1915. ParanoiaLock();
  1916. iIndexG = GetPlayerIndex(dpIdGroup);
  1917. iIndexP = GetPlayerIndex(dpIdPlayer);
  1918. if ( iIndexG == -1
  1919. || m_aPlayer[iIndexG].bPlayer == TRUE
  1920. || iIndexP == -1
  1921. || m_aPlayer[iIndexP].bPlayer == FALSE)
  1922. {
  1923. ParanoiaUnlock();
  1924. return(DPERR_INVALIDPID);
  1925. }
  1926. for (ii = 0; ii < MAX_PLAYERS; ii++)
  1927. {
  1928. if (m_aPlayer[iIndexG].aGroup[ii] == m_aPlayer[iIndexP].pid)
  1929. {
  1930. dpGAdd.dwType = DPSYS_DELETEPLAYERFROMGRP;
  1931. dpGAdd.dpIdGroup = m_aPlayer[iIndexG].pid;
  1932. dpGAdd.dpIdPlayer = m_aPlayer[iIndexP].pid;
  1933. m_aPlayer[iIndexG].aGroup[ii] = 0;
  1934. ParanoiaUnlock();
  1935. pMsg->dpHdr.usCookie = DPSYS_SYS;
  1936. pMsg->dpHdr.to = 0;
  1937. pMsg->dpHdr.from = 0;
  1938. pMsg->dpHdr.usCount = sizeof(DPMSG_GROUPADD);
  1939. pMsg->dpHdr.usGame = (USHORT) m_usGameCookie;
  1940. memcpy( (LPVOID) &pMsg->sMsg, (LPVOID) &dpGAdd, sizeof(DPMSG_GROUPADD));
  1941. if (m_bPlayer0)
  1942. {
  1943. LocalMsg(iIndexG, (LPVOID) &dpGAdd, sizeof(DPMSG_GROUPADD));
  1944. PostGameMessage( (LPVOID) pMsg, sizeof(SPMSG_GROUPADD));
  1945. }
  1946. else
  1947. {
  1948. PostNSMessage( pMsg, sizeof(SPMSG_GROUPADD));
  1949. }
  1950. return(DP_OK);
  1951. }
  1952. }
  1953. ParanoiaUnlock();
  1954. return(DPERR_INVALIDPID);
  1955. }
  1956. VOID CImpIDP_SP::HandleMessage(LPVOID lpv, DWORD dwSize, SOCKADDR *pSAddr, INT SockAddrLen)
  1957. {
  1958. DPHDR *pHdr;
  1959. BOOL bHigh = FALSE;
  1960. DPID pidTo, pidFrom;
  1961. DWORD ii;
  1962. SPMSG_ADDPLAYER *pAddPlayer;
  1963. LONG iIndex;
  1964. pHdr = (DPHDR *) lpv;
  1965. // TSHELL_INFO(TEXT("HandleMessage entered."));
  1966. switch(pHdr->usCookie)
  1967. {
  1968. default:
  1969. TSHELL_INFO(TEXT("Unknown message value"));
  1970. break;
  1971. case DPSYS_HIGH:
  1972. bHigh = TRUE;
  1973. //
  1974. // Fall Through!
  1975. //
  1976. case DPSYS_USER:
  1977. pidTo = 0x00ff & ((DPID) pHdr->to);
  1978. pidFrom = 0x00ff & ((DPID) pHdr->from);
  1979. dwSize = (DWORD) ((DPID) pHdr->usCount);
  1980. iIndex = GetPlayerIndex(pidTo);
  1981. if ( pidTo == 0
  1982. || iIndex != -1)
  1983. {
  1984. AddMessage((LPVOID) (((LPBYTE) lpv) + sizeof(DPHDR)), dwSize,
  1985. pidTo, pidFrom, bHigh);
  1986. }
  1987. iIndex = GetPlayerIndex(pidFrom);
  1988. if ( pidFrom != 0
  1989. && (iIndex == -1))
  1990. {
  1991. SPMSG_GETPLAYER spmsg_getplayer;
  1992. SPMSG_GETPLAYER *pMsg = &spmsg_getplayer;
  1993. pMsg->dpHdr.usCookie = DPSYS_SYS;
  1994. pMsg->dpHdr.to = 0;
  1995. pMsg->dpHdr.from = 0;
  1996. pMsg->dpHdr.usCount = sizeof(DPMSG_GETPLAYER);
  1997. pMsg->dpHdr.usGame = (USHORT) m_usGameCookie;
  1998. pMsg->sMsg.dwType = DPSYS_GETPLAYER;
  1999. pMsg->sMsg.dpId = pidFrom;
  2000. PostNSMessage((LPVOID) pMsg, sizeof(SPMSG_GETPLAYER));
  2001. }
  2002. break;
  2003. case DPSYS_SYS:
  2004. TSHELL_INFO(TEXT("HandleMessage System Message."));
  2005. switch(((SPMSG_GENERIC *)lpv)->sMsg.dwType)
  2006. {
  2007. default:
  2008. DBG_INFO((DBGARG, TEXT("Unknown Type %x"), ((SPMSG_GENERIC *)lpv)->sMsg.dwType));
  2009. break;
  2010. case DPSYS_ENABLEPLAYER:
  2011. {
  2012. SPMSG_ENABLEPLAYER *pMsg;
  2013. pMsg = (SPMSG_ENABLEPLAYER *) lpv;
  2014. if (pMsg->dpHdr.usCount == sizeof(DPMSG_ENABLEPLAYER))
  2015. {
  2016. if (m_bPlayer0 && m_bEnablePlayerAdd != pMsg->sMsg.bEnable)
  2017. PostGameMessage( (LPVOID) pMsg, sizeof(SPMSG_ENABLEPLAYER));
  2018. m_bEnablePlayerAdd = pMsg->sMsg.bEnable;
  2019. }
  2020. }
  2021. break;
  2022. case DPSYS_DELETEPLAYERFROMGRP:
  2023. case DPSYS_ADDPLAYERTOGROUP:
  2024. case DPSYS_SETGROUPPLAYER:
  2025. {
  2026. SPMSG_GROUPADD *pMsg;
  2027. LONG iIndexG;
  2028. LONG iIndexP;
  2029. pMsg = (SPMSG_GROUPADD *) lpv;
  2030. if (pMsg->dpHdr.usCount == sizeof(DPMSG_GROUPADD))
  2031. {
  2032. ParanoiaLock();
  2033. iIndexG = GetPlayerIndex(pMsg->sMsg.dpIdGroup);
  2034. iIndexP = GetPlayerIndex(pMsg->sMsg.dpIdPlayer);
  2035. if ( iIndexG == -1
  2036. || m_aPlayer[iIndexG].bPlayer == TRUE
  2037. || iIndexP == -1
  2038. || m_aPlayer[iIndexP].bPlayer == FALSE)
  2039. {
  2040. TSHELL_INFO(TEXT("Invalid GroupAdd message."));
  2041. }
  2042. else
  2043. {
  2044. if ( pMsg->sMsg.dwType == DPSYS_ADDPLAYERTOGROUP
  2045. || pMsg->sMsg.dwType == DPSYS_SETGROUPPLAYER)
  2046. {
  2047. for (ii = 0; ii < MAX_PLAYERS; ii++)
  2048. if (m_aPlayer[iIndexG].aGroup[ii] == 0)
  2049. {
  2050. m_aPlayer[iIndexG].aGroup[ii] = m_aPlayer[iIndexP].pid;
  2051. break;
  2052. }
  2053. }
  2054. else
  2055. {
  2056. for (ii = 0; ii < MAX_PLAYERS; ii++)
  2057. if (m_aPlayer[iIndexG].aGroup[ii] == m_aPlayer[iIndexP].pid)
  2058. {
  2059. m_aPlayer[iIndexG].aGroup[ii] = 0;
  2060. }
  2061. }
  2062. if (pMsg->sMsg.dwType != DPSYS_SETGROUPPLAYER)
  2063. {
  2064. LocalMsg(iIndexG, (LPVOID) &pMsg->sMsg, sizeof(DPMSG_GROUPADD));
  2065. if (m_bPlayer0)
  2066. {
  2067. PostGameMessage( (LPVOID) pMsg, sizeof(SPMSG_GROUPADD));
  2068. }
  2069. }
  2070. }
  2071. ParanoiaUnlock();
  2072. }
  2073. else
  2074. {
  2075. TSHELL_INFO(TEXT("Invalid size on system message"));
  2076. }
  2077. }
  2078. break;
  2079. case DPSYS_SENDDESC:
  2080. {
  2081. SPMSG_SENDDESC *pMsg;
  2082. pMsg = (SPMSG_SENDDESC *) lpv;
  2083. if (pMsg->dpHdr.usCount == SIZE_SENDDESC)
  2084. {
  2085. memcpy( (LPVOID) &m_dpDesc, (LPVOID) &pMsg->sMsg.dpDesc, sizeof(m_dpDesc));
  2086. // DBG_INFO((DBGARG, TEXT("New Description. Current Players %d"),
  2087. // m_dpDesc.dwCurrentPlayers));
  2088. }
  2089. }
  2090. break;
  2091. case DPSYS_PING:
  2092. {
  2093. SPMSG_PING *pMsg;
  2094. pMsg = (SPMSG_PING *) lpv;
  2095. if (pMsg->dpHdr.usCount == SIZE_PING)
  2096. {
  2097. if (pMsg->dwTicks == m_dwPingSent)
  2098. {
  2099. m_dpcaps.dwLatency = (GetTickCount() - m_dwPingSent) /2;
  2100. m_dwPingSent = 0;
  2101. // TSHELL_INFO(TEXT("Latency Accepted from our Ping."));
  2102. }
  2103. else
  2104. {
  2105. SPMSG_PING spmsg_ping;
  2106. SPMSG_PING *pMsg2 = &spmsg_ping;
  2107. UINT uiSize = sizeof(SPMSG_PING);
  2108. memcpy( (LPVOID) pMsg2, (LPVOID) pMsg, sizeof(SPMSG_PING));
  2109. SendTo(m_ClientSocket, pSAddr, SockAddrLen, (char *)pMsg2, &uiSize);
  2110. // TSHELL_INFO(TEXT("Return Ping."));
  2111. }
  2112. TSHELL_INFO(TEXT("Ping Recieved."));
  2113. }
  2114. }
  2115. break;
  2116. case DPSYS_SETPLAYER:
  2117. {
  2118. SPMSG_SETPLAYER *pSetPlayer;
  2119. pSetPlayer = (SPMSG_SETPLAYER *) lpv;
  2120. TSHELL_INFO(TEXT("Received SETPLAYER message"));
  2121. if (pSetPlayer->dpHdr.usCount == SIZE_SETPLAYER)
  2122. {
  2123. ParanoiaLock();
  2124. iIndex = GetPlayerIndex(pSetPlayer->sMsg.dpId);
  2125. if (iIndex != -1)
  2126. {
  2127. if (m_aPlayer[iIndex].bPlayer == (BOOL) pSetPlayer->sMsg.dwPlayerType)
  2128. {
  2129. lstrcpyn( m_aPlayer[iIndex].chNickName, pSetPlayer->sMsg.szShortName, DPSHORTNAMELEN);
  2130. lstrcpyn( m_aPlayer[iIndex].chFullName, pSetPlayer->sMsg.szLongName , DPLONGNAMELEN);
  2131. m_dpDesc.dwCurrentPlayers = pSetPlayer->sMsg.dwCurrentPlayers;
  2132. }
  2133. TSHELL_INFO(TEXT("Name change through SETPLAYER"));
  2134. }
  2135. else if ( !m_bPlayer0
  2136. && ((iIndex = FindInvalidIndex()) != -1))
  2137. {
  2138. if (!pSetPlayer->sMsg.dwPlayerType)
  2139. {
  2140. m_aPlayer[iIndex].aGroup = (DPID *) lmalloc(sizeof(DPID) * MAX_PLAYERS);
  2141. if (m_aPlayer[iIndex].aGroup != NULL)
  2142. memset(m_aPlayer[iIndex].aGroup, 0x00, sizeof(DPID) * MAX_PLAYERS);
  2143. else
  2144. pSetPlayer->sMsg.dwPlayerType = TRUE; // Critical failure.
  2145. }
  2146. lstrcpy( m_aPlayer[iIndex].chNickName, pSetPlayer->sMsg.szShortName);
  2147. lstrcpy( m_aPlayer[iIndex].chFullName, pSetPlayer->sMsg.szLongName);
  2148. m_aPlayer[iIndex].bValid = TRUE;
  2149. m_aPlayer[iIndex].bPlayer = pSetPlayer->sMsg.dwPlayerType;
  2150. m_aPlayer[iIndex].bLocal = FALSE;
  2151. memcpy(&m_aPlayer[iIndex].sockaddr, pSAddr, sizeof(SOCKADDR));
  2152. m_aPlayer[iIndex].pid = pSetPlayer->sMsg.dpId;
  2153. m_dpDesc.dwCurrentPlayers = pSetPlayer->sMsg.dwCurrentPlayers;
  2154. TSHELL_INFO(TEXT("Remote player updated with SETPLAYER."));
  2155. }
  2156. if (iIndex != -1)
  2157. {
  2158. if (pSetPlayer->sockaddr.sa_family == 0)
  2159. memcpy(&m_aPlayer[iIndex].sockaddr, &m_NSSockAddr, sizeof(SOCKADDR));
  2160. else
  2161. memcpy(&m_aPlayer[iIndex].sockaddr, &pSetPlayer->sockaddr, sizeof(SOCKADDR));
  2162. }
  2163. ParanoiaUnlock();
  2164. }
  2165. }
  2166. break;
  2167. case DPSYS_ADDPLAYER:
  2168. {
  2169. pAddPlayer = (SPMSG_ADDPLAYER *) lpv;
  2170. if (pAddPlayer->dpHdr.usCount == SIZE_ADDPLAYER)
  2171. {
  2172. if (m_bEnablePlayerAdd == FALSE && pAddPlayer->sMsg.dwPlayerType == TRUE)
  2173. break;
  2174. if (m_bPlayer0)
  2175. {
  2176. if (pAddPlayer->dpHdr.usSeq == m_usSeqSys)
  2177. {
  2178. TSHELL_INFO(TEXT("We have seen this before."));
  2179. //
  2180. // BUGBUG, search our list and try to find a player
  2181. // we have already created and give them that.
  2182. //
  2183. break;
  2184. }
  2185. ParanoiaLock();
  2186. TSHELL_INFO(TEXT("Begin AddPlayer Processing Player 0."));
  2187. if ( m_dpDesc.dwMaxPlayers >= m_dpDesc.dwCurrentPlayers
  2188. && pAddPlayer->sMsg.dpId == 0
  2189. && ((iIndex = FindInvalidIndex()) != -1))
  2190. {
  2191. SPMSG_ADDPLAYER spmsg_addplayer;
  2192. SPMSG_ADDPLAYER *pReplyMsg = &spmsg_addplayer;
  2193. if (!pAddPlayer->sMsg.dwPlayerType)
  2194. {
  2195. m_aPlayer[iIndex].aGroup = (DPID *) lmalloc(sizeof(DPID) * MAX_PLAYERS);
  2196. if (m_aPlayer[iIndex].aGroup != NULL)
  2197. memset(m_aPlayer[iIndex].aGroup, 0x00, sizeof(DPID) * MAX_PLAYERS);
  2198. else
  2199. pAddPlayer->sMsg.dwPlayerType = TRUE; // Critical failure.
  2200. }
  2201. pAddPlayer->sMsg.dwCurrentPlayers = ++m_dpDesc.dwCurrentPlayers;
  2202. m_aPlayer[iIndex].pid = (DPID) m_dwNextPlayer++;
  2203. lstrcpy( m_aPlayer[iIndex].chNickName, pAddPlayer->sMsg.szShortName);
  2204. lstrcpy( m_aPlayer[iIndex].chFullName, pAddPlayer->sMsg.szLongName);
  2205. m_aPlayer[iIndex].bValid = TRUE;
  2206. m_aPlayer[iIndex].bPlayer = pAddPlayer->sMsg.dwPlayerType;
  2207. m_aPlayer[iIndex].bLocal = FALSE;
  2208. memcpy(&m_aPlayer[iIndex].sockaddr, pSAddr, sizeof(SOCKADDR));
  2209. memcpy(&pAddPlayer->sockaddr, pSAddr, sizeof(SOCKADDR));
  2210. pAddPlayer->sMsg.dpId = m_aPlayer[iIndex].pid;
  2211. TSHELL_INFO(TEXT("Replying to AddPlayer message."));
  2212. m_usSeqSys = pAddPlayer->dpHdr.usSeq;
  2213. pAddPlayer->dpHdr.usSeq = NextSequence();
  2214. memcpy((LPVOID) pReplyMsg, (LPVOID) pAddPlayer,
  2215. sizeof(SPMSG_ADDPLAYER));
  2216. PostGameMessage( (LPVOID) pReplyMsg, sizeof(SPMSG_ADDPLAYER));
  2217. LocalMsg(iIndex, &pAddPlayer->sMsg, sizeof(DPMSG_ADDPLAYER));
  2218. }
  2219. else
  2220. {
  2221. TSHELL_INFO(TEXT("Ignoring message, it will timeout."));
  2222. }
  2223. ParanoiaUnlock();
  2224. }
  2225. //
  2226. // Ignore it it we already know about this player.
  2227. //
  2228. else if (GetPlayerIndex(pAddPlayer->sMsg.dpId) == -1)
  2229. {
  2230. TSHELL_INFO(TEXT("Begin AddPlayer Processing Remote."));
  2231. ParanoiaLock();
  2232. #ifdef DEBUG
  2233. if (m_dpDesc.dwCurrentPlayers != pAddPlayer->sMsg.dwCurrentPlayers)
  2234. {
  2235. DBG_INFO((DBGARG, TEXT("Adjusting local count of players from %d to %d"),
  2236. m_dpDesc.dwCurrentPlayers,
  2237. pAddPlayer->sMsg.dwCurrentPlayers));
  2238. }
  2239. #endif
  2240. m_dpDesc.dwCurrentPlayers = pAddPlayer->sMsg.dwCurrentPlayers;
  2241. iIndex = FindInvalidIndex();
  2242. if ((iIndex = FindInvalidIndex()) != -1)
  2243. {
  2244. if (!pAddPlayer->sMsg.dwPlayerType)
  2245. {
  2246. m_aPlayer[iIndex].aGroup = (DPID *) lmalloc(sizeof(DPID) * MAX_PLAYERS);
  2247. if (m_aPlayer[iIndex].aGroup != NULL)
  2248. memset(m_aPlayer[iIndex].aGroup, 0x00, sizeof(DPID) * MAX_PLAYERS);
  2249. else
  2250. pAddPlayer->sMsg.dwPlayerType = TRUE; // Critical failure.
  2251. }
  2252. lstrcpy( m_aPlayer[iIndex].chNickName, pAddPlayer->sMsg.szShortName);
  2253. lstrcpy( m_aPlayer[iIndex].chFullName, pAddPlayer->sMsg.szLongName);
  2254. m_aPlayer[iIndex].bValid = TRUE;
  2255. m_aPlayer[iIndex].bPlayer = pAddPlayer->sMsg.dwPlayerType;
  2256. if (pAddPlayer->sockaddr.sa_family == 0)
  2257. memcpy(&m_aPlayer[iIndex].sockaddr, &m_NSSockAddr, sizeof(SOCKADDR));
  2258. else
  2259. memcpy(&m_aPlayer[iIndex].sockaddr, &pAddPlayer->sockaddr, sizeof(SOCKADDR));
  2260. m_aPlayer[iIndex].pid = pAddPlayer->sMsg.dpId;
  2261. if (m_hNewPlayerEvent && pAddPlayer->dwUnique == m_dwUnique)
  2262. {
  2263. m_aPlayer[iIndex].bLocal = TRUE;
  2264. m_iPlayerIndex = iIndex;
  2265. SetEvent(m_hNewPlayerEvent);
  2266. }
  2267. else
  2268. {
  2269. m_aPlayer[iIndex].bLocal = FALSE;
  2270. }
  2271. LocalMsg(iIndex, &pAddPlayer->sMsg, sizeof(DPMSG_ADDPLAYER));
  2272. }
  2273. ParanoiaUnlock();
  2274. }
  2275. }
  2276. else
  2277. {
  2278. TSHELL_INFO(TEXT("Invalid size on system message ADDPLAYER"));
  2279. }
  2280. }
  2281. break;
  2282. case DPSYS_DELETEGROUP:
  2283. case DPSYS_DELETEPLAYER:
  2284. {
  2285. SPMSG_GETPLAYER *pMsg;
  2286. SPMSG_GETPLAYER spmsg_getplayer;
  2287. SPMSG_GETPLAYER *pMsg2 = &spmsg_getplayer;
  2288. pMsg = (SPMSG_GETPLAYER *) lpv;
  2289. TSHELL_INFO(TEXT("Got Delete"));
  2290. if (pMsg->dpHdr.usCount == SIZE_GETPLAYER)
  2291. {
  2292. ParanoiaLock();
  2293. if ((iIndex = GetPlayerIndex(pMsg->sMsg.dpId)) != -1)
  2294. {
  2295. if (m_bPlayer0)
  2296. {
  2297. TSHELL_INFO(TEXT("Player 0 Pings Delete."));
  2298. memcpy( (LPVOID) pMsg2, (LPVOID) pMsg, sizeof(SPMSG_GETPLAYER));
  2299. PostGameMessage( (LPVOID) pMsg2, sizeof(SPMSG_GETPLAYER));
  2300. }
  2301. m_dpDesc.dwCurrentPlayers--;
  2302. if (m_aPlayer[iIndex].bLocal)
  2303. {
  2304. CloseHandle(m_aPlayer[iIndex].hEvent);
  2305. FlushQueue(m_aPlayer[iIndex].pid);
  2306. }
  2307. m_aPlayer[iIndex].bValid = FALSE;
  2308. if (m_aPlayer[iIndex].aGroup)
  2309. lfree(m_aPlayer[iIndex].aGroup);
  2310. LocalMsg(iIndex, (LPVOID) &pMsg->sMsg, sizeof(DPMSG_GETPLAYER));
  2311. if (pMsg->sMsg.dwType == DPSYS_DELETEPLAYER)
  2312. {
  2313. DWORD ii, jj;
  2314. for (ii = 0; ii < MAX_PLAYERS; ii++)
  2315. {
  2316. if ( m_aPlayer[ii].bValid == TRUE
  2317. && m_aPlayer[ii].bPlayer == FALSE
  2318. && m_aPlayer[ii].aGroup)
  2319. {
  2320. for (jj = 0; jj < MAX_PLAYERS; jj++)
  2321. {
  2322. if (m_aPlayer[ii].aGroup[jj] == pMsg->sMsg.dpId)
  2323. {
  2324. m_aPlayer[ii].aGroup[jj] = 0;
  2325. break;
  2326. }
  2327. }
  2328. }
  2329. }
  2330. }
  2331. }
  2332. ParanoiaUnlock();
  2333. }
  2334. else
  2335. {
  2336. TSHELL_INFO(TEXT("Invalid size on system message"));
  2337. }
  2338. }
  2339. break;
  2340. case DPSYS_GETPLAYER:
  2341. {
  2342. DPID pid = ((SPMSG_GETPLAYER *) lpv)->sMsg.dpId;
  2343. BOOL bFound = FALSE;
  2344. if (m_bPlayer0)
  2345. {
  2346. ParanoiaLock();
  2347. if ((iIndex = GetPlayerIndex((DPID) pid)) != -1)
  2348. {
  2349. SPMSG_ADDPLAYER spmsg_addplayer;
  2350. SPMSG_ADDPLAYER *pMsg = &spmsg_addplayer;
  2351. pMsg->dpHdr.usCookie = DPSYS_SYS;
  2352. pMsg->dpHdr.to = 0;
  2353. pMsg->dpHdr.from = 0;
  2354. pMsg->dpHdr.usCount = SIZE_ADDPLAYER;
  2355. pMsg->sMsg.dwType = DPSYS_SETPLAYER;
  2356. pMsg->sMsg.dwPlayerType = m_aPlayer[iIndex].bPlayer;
  2357. pMsg->sMsg.dpId = pid;
  2358. pMsg->sMsg.dwCurrentPlayers = m_dpDesc.dwCurrentPlayers;
  2359. lstrcpy( pMsg->sMsg.szShortName, m_aPlayer[iIndex].chNickName);
  2360. lstrcpy( pMsg->sMsg.szLongName, m_aPlayer[iIndex].chFullName);
  2361. dwSize = sizeof(SPMSG_SETPLAYER);
  2362. SendTo(m_ClientSocket, pSAddr, SockAddrLen, (char *)pMsg, (LPUINT) &dwSize);
  2363. }
  2364. ParanoiaUnlock();
  2365. }
  2366. }
  2367. break;
  2368. case DPSYS_ENUMPLAYERRESP:
  2369. {
  2370. SPMSG_ADDPLAYER *pMsg;
  2371. pMsg = (SPMSG_ADDPLAYER *) lpv;
  2372. TSHELL_INFO(TEXT("Got a remote Player."));
  2373. PlayerDataLock();
  2374. if (m_fpEnumPlayers)
  2375. {
  2376. memcpy( (LPVOID) &m_spmsgAddPlayer, pMsg, sizeof(SPMSG_ADDPLAYER));
  2377. SetEvent(m_hPlayerBlkEventMain);
  2378. TSHELL_INFO(TEXT("Player should be processing in main thread shortly."));
  2379. PlayerDataUnlock();
  2380. WaitForSingleObject(m_hPlayerBlkEventRead, 5000);
  2381. ResetEvent(m_hPlayerBlkEventRead);
  2382. }
  2383. else
  2384. {
  2385. TSHELL_INFO(TEXT("Ignore remote player because callback null."));
  2386. PlayerDataUnlock();
  2387. }
  2388. }
  2389. break;
  2390. case DPSYS_ENUMALLPLAYERS:
  2391. {
  2392. if (m_bPlayer0)
  2393. {
  2394. SPMSG_ADDPLAYER spmsg_addplayer;
  2395. SPMSG_ADDPLAYER *pMsg = &spmsg_addplayer;
  2396. pMsg->dpHdr.usCookie = DPSYS_SYS;
  2397. pMsg->dpHdr.to = 0;
  2398. pMsg->dpHdr.from = 0;
  2399. pMsg->dpHdr.usCount = SIZE_ADDPLAYER;
  2400. pMsg->sMsg.dwType = DPSYS_ENUMPLAYERRESP;
  2401. pMsg->sMsg.dwPlayerType = TRUE;
  2402. pMsg->sMsg.dwCurrentPlayers = m_dpDesc.dwCurrentPlayers;
  2403. ParanoiaLock();
  2404. for (ii = 0; ii < MAX_PLAYERS; ii++)
  2405. {
  2406. if (m_aPlayer[ii].bValid && m_aPlayer[ii].bPlayer)
  2407. {
  2408. pMsg->sMsg.dpId = m_aPlayer[ii].pid;
  2409. lstrcpy( pMsg->sMsg.szShortName, m_aPlayer[ii].chNickName);
  2410. lstrcpy( pMsg->sMsg.szLongName, m_aPlayer[ii].chFullName);
  2411. dwSize = sizeof(SPMSG_SETPLAYER);
  2412. SendTo(m_ClientSocket, pSAddr, SockAddrLen, (char *)pMsg, (LPUINT) &dwSize);
  2413. }
  2414. }
  2415. ParanoiaUnlock();
  2416. }
  2417. }
  2418. break;
  2419. }
  2420. }
  2421. }
  2422. VOID CImpIDP_SP::SendPing()
  2423. {
  2424. if (!m_bConnected)
  2425. {
  2426. return;
  2427. }
  2428. if ( m_dwPingSent
  2429. && (GetTickCount() < (m_dwPingSent + 2000)))
  2430. {
  2431. return;
  2432. }
  2433. else
  2434. m_dwPingSent = 0;
  2435. SPMSG_PING spmsg_ping;
  2436. SPMSG_PING *pMsg = &spmsg_ping;
  2437. pMsg->dpHdr.usCookie = DPSYS_SYS;
  2438. pMsg->dpHdr.to = 0;
  2439. pMsg->dpHdr.from = 0;
  2440. pMsg->dpHdr.usCount = SIZE_PING;
  2441. pMsg->dpHdr.usGame = (USHORT) m_usGameCookie;
  2442. pMsg->dwType = DPSYS_PING;
  2443. pMsg->dwTicks = m_dwPingSent = GetTickCount();
  2444. PostNSMessage( (LPVOID) pMsg, sizeof(SPMSG_PING));
  2445. }
  2446. VOID CImpIDP_SP::ConnectPlayers(SOCKADDR *pSAddr, INT SockAddrLen)
  2447. {
  2448. DWORD ii;
  2449. DWORD jj;
  2450. SPMSG_ADDPLAYER Msg;
  2451. DPMSG_ADDPLAYER dpAdd;
  2452. DWORD dwSize = sizeof(SPMSG_ADDPLAYER);
  2453. SPMSG_GROUPADD MsgG;
  2454. DPMSG_GROUPADD dpGAdd;
  2455. DWORD dwGSize = sizeof(SPMSG_GROUPADD);
  2456. dpAdd.dwType = DPSYS_SETPLAYER;
  2457. dpAdd.dpId = 0;
  2458. dpGAdd.dwType = DPSYS_SETGROUPPLAYER;
  2459. ParanoiaLock();
  2460. for (ii = 0; ii < MAX_PLAYERS; ii++)
  2461. {
  2462. if (m_aPlayer[ii].bValid )
  2463. {
  2464. dpAdd.dpId = m_aPlayer[ii].pid;
  2465. dpAdd.dwPlayerType = m_aPlayer[ii].bPlayer;
  2466. lstrcpy( dpAdd.szShortName, m_aPlayer[ii].chNickName);
  2467. lstrcpy( dpAdd.szLongName , m_aPlayer[ii].chFullName);
  2468. dpAdd.dwCurrentPlayers = m_dpDesc.dwCurrentPlayers;
  2469. Msg.dpHdr.usCookie = DPSYS_SYS;
  2470. Msg.dpHdr.to = (USHORT) m_aPlayer[ii].pid;
  2471. Msg.dpHdr.from = 0;
  2472. Msg.dpHdr.usCount = SIZE_SETPLAYER;
  2473. Msg.dpHdr.usGame = m_usGameCookie;
  2474. Msg.dpHdr.usSeq = NextSequence();
  2475. memcpy( (LPVOID) &Msg.sMsg, &dpAdd, sizeof(DPMSG_ADDPLAYER));
  2476. memcpy( (LPVOID) &Msg.sockaddr, &m_aPlayer[ii].sockaddr, sizeof(SOCKADDR));
  2477. SendTo(m_ClientSocket, pSAddr, SockAddrLen, (char *)&Msg, (LPUINT) &dwSize);
  2478. }
  2479. }
  2480. for (ii = 0; ii < MAX_PLAYERS; ii++)
  2481. {
  2482. if ( m_aPlayer[ii].bValid
  2483. && m_aPlayer[ii].bPlayer == FALSE
  2484. && m_aPlayer[ii].aGroup)
  2485. {
  2486. for (jj = 0; jj < MAX_PLAYERS; jj++)
  2487. {
  2488. if (m_aPlayer[ii].aGroup[jj] != 0)
  2489. {
  2490. MsgG.dpHdr.usCookie = DPSYS_SYS;
  2491. MsgG.dpHdr.to = 0;
  2492. MsgG.dpHdr.from = 0;
  2493. MsgG.dpHdr.usCount = SIZE_GROUPADD;
  2494. MsgG.dpHdr.usGame = m_usGameCookie;
  2495. MsgG.dpHdr.usSeq = NextSequence();
  2496. dpGAdd.dpIdGroup = m_aPlayer[ii].pid;
  2497. dpGAdd.dpIdPlayer = m_aPlayer[ii].aGroup[jj];
  2498. memcpy( (LPVOID) &MsgG.sMsg, &dpGAdd, sizeof(DPMSG_GROUPADD));
  2499. SendTo(m_ClientSocket, pSAddr, SockAddrLen, (char *)&MsgG, (LPUINT) &dwGSize);
  2500. }
  2501. }
  2502. }
  2503. }
  2504. ParanoiaUnlock();
  2505. }
  2506. VOID CImpIDP_SP::DeleteRemotePlayers()
  2507. {
  2508. DWORD ii;
  2509. DPMSG_DELETEPLAYER dpDel;
  2510. dpDel.dwType = DPSYS_DELETEPLAYER;
  2511. ParanoiaLock();
  2512. for (ii = 0; ii < MAX_PLAYERS; ii++)
  2513. {
  2514. if (m_aPlayer[ii].bValid && m_aPlayer[ii].bLocal == FALSE)
  2515. {
  2516. m_aPlayer[ii].bValid = FALSE;
  2517. if (m_aPlayer[ii].aGroup)
  2518. lfree(m_aPlayer[ii].aGroup);
  2519. m_dpDesc.dwCurrentPlayers--;
  2520. dpDel.dpId = m_aPlayer[ii].pid;
  2521. LocalMsg(-1, (LPVOID) &dpDel, sizeof(DPMSG_DELETEPLAYER));
  2522. }
  2523. }
  2524. ParanoiaUnlock();
  2525. }
  2526. BOOL CImpIDP_SP::CompareSessions(DWORD dwType, LPDPSESSIONDESC lpSDesc)
  2527. {
  2528. if ( dwType == DPSYS_OPEN
  2529. && IsEqualGUID((REFGUID) m_dpDesc.guidSession, (REFGUID) lpSDesc->guidSession)
  2530. && m_bEnablePlayerAdd == TRUE
  2531. && m_dpDesc.dwCurrentPlayers < m_dpDesc.dwMaxPlayers
  2532. && ( m_dpDesc.szPassword[0] == 0x00
  2533. || lstrcmp(m_dpDesc.szPassword, lpSDesc->szPassword) == 0))
  2534. return(TRUE);
  2535. if ( dwType == DPSYS_ENUM
  2536. && m_cMachines < MAX_PLAYERS
  2537. && ( IsEqualGUID((REFGUID) m_dpDesc.guidSession, (REFGUID) lpSDesc->guidSession)
  2538. || IsEqualGUID((REFGUID) NULL_GUID, (REFGUID) lpSDesc->guidSession))
  2539. && ( lpSDesc->dwFlags & DPENUMSESSIONS_ALL
  2540. || ( m_dpDesc.dwCurrentPlayers < m_dpDesc.dwMaxPlayers
  2541. && m_bEnablePlayerAdd == TRUE
  2542. && ( m_dpDesc.szPassword[0] == 0x00
  2543. || lstrcmp(m_dpDesc.szPassword, lpSDesc->szPassword) == 0))))
  2544. return(TRUE);
  2545. return(FALSE);
  2546. }
  2547. BOOL CImpIDP_SP::GetSessionData(DWORD dwSession)
  2548. {
  2549. DWORD ii;
  2550. NS_SESSION_SAVE *pns;
  2551. for (ii = 0; ii < m_dwSessionPrev; ii++)
  2552. {
  2553. pns = (NS_SESSION_SAVE *) m_ppSessionArray[ii];
  2554. if (pns->dpDesc.dwSession == dwSession)
  2555. {
  2556. memcpy(&m_NSSockAddr, &pns->sockaddr, sizeof(SOCKADDR));
  2557. m_usGamePort = pns->usGamePort;
  2558. m_dwUnique = pns->dwUnique;
  2559. return(TRUE);
  2560. }
  2561. }
  2562. return(FALSE);
  2563. }
  2564. VOID CImpIDP_SP::SaveSessionData(NS_SESSION_SAVE *pnsSave)
  2565. {
  2566. //
  2567. //
  2568. //
  2569. if (m_dwSessionAlloc == m_dwSessionPrev)
  2570. {
  2571. char **ppTmp;
  2572. m_dwSessionAlloc += 16;
  2573. ppTmp = (char **) lmalloc(sizeof(char *) * m_dwSessionAlloc);
  2574. if (ppTmp)
  2575. {
  2576. if (m_ppSessionArray)
  2577. {
  2578. memcpy( ppTmp, m_ppSessionArray, m_dwSessionPrev * sizeof(char *));
  2579. lfree(m_ppSessionArray);
  2580. }
  2581. }
  2582. else
  2583. {
  2584. m_dwSessionAlloc -= 16;
  2585. return;
  2586. }
  2587. m_ppSessionArray = ppTmp;
  2588. }
  2589. m_ppSessionArray[m_dwSessionPrev] = (char *) lmalloc(sizeof(NS_SESSION_SAVE));
  2590. if (m_ppSessionArray[m_dwSessionPrev])
  2591. {
  2592. *((NS_SESSION_SAVE *)m_ppSessionArray[m_dwSessionPrev++]) = *pnsSave;
  2593. return;
  2594. }
  2595. else
  2596. {
  2597. return;
  2598. }
  2599. return;
  2600. }
  2601. VOID CImpIDP_SP::HandleConnect(LPVOID lpv, DWORD dwSize, SOCKADDR *pSAddr, INT SockAddrLen)
  2602. {
  2603. DWORD ii;
  2604. // TSHELL_INFO(TEXT("Handle Connect"));
  2605. SPMSG_ENUM *pMsg = (SPMSG_ENUM *) lpv;
  2606. if (dwSize != sizeof(SPMSG_ENUM))
  2607. {
  2608. TSHELL_INFO(TEXT("Connect message wrong size."));
  2609. return;
  2610. }
  2611. if (m_bPlayer0)
  2612. {
  2613. switch (pMsg->dwType)
  2614. {
  2615. case DPSYS_ENUM_REPLY:
  2616. TSHELL_INFO(TEXT("Player 0 got an enum reply, this is bogus."));
  2617. return;
  2618. default:
  2619. TSHELL_INFO(TEXT("Player 0 got an unknown type connection msg, this is bogus."));
  2620. return;
  2621. case DPSYS_ENUM:
  2622. {
  2623. TSHELL_INFO(TEXT("HandleConnect:Player 0 ENUM."));
  2624. if ( pMsg->usVerMajor == DPVERSION_MAJOR
  2625. && pMsg->usVerMinor == DPVERSION_MINOR
  2626. && CompareSessions(pMsg->dwType, &pMsg->dpSessionDesc))
  2627. {
  2628. pMsg->dwType = DPSYS_ENUM_REPLY;
  2629. pMsg->dpSessionDesc = m_dpDesc;
  2630. memset(pMsg->dpSessionDesc.szPassword, 0x00, DPSHORTNAMELEN);
  2631. pMsg->usPort = m_usGamePort;
  2632. pMsg->dwUnique = ++m_dwUnique;
  2633. pMsg->dpHdr.usSeq = NextSequence();
  2634. if (SendTo(m_ClientSocket, pSAddr, SockAddrLen, (char *)pMsg, (LPUINT) &dwSize) != 0)
  2635. {
  2636. TSHELL_INFO(TEXT("ENUM SendTo failed."));
  2637. }
  2638. else
  2639. {
  2640. TSHELL_INFO(TEXT("Enum SendTo succeeded."));
  2641. }
  2642. }
  2643. else
  2644. {
  2645. TSHELL_INFO(TEXT("Compare Sessions Failed."));
  2646. }
  2647. }
  2648. break;
  2649. case DPSYS_OPEN:
  2650. TSHELL_INFO(TEXT("HandleConnect:Player 0 OPEN."));
  2651. pMsg->usPort = m_usGamePort;
  2652. if (pMsg->usPort != m_usGamePort)
  2653. {
  2654. TSHELL_INFO(TEXT("Attempt to open from wrong port."));
  2655. return;
  2656. }
  2657. if (CompareSessions(pMsg->dwType, &pMsg->dpSessionDesc))
  2658. {
  2659. pMsg->dwType = DPSYS_CONNECT;
  2660. pMsg->dpSessionDesc = m_dpDesc;
  2661. SendTo(m_ClientSocket, pSAddr, SockAddrLen, (char *)pMsg, (LPUINT) &dwSize);
  2662. if (m_dpDesc.dwCurrentPlayers != 0)
  2663. {
  2664. TSHELL_INFO(TEXT("Send current players."));
  2665. ConnectPlayers(pSAddr, SockAddrLen);
  2666. }
  2667. for (ii = 0; ii < m_cMachines; ii++)
  2668. if (memcmp(&m_aMachineAddr[ii], pSAddr, sizeof(SOCKADDR)) == 0)
  2669. return;
  2670. memcpy( &m_aMachineAddr[m_cMachines++], pSAddr, sizeof(SOCKADDR));
  2671. }
  2672. else
  2673. {
  2674. pMsg->dwType = DPSYS_REJECT;
  2675. pMsg->dpSessionDesc = m_dpDesc;
  2676. pMsg->dpHdr.usSeq = NextSequence();
  2677. SendTo(m_ClientSocket, pSAddr, SockAddrLen, (char *)pMsg, (LPUINT) &dwSize);
  2678. }
  2679. break;
  2680. }
  2681. }
  2682. else
  2683. {
  2684. switch (pMsg->dwType)
  2685. {
  2686. default:
  2687. TSHELL_INFO(TEXT("Player x got an unknown type connection msg, this is bogus."));
  2688. return;
  2689. case DPSYS_ENUM_REPLY:
  2690. TSHELL_INFO(TEXT("HandleConnect:Player N Reply."));
  2691. EnumDataLock();
  2692. if (m_fpEnumSessions)
  2693. {
  2694. NS_SESSION_SAVE ns;
  2695. m_dwSession++;
  2696. m_SessionAddrLen = SockAddrLen;
  2697. m_usGamePort = pMsg->usPort;
  2698. memcpy( &m_NSSockAddr, pSAddr, m_SessionAddrLen);
  2699. pMsg->dpSessionDesc.dwSession = m_dwSession;
  2700. ns.dpDesc = pMsg->dpSessionDesc;
  2701. memcpy( &ns.sockaddr, pSAddr, m_SessionAddrLen);
  2702. ns.usGamePort = pMsg->usPort;
  2703. ns.dwUnique = pMsg->dwUnique;
  2704. SaveSessionData(&ns);
  2705. DBG_INFO((DBGARG, TEXT("Session %d Name %s"),
  2706. pMsg->dpSessionDesc.dwSession,
  2707. pMsg->dpSessionDesc.szSessionName));
  2708. memcpy( (LPVOID) &m_spmsgEnum, pMsg, sizeof(SPMSG_ENUM));
  2709. DBG_INFO((DBGARG, TEXT("Tick %d"), GetTickCount()));
  2710. SetEvent(m_hEnumBlkEventMain);
  2711. EnumDataUnlock();
  2712. DBG_INFO((DBGARG, TEXT("Tick %d"), GetTickCount()));
  2713. WaitForSingleObject(m_hEnumBlkEventRead, 5000);
  2714. ResetEvent(m_hEnumBlkEventRead);
  2715. DBG_INFO((DBGARG, TEXT("Tick %d"), GetTickCount()));
  2716. }
  2717. else
  2718. EnumDataUnlock();
  2719. break;
  2720. case DPSYS_CONNECT:
  2721. TSHELL_INFO(TEXT("HandleConnect:Player N Connect."));
  2722. m_bConnected = TRUE;
  2723. m_usGamePort = pMsg->usPort;
  2724. m_SessionAddrLen = SockAddrLen;
  2725. memcpy( &m_NSSockAddr, pSAddr, m_SessionAddrLen);
  2726. memcpy( &m_dpDesc, &pMsg->dpSessionDesc, sizeof(m_dpDesc));
  2727. DBG_INFO((DBGARG, TEXT("Current Players from connect %d"),
  2728. pMsg->dpSessionDesc.dwCurrentPlayers));
  2729. GetSockAddress(&m_GameSockAddr, NULL, m_usGamePort, NULL, TRUE);
  2730. SetEvent(m_hBlockingEvent);
  2731. return;
  2732. case DPSYS_REJECT:
  2733. TSHELL_INFO(TEXT("HandleConnect:Player N Reject."));
  2734. TSHELL_INFO(TEXT("We have been rejected for Open."));
  2735. SetEvent(m_hBlockingEvent);
  2736. return;
  2737. }
  2738. }
  2739. // TSHELL_INFO(TEXT("Leave Connect"));
  2740. return;
  2741. }