cMultiplayer.cpp
上传用户:sycq158
上传日期:2008-10-22
资源大小:15361k
文件大小:29k
源码类别:

游戏

开发平台:

Visual C++

  1. // CMAIN LIB - APPLICATION AND DIRECT WRAPPER
  2. //
  3. // Written by Mauricio Teichmann Ritter
  4. //
  5. // Copyright (C) 2002, Brazil. All rights reserved.
  6. // 
  7. //
  8. // cMultiplayer.cpp: implementation of the cMultiplayer class.
  9. //
  10. //////////////////////////////////////////////////////////////////////
  11. #include "stdafx.h"
  12. #include "cMultiplayer.h"
  13. //////////////////////////////////////////////////////////////////////
  14. // Construction/Destruction
  15. //////////////////////////////////////////////////////////////////////
  16. cMultiplayer::cMultiplayer()
  17. {
  18. m_pdnSPInfo = NULL;
  19. m_pdnDeviceInfo = NULL;
  20. m_pDP = NULL;
  21. m_pDeviceAddress = NULL;
  22. m_iSPIndex = 0;
  23. m_iSerialDevice = NULL;
  24. m_iModemDevice = NULL;
  25. m_dwTcpPort = NULL;
  26. m_dwBaudRate = NULL;
  27. m_sFlowControl[0] = NULL;
  28. m_sParity[0] = NULL;
  29. m_sStopBits[0] = NULL;
  30. m_pHostList = NULL;
  31. m_iNumHosts = 0;
  32. m_bCanConnect = TRUE;
  33. m_iPlayerType = 0;
  34. m_dpnidHost = 0;
  35. m_dpnidSelf = 0;
  36. m_pDP = NULL;
  37. m_pHandler = NULL;
  38. }
  39. cMultiplayer::~cMultiplayer()
  40. {
  41. }
  42. BOOL cMultiplayer::Initialize()
  43. {
  44. HRESULT hr;
  45. hr = CoCreateInstance( CLSID_DirectPlay8Peer, NULL, 
  46.    CLSCTX_INPROC_SERVER,
  47.    IID_IDirectPlay8Peer, 
  48.    (LPVOID*) &m_pDP);
  49. if(hr != 0)
  50. {
  51. #ifdef _DEBUG
  52. Log("HRES: %d - %sn", hr, DXGetErrorString8(hr));
  53. #endif
  54. return FALSE;
  55. }
  56. // Initialize DirectPlay
  57. hr = m_pDP->Initialize(this, StaticDirectPlayMessageHandler, 0);
  58. if(hr != 0)
  59. {
  60. #ifdef _DEBUG
  61. Log("HRES: %d - %sn", hr, DXGetErrorString8(hr));
  62. #endif
  63. return FALSE;
  64. }
  65. m_lstPlayers.clear();
  66. InitializeCriticalSection(&m_csMessages);
  67. m_dpnidSelf = 0;
  68. m_dpnidHost = 0;
  69. return TRUE;
  70. }
  71. HRESULT WINAPI cMultiplayer::StaticDirectPlayMessageHandler(
  72.   PVOID pvUserContext,
  73.   DWORD dwMessageId,
  74.   PVOID pMsgBuffer )
  75. {
  76. return ((cMultiplayer*)pvUserContext)->DirectPlayMessageHandler(pvUserContext, dwMessageId, pMsgBuffer);
  77. }
  78. HRESULT WINAPI cMultiplayer::DirectPlayMessageHandler(
  79.   PVOID pvUserContext,
  80.   DWORD dwMessageId,
  81.   PVOID pMsgBuffer )
  82. {
  83. switch( dwMessageId )
  84. {
  85. case DPN_MSGID_CREATE_PLAYER:
  86. DPNMSG_CREATE_PLAYER* pCreatePlayer;
  87. pCreatePlayer = (DPNMSG_CREATE_PLAYER*)pMsgBuffer;
  88. if(m_iPlayerType == PLAYERTYPE_HOST)
  89. {
  90. PLAYER_INFO* pPlayerInfo;
  91. pPlayerInfo = new PLAYER_INFO;
  92. pPlayerInfo->dpnidPlayer = pCreatePlayer->dpnidPlayer;
  93. PLAYERINFO_VECTOR::iterator theIterator;
  94. BOOL bAdd = TRUE;
  95. for(theIterator = m_lstPlayers.begin();theIterator != m_lstPlayers.end();theIterator++)
  96. {
  97. if( (*theIterator)->dpnidPlayer == pCreatePlayer->dpnidPlayer)
  98. bAdd = FALSE;
  99. }
  100. if(bAdd)
  101. {
  102. if(m_dpnidSelf == 0)
  103. m_dpnidSelf = pCreatePlayer->dpnidPlayer;
  104. else
  105. m_lstPlayers.push_back(pPlayerInfo);
  106. #ifdef _DEBUG
  107. Log("DPN_MSGID_CREATE_PLAYER: %dn", pCreatePlayer->dpnidPlayer);
  108. #endif
  109. }
  110. }
  111. else
  112. {
  113. if(m_dpnidSelf == 0)
  114. m_dpnidSelf = pCreatePlayer->dpnidPlayer;
  115. #ifdef _DEBUG
  116. Log("DPN_MSGID_CREATE_PLAYER SELF: %dn", m_dpnidSelf);
  117. #endif
  118. FindHost();
  119. }
  120. break;
  121. case DPN_MSGID_CONNECT_COMPLETE:
  122. DPNMSG_CONNECT_COMPLETE* pConnect;
  123. pConnect = (DPNMSG_CONNECT_COMPLETE*)pMsgBuffer;
  124. //m_iMyId = *((int*)pConnect->pvApplicationReplyData);
  125. #ifdef _DEBUG
  126. Log("DPN_MSGID_CONNECT_COMPLETEn");
  127. #endif
  128. break;
  129. case DPN_MSGID_INDICATE_CONNECT:
  130. #ifdef _DEBUG
  131. Log("DPN_MSGID_INDICATE_CONNECT: %dn", m_bCanConnect);
  132. #endif
  133. if(m_bCanConnect)
  134. return DPN_OK;
  135. else
  136. return DPNERR_GENERIC;
  137. break;
  138. case DPN_MSGID_ENUM_HOSTS_QUERY:
  139. return DPN_OK;
  140. break;
  141.     case DPN_MSGID_ENUM_HOSTS_RESPONSE:
  142.         PDPNMSG_ENUM_HOSTS_RESPONSE     pEnumHostsResponseMsg;
  143.         const DPN_APPLICATION_DESC*     pAppDesc;
  144.         HOST_NODE*                      pHostNode;
  145.         WCHAR*                          pwszSession;
  146. pwszSession = NULL;
  147. pHostNode = NULL;
  148.     
  149.         pEnumHostsResponseMsg = (PDPNMSG_ENUM_HOSTS_RESPONSE) pMsgBuffer;
  150.         pAppDesc = pEnumHostsResponseMsg->pApplicationDescription;
  151.     
  152.         // Insert each host response if it isn't already present
  153.         //EnterCriticalSection(&g_csHostList);
  154.     
  155.         for (pHostNode = m_pHostList; pHostNode; pHostNode = pHostNode->pNext)
  156.         {
  157.             if( pAppDesc->guidInstance == pHostNode->pAppDesc->guidInstance)
  158.             {
  159.                 // This host is already in the list
  160.                 pHostNode = NULL;
  161.                 goto Break_ENUM_HOSTS_RESPONSE;
  162.             }
  163.         }
  164.     
  165.         // This host session is not in the list then so insert it.
  166.         pHostNode = new HOST_NODE;
  167.         if( pHostNode == NULL)
  168.         {
  169.             goto Break_ENUM_HOSTS_RESPONSE;
  170.         }
  171.     
  172.         ZeroMemory(pHostNode, sizeof(HOST_NODE));
  173.     
  174.         // Copy the Host Address
  175.         if( FAILED( pEnumHostsResponseMsg->pAddressSender->Duplicate(&pHostNode->pHostAddress ) ) )
  176.         {
  177.             goto Break_ENUM_HOSTS_RESPONSE;
  178.         }
  179.     
  180.         pHostNode->pAppDesc = new DPN_APPLICATION_DESC;
  181.     
  182.         if( pHostNode == NULL)
  183.         {
  184.             goto Break_ENUM_HOSTS_RESPONSE;
  185.         }
  186.     
  187.         ZeroMemory(pHostNode->pAppDesc, sizeof(DPN_APPLICATION_DESC));
  188.         memcpy(pHostNode->pAppDesc, pAppDesc, sizeof(DPN_APPLICATION_DESC));
  189.     
  190.         // Null out all the pointers we aren't copying
  191.         pHostNode->pAppDesc->pwszSessionName = NULL;
  192.         pHostNode->pAppDesc->pwszPassword = NULL;
  193.         pHostNode->pAppDesc->pvReservedData = NULL;
  194.         pHostNode->pAppDesc->dwReservedDataSize = 0;
  195.         pHostNode->pAppDesc->pvApplicationReservedData = NULL;
  196.         pHostNode->pAppDesc->dwApplicationReservedDataSize = 0;
  197.     
  198. m_iNumHosts++;
  199.         if( pAppDesc->pwszSessionName)
  200.         {
  201.             pwszSession = new WCHAR[wcslen(pAppDesc->pwszSessionName) + 1];
  202.         
  203.             if( pwszSession)
  204.             {
  205.                 wcscpy(pwszSession, pAppDesc->pwszSessionName);
  206.             }
  207.         }
  208.     
  209.         pHostNode->pwszSessionName = pwszSession;
  210.     
  211.         // Insert it onto the front of the list
  212.         pHostNode->pNext = m_pHostList;// ? m_pHostList->pNext : NULL;
  213.         m_pHostList = pHostNode;
  214.         pHostNode = NULL;
  215.     
  216. Break_ENUM_HOSTS_RESPONSE:
  217.         //LeaveCriticalSection(&g_csHostList);       
  218.         if( pHostNode )
  219.         {
  220.             if(pHostNode->pHostAddress)
  221. pHostNode->pHostAddress->Release();
  222.             if(pHostNode->pAppDesc)
  223. {
  224. delete[] pHostNode->pAppDesc;
  225. }
  226.             delete pHostNode;
  227.         }
  228.         break;
  229.  case DPN_MSGID_RECEIVE:
  230.         {
  231.             PDPNMSG_RECEIVE     pMsg;
  232. PLAYER_MESSAGE* pPlayerMessage;
  233. pMsg = (PDPNMSG_RECEIVE) pMsgBuffer;
  234. //int iTmp;
  235. pPlayerMessage = (PLAYER_MESSAGE*) pMsg->pReceiveData;
  236. #ifdef _DEBUG
  237. //Log("DPN_MSGID_RECEIVE - dwSize:%d  dwDataSize: %d Type %dn", pMsg->dwSize, pMsg->dwReceiveDataSize, pPlayerMessage->m_iType);
  238. #endif
  239. if(m_pHandler)
  240. {
  241. m_pHandler->IncomingMessage(pPlayerMessage->m_iType, pMsg->dpnidSender, pMsg->pReceiveData+sizeof(int), pMsg->dwReceiveDataSize-sizeof(int));
  242. }
  243.             break;
  244.         }
  245. }
  246. return DPN_OK;
  247. }
  248. void cMultiplayer::EnumServiceProviders()
  249. {
  250. HRESULT hr;
  251.     DWORD                       dwSize          = 0;
  252.     // 确定需要的buffer大小
  253.     hr = m_pDP->EnumServiceProviders(NULL, NULL, NULL, &dwSize, &m_dwNumSP, 0);
  254. m_pdnSPInfo = (DPN_SERVICE_PROVIDER_INFO*) new BYTE[dwSize];
  255. #ifdef _DEBUG
  256. Log("SP Size: %d NumSP: %dn", dwSize, m_dwNumSP);
  257. #endif
  258.     //Fill the buffer with service provider information
  259.     hr = m_pDP->EnumServiceProviders(NULL, NULL, m_pdnSPInfo, &dwSize, &m_dwNumSP, 0);
  260. DWORD dwSp;
  261. dwSp = GetRegDWValue("ServiceProvider");
  262. if(dwSp != NULL)
  263. {
  264. int i = 0;
  265. SetRegDWValue("ServiceProvider", (DWORD) i);
  266. for(i=0;i<(int)m_dwNumSP;i++)
  267. {
  268. if(*GetSPGuid(i) == CLSID_DP8SP_TCPIP)
  269. {
  270. SetRegDWValue("ServiceProvider", (DWORD) i);
  271. m_iSPIndex = i;
  272. return;
  273. }
  274. }
  275. }
  276. else
  277. {
  278. m_iSPIndex = dwSp;
  279. }
  280. if(*GetSPGuid(m_iSPIndex) == CLSID_DP8SP_MODEM ||
  281.    *GetSPGuid(m_iSPIndex) == CLSID_DP8SP_SERIAL)
  282. {
  283. EnumDevices();
  284. }
  285. }
  286. void cMultiplayer::Destroy()
  287. {
  288. HRESULT hr;
  289. if(m_pdnSPInfo)
  290. delete[] m_pdnSPInfo;
  291. if(m_pdnDeviceInfo)
  292. delete[] m_pdnDeviceInfo;
  293. if(m_pDP)
  294. {
  295. hr = m_pDP->Close(0); 
  296. }
  297. if(m_pDeviceAddress)
  298. m_pDeviceAddress->Release();
  299. if(m_pDP)
  300. {
  301. m_pDP->Release();
  302. m_pDP = NULL;
  303. }
  304. if(m_pHostList)
  305. {
  306. HOST_NODE* pTmp;
  307. pTmp = m_pHostList;
  308. while(pTmp != NULL)
  309. {
  310. pTmp = m_pHostList->pNext;
  311. delete m_pHostList;
  312. m_pHostList = pTmp;
  313. }
  314. }
  315. PLAYERINFO_VECTOR::iterator theIterator;
  316. for(theIterator = m_lstPlayers.begin();theIterator != m_lstPlayers.end();theIterator++)
  317. {
  318. delete *theIterator;
  319. }
  320. m_lstPlayers.clear();
  321. PLAYERMESSAGE_ELEMENT MessageIterator;
  322. for(MessageIterator = m_lstMessages.begin();MessageIterator != m_lstMessages.end();MessageIterator++)
  323. {
  324. free( (*MessageIterator)->pReceiveData);
  325. delete *MessageIterator;
  326. }
  327. m_lstMessages.clear();
  328. }
  329. long cMultiplayer::GetNumSPs()
  330. {
  331. return m_dwNumSP;
  332. }
  333. char* cMultiplayer::GetSPName(int iIndex)
  334. {
  335. if(iIndex >= (int) m_dwNumSP)
  336. return NULL;
  337. DPN_SERVICE_PROVIDER_INFO* pSPInfoEnum;
  338. pSPInfoEnum = m_pdnSPInfo;
  339. int iTmp = 0;
  340. while(iTmp != iIndex)
  341. {
  342. pSPInfoEnum++;
  343. iTmp++;
  344. }
  345. if(pSPInfoEnum->guid == CLSID_DP8SP_MODEM)
  346. return "MODEM";
  347. if(pSPInfoEnum->guid == CLSID_DP8SP_TCPIP)
  348. return "TCP-IP NETWORK";
  349. if(pSPInfoEnum->guid == CLSID_DP8SP_IPX)
  350. return "IPX NETWORK";
  351. if(pSPInfoEnum->guid == CLSID_DP8SP_SERIAL)
  352. return "SERIAL PORT";
  353. /*case CLSID_DP8SP_TCPIP:
  354. return "TCPIP NETWORK";
  355. case CLSID_DP8SP_SERIAL:
  356. return "SERIAL PORT";*/
  357. return NULL;
  358. }
  359. GUID* cMultiplayer::GetSPGuid(int iIndex)
  360. {
  361. if(iIndex >= (int)  m_dwNumSP)
  362. return NULL;
  363. DPN_SERVICE_PROVIDER_INFO* pSPInfoEnum;
  364. pSPInfoEnum = m_pdnSPInfo;
  365. int iTmp = 0;
  366. while(iTmp != iIndex)
  367. {
  368. pSPInfoEnum++;
  369. iTmp++;
  370. }
  371. return &pSPInfoEnum->guid;
  372. }
  373. int cMultiplayer::GetNumSPOptions()
  374. {
  375. if(*GetSPGuid(m_iSPIndex) == CLSID_DP8SP_MODEM)
  376. return 2;
  377. if(*GetSPGuid(m_iSPIndex) == CLSID_DP8SP_TCPIP)
  378. return 1;
  379. if(*GetSPGuid(m_iSPIndex) == CLSID_DP8SP_SERIAL)
  380. return 5;
  381. if(*GetSPGuid(m_iSPIndex) == CLSID_DP8SP_IPX)
  382. return 1;
  383. return 0;
  384. }
  385. void cMultiplayer::NextSP()
  386. {
  387. m_iSPIndex++;
  388. if(m_iSPIndex >= (int) m_dwNumSP)
  389. m_iSPIndex = 0;
  390. SetRegDWValue("ServiceProvider", (DWORD) m_iSPIndex);
  391. if(*GetSPGuid(m_iSPIndex) == CLSID_DP8SP_MODEM ||
  392.    *GetSPGuid(m_iSPIndex) == CLSID_DP8SP_SERIAL)
  393. {
  394. EnumDevices();
  395. }
  396. }
  397. int cMultiplayer::GetSPIndex()
  398. {
  399. return m_iSPIndex;
  400. }
  401. void cMultiplayer::GetSPOption(int iOption, char* szBuffer, DWORD dwBufferSize)
  402. {
  403. DPN_SERVICE_PROVIDER_INFO* pDeviceInfoEnum;
  404. pDeviceInfoEnum = m_pdnDeviceInfo;
  405. int iTmp = 0;
  406. if(*GetSPGuid(m_iSPIndex) == CLSID_DP8SP_MODEM)
  407. {
  408. switch(iOption)
  409. {
  410. case 0:
  411. return;
  412. case 1:
  413. return;
  414. }
  415. }
  416. if(*GetSPGuid(m_iSPIndex) == CLSID_DP8SP_TCPIP)
  417. {
  418. switch(iOption)
  419. {
  420. case 0:
  421. if(!m_dwTcpPort)
  422. m_dwTcpPort =  GetRegDWValue("TcpIpPort");
  423. if(!m_dwTcpPort)
  424. {
  425. m_dwTcpPort = -1;
  426. SetRegDWValue("TcpIpPort", m_dwTcpPort);
  427. }
  428. if(m_dwTcpPort == -1)
  429. sprintf(szBuffer, "DEFAULT");
  430. else
  431. sprintf(szBuffer, "%d", m_dwTcpPort);
  432. break;
  433. }
  434. }
  435. if(*GetSPGuid(m_iSPIndex) == CLSID_DP8SP_SERIAL)
  436. {
  437. switch(iOption)
  438. {
  439. case 0:
  440. if(!m_iSerialDevice)
  441. m_iSerialDevice =  GetRegDWValue("SerialDevice");
  442. if(!m_iSerialDevice)
  443. {
  444. m_iSerialDevice = 0;
  445. SetRegDWValue("SerialDevice", m_iSerialDevice);
  446. }
  447. while(iTmp != m_iSerialDevice)
  448. {
  449. pDeviceInfoEnum++;
  450. iTmp++;
  451. }
  452. sprintf(szBuffer, "%S", pDeviceInfoEnum->pwszName);
  453. break;
  454. case 1:
  455. if(!m_dwBaudRate)
  456. m_dwBaudRate =  GetRegDWValue("BaudRate");
  457. if(!m_dwBaudRate)
  458. {
  459. m_dwBaudRate = DPNA_BAUD_RATE_9600;
  460. SetRegDWValue("BaudRate", m_dwBaudRate);
  461. }
  462. sprintf(szBuffer, "%d BPS", m_dwBaudRate);
  463. break;
  464. case 2:
  465. if(!m_sFlowControl[0])
  466. GetRegStringValue("FlowControl", m_sFlowControl, 10);
  467. if(!m_sFlowControl[0])
  468. {
  469. sprintf(m_sFlowControl, "%S", DPNA_FLOW_CONTROL_NONE);
  470. SetRegStringValue("FlowControl", m_sFlowControl);
  471. }
  472. sprintf(szBuffer, "%s", m_sFlowControl);
  473. break;
  474. case 3:
  475. if(!m_sParity[0])
  476. GetRegStringValue("Parity", m_sParity, 10);
  477. if(!m_sParity[0])
  478. {
  479. sprintf(m_sParity, "%S", DPNA_PARITY_NONE);
  480. SetRegStringValue("Parity", m_sParity);
  481. }
  482. sprintf(szBuffer, "%s", m_sParity);
  483. break;
  484. case 4:
  485. if(!m_sStopBits[0])
  486. GetRegStringValue("StopBits", m_sStopBits, 10);
  487. if(!m_sStopBits[0])
  488. {
  489. sprintf(m_sStopBits, "%S", DPNA_STOP_BITS_ONE);
  490. SetRegStringValue("StopBits", m_sStopBits);
  491. }
  492. sprintf(szBuffer, "%s", m_sStopBits);
  493. break;
  494. }
  495. }
  496. if(*GetSPGuid(m_iSPIndex) == CLSID_DP8SP_IPX)
  497. {
  498. switch(iOption)
  499. {
  500. case 0:
  501. break;
  502. }
  503. }
  504. return;
  505. }
  506. char* cMultiplayer::GetSPOptionName(int iOption)
  507. {
  508. if(*GetSPGuid(m_iSPIndex) == CLSID_DP8SP_MODEM)
  509. {
  510. switch(iOption)
  511. {
  512. case 0:
  513. return "DEVICE";
  514. case 1:
  515. return "PHONE NUMBER";
  516. }
  517. }
  518. if(*GetSPGuid(m_iSPIndex) == CLSID_DP8SP_TCPIP)
  519. {
  520. switch(iOption)
  521. {
  522. case 0:
  523. return "PORT NUMBER";
  524. }
  525. }
  526. if(*GetSPGuid(m_iSPIndex) == CLSID_DP8SP_SERIAL)
  527. {
  528. switch(iOption)
  529. {
  530. case 0:
  531. return "DEVICE";
  532. case 1:
  533. return "BAUD RATE";
  534. case 2:
  535. return "FLOW CONTROL";
  536. case 3:
  537. return "PARITY";
  538. case 4:
  539. return "STOP BITS";
  540. }
  541. }
  542. if(*GetSPGuid(m_iSPIndex) == CLSID_DP8SP_IPX)
  543. {
  544. switch(iOption)
  545. {
  546. case 0:
  547. return "PORT NUMBER";
  548. }
  549. }
  550. return NULL;
  551. }
  552. int cMultiplayer::GetSPOptionType(int iOption)
  553. {
  554. if(*GetSPGuid(m_iSPIndex) == CLSID_DP8SP_MODEM)
  555. {
  556. switch(iOption)
  557. {
  558. case 0:
  559. return 0;
  560. case 1:
  561. return 1;
  562. }
  563. }
  564. if(*GetSPGuid(m_iSPIndex) == CLSID_DP8SP_TCPIP)
  565. {
  566. switch(iOption)
  567. {
  568. case 0:
  569. return 1;
  570. }
  571. }
  572. if(*GetSPGuid(m_iSPIndex) == CLSID_DP8SP_SERIAL)
  573. {
  574. return 0;
  575. }
  576. if(*GetSPGuid(m_iSPIndex) == CLSID_DP8SP_IPX)
  577. {
  578. return 1;
  579. }
  580. return 0;
  581. }
  582. void cMultiplayer::EnumDevices()
  583. {
  584. if(m_pdnDeviceInfo)
  585. delete[] m_pdnDeviceInfo;
  586. HRESULT hr;
  587.     DWORD                       dwSize          = 0;
  588.     // Determine the required buffer size
  589.     hr = m_pDP->EnumServiceProviders(GetSPGuid(m_iSPIndex), NULL, NULL, &dwSize, &m_dwNumDevices, 0);
  590. #ifdef _DEBUG
  591. Log("Devices: Size: %d NumDevices: %dn", dwSize, m_dwNumSP);
  592. #endif
  593. m_pdnDeviceInfo = (DPN_SERVICE_PROVIDER_INFO*) new BYTE[dwSize];
  594.     //Fill the buffer with service provider information
  595.     hr = m_pDP->EnumServiceProviders(GetSPGuid(m_iSPIndex), NULL, m_pdnDeviceInfo, &dwSize, &m_dwNumDevices, 0);
  596. }
  597. char* cMultiplayer::GetRegStringValue(char* lpszValueName, char* szBuffer, DWORD dwBufLen)
  598. {
  599.     HKEY hKey;
  600.     LONG lRet;
  601.     if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  602.         "SOFTWARE\RaceX",
  603.                     0,
  604.                     KEY_QUERY_VALUE,
  605.                     &hKey) != ERROR_SUCCESS)
  606. return NULL;
  607.     lRet = RegQueryValueEx(hKey,
  608.                     lpszValueName,
  609.                     NULL,
  610.                     NULL,
  611.                     (LPBYTE)szBuffer,
  612.                     &dwBufLen);
  613.     if(lRet != ERROR_SUCCESS) return NULL;
  614. RegCloseKey(hKey);
  615. return szBuffer;
  616. }
  617. DWORD cMultiplayer::GetRegDWValue(char* lpszValueName)
  618. {
  619. DWORD dwSize=sizeof(DWORD), dwValue, dwType=REG_DWORD;
  620.     HKEY hKey;
  621.     LONG lRet;
  622.     if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  623.         "SOFTWARE\RaceX",
  624.                     0,
  625.                     KEY_QUERY_VALUE,
  626.                     &hKey) != ERROR_SUCCESS)
  627. return NULL;
  628.     lRet=RegQueryValueEx(hKey,
  629.                         lpszValueName,
  630.                         0,
  631.                         &dwType,
  632.                         (LPBYTE)&dwValue,
  633.                         &dwSize );
  634. if(lRet != ERROR_SUCCESS) return NULL;
  635. RegCloseKey(hKey);
  636. return dwValue;
  637. }
  638. void cMultiplayer::SetRegDWValue(char* lpszValueName, DWORD dwValue)
  639. {
  640. DWORD dwSize=sizeof(DWORD), dwType=REG_DWORD;
  641.     HKEY hKey;
  642.     LONG lRet;
  643.     if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  644.         "SOFTWARE\RaceX",
  645.                     0,
  646.                     KEY_WRITE,
  647.                     &hKey) != ERROR_SUCCESS)
  648. {
  649. if(RegCreateKey(HKEY_LOCAL_MACHINE,
  650.         "SOFTWARE\RaceX", &hKey) != ERROR_SUCCESS)
  651. return;
  652. }
  653.     lRet=RegSetValueEx(hKey,
  654.                         lpszValueName,
  655.                         0,
  656.                         dwType,
  657.                         (LPBYTE)&dwValue,
  658.                         dwSize );
  659. if(lRet != ERROR_SUCCESS) return;
  660. RegCloseKey(hKey);
  661. return;
  662. }
  663. void cMultiplayer::SetRegStringValue(char* lpszValueName, char* lpszValue)
  664. {
  665. DWORD dwSize=sizeof(DWORD), dwType=REG_SZ;
  666.     HKEY hKey;
  667. LONG lRet;
  668.     if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  669.         "SOFTWARE\RaceX",
  670.                     0,
  671.                     KEY_WRITE,
  672.                     &hKey) != ERROR_SUCCESS)
  673. {
  674. if(RegCreateKey(HKEY_LOCAL_MACHINE,
  675.         "SOFTWARE\RaceX", &hKey) != ERROR_SUCCESS)
  676. return;
  677. }
  678. dwSize = strlen(lpszValue) + 1;
  679.     lRet=RegSetValueEx(hKey,
  680.                         lpszValueName,
  681.                         0,
  682.                         dwType,
  683.                         (LPBYTE)lpszValue,
  684.                         dwSize );
  685. if(lRet != ERROR_SUCCESS) return;
  686. RegCloseKey(hKey);
  687. return;
  688. }
  689. void cMultiplayer::AdvanceSPOption(int iOption)
  690. {
  691. char buffer[20];
  692. int iTmp = 0;
  693. if(*GetSPGuid(m_iSPIndex) == CLSID_DP8SP_MODEM)
  694. {
  695. switch(iOption)
  696. {
  697. case 0:
  698. m_iModemDevice++;
  699. if(m_iModemDevice >= (int)m_dwNumDevices)
  700. m_iModemDevice = 0;
  701. SetRegDWValue("ModemDevice", (DWORD) m_iModemDevice);
  702. return;
  703. case 1:
  704. return;
  705. }
  706. }
  707. if(*GetSPGuid(m_iSPIndex) == CLSID_DP8SP_TCPIP)
  708. {
  709. return;
  710. }
  711. if(*GetSPGuid(m_iSPIndex) == CLSID_DP8SP_SERIAL)
  712. {
  713. switch(iOption)
  714. {
  715. case 0:
  716. m_iSerialDevice++;
  717. if(m_iSerialDevice >= (int)m_dwNumDevices)
  718. m_iSerialDevice = 0;
  719. SetRegDWValue("SerialDevice", (DWORD) m_iSerialDevice);
  720. break;
  721. case 1:
  722. switch(m_dwBaudRate)
  723. {
  724. case DPNA_BAUD_RATE_9600:
  725. m_dwBaudRate = DPNA_BAUD_RATE_14400;
  726. SetRegDWValue("BaudRate", m_dwBaudRate);
  727. break;
  728. case DPNA_BAUD_RATE_14400:
  729. m_dwBaudRate = DPNA_BAUD_RATE_19200;
  730. SetRegDWValue("BaudRate", m_dwBaudRate);
  731. break;
  732. case DPNA_BAUD_RATE_19200:
  733. m_dwBaudRate = DPNA_BAUD_RATE_38400;
  734. SetRegDWValue("BaudRate", m_dwBaudRate);
  735. break;
  736. case DPNA_BAUD_RATE_38400:
  737. m_dwBaudRate = DPNA_BAUD_RATE_56000;
  738. SetRegDWValue("BaudRate", m_dwBaudRate);
  739. break;
  740. case DPNA_BAUD_RATE_56000:
  741. m_dwBaudRate = DPNA_BAUD_RATE_9600;
  742. SetRegDWValue("BaudRate", m_dwBaudRate);
  743. break;
  744. }
  745. break;
  746. case 2:
  747. sprintf(buffer, "%S", DPNA_FLOW_CONTROL_NONE);
  748. if(strcmp(m_sFlowControl, buffer) == 0)
  749. {
  750. sprintf(m_sFlowControl, "%S", DPNA_FLOW_CONTROL_DTR);
  751. SetRegStringValue("FlowControl", m_sFlowControl);
  752. break;
  753. }
  754. sprintf(buffer, "%S", DPNA_FLOW_CONTROL_DTR);
  755. if(strcmp(m_sFlowControl, buffer) == 0)
  756. {
  757. sprintf(m_sFlowControl, "%S", DPNA_FLOW_CONTROL_XONXOFF);
  758. SetRegStringValue("FlowControl", m_sFlowControl);
  759. break;
  760. }
  761. sprintf(buffer, "%S", DPNA_FLOW_CONTROL_XONXOFF);
  762. if(strcmp(m_sFlowControl, buffer) == 0)
  763. {
  764. sprintf(m_sFlowControl, "%S", DPNA_FLOW_CONTROL_RTSDTR);
  765. SetRegStringValue("FlowControl", m_sFlowControl);
  766. break;
  767. }
  768. sprintf(buffer, "%S", DPNA_FLOW_CONTROL_RTSDTR);
  769. if(strcmp(m_sFlowControl, buffer) == 0)
  770. {
  771. sprintf(m_sFlowControl, "%S", DPNA_FLOW_CONTROL_RTS);
  772. SetRegStringValue("FlowControl", m_sFlowControl);
  773. break;
  774. }
  775. sprintf(buffer, "%S", DPNA_FLOW_CONTROL_RTS);
  776. if(strcmp(m_sFlowControl, buffer) == 0)
  777. {
  778. sprintf(m_sFlowControl, "%S", DPNA_FLOW_CONTROL_NONE);
  779. SetRegStringValue("FlowControl", m_sFlowControl);
  780. break;
  781. }
  782. break;
  783. case 3:
  784. sprintf(buffer, "%S", DPNA_PARITY_NONE);
  785. if(strcmp(m_sParity, buffer) == 0)
  786. {
  787. sprintf(m_sParity, "%S", DPNA_PARITY_MARK);
  788. SetRegStringValue("Parity", m_sParity);
  789. break;
  790. }
  791. sprintf(buffer, "%S", DPNA_PARITY_MARK);
  792. if(strcmp(m_sParity, buffer) == 0)
  793. {
  794. sprintf(m_sParity, "%S", DPNA_PARITY_EVEN);
  795. SetRegStringValue("Parity", m_sParity);
  796. break;
  797. }
  798. sprintf(buffer, "%S", DPNA_PARITY_EVEN);
  799. if(strcmp(m_sParity, buffer) == 0)
  800. {
  801. sprintf(m_sParity, "%S", DPNA_PARITY_SPACE);
  802. SetRegStringValue("Parity", m_sParity);
  803. break;
  804. }
  805. sprintf(buffer, "%S", DPNA_PARITY_SPACE);
  806. if(strcmp(m_sParity, buffer) == 0)
  807. {
  808. sprintf(m_sParity, "%S", DPNA_PARITY_ODD);
  809. SetRegStringValue("Parity", m_sParity);
  810. break;
  811. }
  812. sprintf(buffer, "%S", DPNA_PARITY_ODD);
  813. if(strcmp(m_sParity, buffer) == 0)
  814. {
  815. sprintf(m_sParity, "%S", DPNA_PARITY_NONE);
  816. SetRegStringValue("Parity", m_sParity);
  817. break;
  818. }
  819. break;
  820. case 4:
  821. sprintf(buffer, "%S", DPNA_STOP_BITS_ONE);
  822. if(strcmp(m_sStopBits, buffer) == 0)
  823. {
  824. sprintf(m_sStopBits, "%S", DPNA_STOP_BITS_ONE_FIVE);
  825. SetRegStringValue("StopBits", m_sStopBits);
  826. break;
  827. }
  828. sprintf(buffer, "%S", DPNA_STOP_BITS_ONE_FIVE);
  829. if(strcmp(m_sStopBits, buffer) == 0)
  830. {
  831. sprintf(m_sStopBits, "%S", DPNA_STOP_BITS_TWO);
  832. SetRegStringValue("StopBits", m_sStopBits);
  833. break;
  834. }
  835. sprintf(buffer, "%S", DPNA_STOP_BITS_TWO);
  836. if(strcmp(m_sStopBits, buffer) == 0)
  837. {
  838. sprintf(m_sStopBits, "%S", DPNA_STOP_BITS_ONE);
  839. SetRegStringValue("StopBits", m_sStopBits);
  840. break;
  841. }
  842. break;
  843. }
  844. }
  845. if(*GetSPGuid(m_iSPIndex) == CLSID_DP8SP_IPX)
  846. {
  847. return;
  848. }
  849. }
  850. BOOL cMultiplayer::Host(char *sSessionName)
  851. {
  852. m_iPlayerType =  PLAYERTYPE_HOST;
  853. HRESULT hr;
  854. // Create our IDirectPlay8Address Device Address
  855. hr = CoCreateInstance( CLSID_DirectPlay8Address, NULL,
  856.    CLSCTX_INPROC_SERVER,
  857.    IID_IDirectPlay8Address,
  858.    (LPVOID*) &m_pDeviceAddress ); 
  859. if(SUCCEEDED(hr))
  860. {
  861. }
  862. // Set the SP for our Device Address
  863. hr = m_pDeviceAddress->SetSP(GetSPGuid(m_iSPIndex));
  864.     DPN_APPLICATION_DESC    dpAppDesc;
  865.     // Set up the application description.
  866.     ZeroMemory(&dpAppDesc, sizeof(DPN_APPLICATION_DESC));
  867.     dpAppDesc.dwSize = sizeof(DPN_APPLICATION_DESC);
  868.     dpAppDesc.guidApplication = g_guidApp;
  869. dpAppDesc.dwMaxPlayers = 4;
  870. WCHAR wstrSessionName[MAX_PATH];
  871. MultiByteToWideChar(CP_ACP, 0, sSessionName, 
  872. strlen(sSessionName), 
  873. wstrSessionName, 
  874. MAX_PATH);
  875. dpAppDesc.pwszSessionName = new WCHAR[wcslen(wstrSessionName)+1];
  876. wcscpy( dpAppDesc.pwszSessionName, wstrSessionName );
  877.     // We are now ready to host the application.
  878.     hr = m_pDP->Host( &dpAppDesc,          // AppDesc
  879.                       &m_pDeviceAddress, 1,// Device Address
  880.                       NULL, NULL,              // Reserved
  881.                       NULL,                    // Player Context
  882.                       0);                      // dwFlags
  883. delete[] dpAppDesc.pwszSessionName;
  884. return TRUE;
  885. }
  886. BOOL cMultiplayer::EnumSessions()
  887. {
  888.     DPN_APPLICATION_DESC    dpAppDesc;
  889. HRESULT hr;
  890. HOST_NODE*              pHostNode = NULL;
  891. WCHAR*                  pwszURL = NULL;
  892. DWORD                   dwNumChars = 0;
  893. // Create our IDirectPlay8Address Device Address
  894. hr = CoCreateInstance( CLSID_DirectPlay8Address, NULL,
  895.    CLSCTX_INPROC_SERVER,
  896.    IID_IDirectPlay8Address,
  897.    (LPVOID*) &m_pDeviceAddress ); 
  898. // Set the SP for our Device Address
  899. hr = m_pDeviceAddress->SetSP(GetSPGuid(m_iSPIndex));
  900. // TODO: Add your control notification handler code here
  901. ZeroMemory(&dpAppDesc, sizeof(DPN_APPLICATION_DESC));
  902. dpAppDesc.dwSize = sizeof(DPN_APPLICATION_DESC);
  903. dpAppDesc.guidApplication = g_guidApp;
  904. m_iNumHosts = 0;
  905. hr = m_pDP->EnumHosts( &dpAppDesc,  // pApplicationDesc
  906.    NULL,  // Host Address
  907.    m_pDeviceAddress,// Device Address
  908.    NULL, 0,   // pvUserEnumData, size
  909.    4,         // dwEnumCount
  910.    0,         // dwRetryInterval
  911.    0,         // dwTimeOut
  912.    NULL,      // pvUserContext
  913.    NULL,      // pAsyncHandle
  914.    DPNENUMHOSTS_SYNC); // dwFlags
  915. return TRUE;
  916. }
  917. int cMultiplayer::GetNumSessions()
  918. {
  919. return m_iNumHosts;
  920. }
  921. void cMultiplayer::GetSessionName(int iIndex, char *sValue, int iSize)
  922. {
  923. HOST_NODE*              pHostNode = NULL;
  924. pHostNode = m_pHostList;
  925. for(int i=0;i<iIndex;i++)
  926. {
  927. pHostNode = pHostNode->pNext;
  928. }
  929. sprintf(sValue, "%S", pHostNode->pwszSessionName);
  930. return;
  931. }
  932. void cMultiplayer::SetCanConnect(BOOL bValue)
  933. {
  934. m_bCanConnect = bValue;
  935. }
  936. BOOL cMultiplayer::GetCanConnect()
  937. {
  938. return m_bCanConnect;
  939. }
  940. void cMultiplayer::Connect(int iHost)
  941. {
  942. // TODO: Add your control notification handler code here
  943.     DPN_APPLICATION_DESC        dpnAppDesc;
  944.     IDirectPlay8Address*        pHostAddress = NULL;
  945. HRESULT hr;
  946. HOST_NODE*              pHostNode = NULL;
  947. m_iPlayerType =  PLAYERTYPE_PEER;
  948. m_dpnidSelf = 0;
  949.     ZeroMemory(&dpnAppDesc, sizeof(DPN_APPLICATION_DESC));
  950.     dpnAppDesc.dwSize = sizeof(DPN_APPLICATION_DESC);
  951.     dpnAppDesc.guidApplication = g_guidApp;
  952. pHostNode = m_pHostList;
  953. for(int i=0;i<iHost;i++)
  954. {
  955. pHostNode = pHostNode->pNext;
  956. }
  957.     hr = pHostNode->pHostAddress->Duplicate(&pHostAddress);
  958.     hr = m_pDP->Connect(&dpnAppDesc,    // Application Description
  959.                         pHostAddress,       // Host Address
  960.                         m_pDeviceAddress,   
  961.                         NULL,  
  962.                         NULL,
  963.                         NULL, 0, 
  964.                         NULL, 
  965.                         NULL,
  966.                         NULL, 
  967.                         DPNCONNECT_SYNC);
  968. pHostAddress->Release();
  969. }
  970. BOOL cMultiplayer::IsHosting()
  971. {
  972. if(m_iPlayerType == PLAYERTYPE_HOST)
  973. return TRUE;
  974. else
  975. return FALSE;
  976. }
  977. int cMultiplayer::GetNumConnected()
  978. {
  979. return m_lstPlayers.size();
  980. }
  981. PLAYER_INFO* cMultiplayer::GetPlayerInfo(int iIndex)
  982. {
  983. return m_lstPlayers[iIndex];
  984. }
  985. void cMultiplayer::SendTo(DPNID dpnidTarget, int iType, LPBYTE lpBuffer, DWORD dwSize, DWORD dwFlags)
  986. {
  987.     DPNHANDLE       hAsync;
  988.     DPNHANDLE*      phAsync;
  989.     DPN_BUFFER_DESC dpnBuffer;
  990. HRESULT hr;
  991. LPBYTE pTmpBuffer;
  992. pTmpBuffer = (LPBYTE) malloc(sizeof(int) + dwSize);
  993. memcpy(pTmpBuffer, &iType, sizeof(int));
  994. memcpy(pTmpBuffer+sizeof(int), lpBuffer, dwSize);
  995.     dpnBuffer.pBufferData = pTmpBuffer;
  996.     dpnBuffer.dwBufferSize = sizeof(int) + dwSize;
  997. if(dwFlags & DPNSEND_SYNC)
  998. phAsync = NULL;
  999. else
  1000. phAsync = &hAsync;
  1001.     hr = m_pDP->SendTo( dpnidTarget, // dpnid
  1002.                                     &dpnBuffer,  // pBufferDesc
  1003.                                     1,           // cBufferDesc
  1004.                                     0,           // dwTimeOut
  1005.                                     NULL,        // pvAsyncContext
  1006.                                     phAsync,        // pvAsyncHandle
  1007.                                     dwFlags );    // dwFlags
  1008. free(pTmpBuffer);
  1009. }
  1010. int cMultiplayer::GetNumMessages()
  1011. {
  1012. DWORD dwTemp;
  1013. dwTemp = m_lstMessages.size();
  1014. return dwTemp;
  1015. }
  1016. PLAYER_MESSAGE* cMultiplayer::GetMessage(int iIndex)
  1017. {
  1018. PLAYERMESSAGE_ELEMENT theIterator;
  1019. EnterCriticalSection(&m_csMessages);
  1020. theIterator = m_lstMessages.begin();
  1021. for(int i=0;i<iIndex;i++)
  1022. theIterator++;
  1023. return (*theIterator);
  1024. }
  1025. void cMultiplayer::RemoveMessage(PLAYER_MESSAGE *pMessage)
  1026. {
  1027. free(pMessage->pReceiveData);
  1028. m_lstMessages.remove(pMessage);
  1029. delete pMessage;
  1030. }
  1031. int cMultiplayer::GetHost()
  1032. {
  1033. return m_dpnidHost;
  1034. }
  1035. void cMultiplayer::FindHost()
  1036. {
  1037. DWORD dwSize = NULL, dwSize2 = NULL;
  1038. DPNID* pDPNIDs = NULL;
  1039. DPN_PLAYER_INFO *pPlayerInfo = NULL;
  1040. m_pDP->EnumPlayersAndGroups(pDPNIDs, &dwSize, DPNENUM_PLAYERS);
  1041. pDPNIDs = (DPNID*)malloc(dwSize * sizeof(DPNID));
  1042. m_pDP->EnumPlayersAndGroups(pDPNIDs, &dwSize, DPNENUM_PLAYERS);
  1043. for(int i=0;i<dwSize;i++)
  1044. {
  1045. dwSize2 = NULL;
  1046. m_pDP->GetPeerInfo(pDPNIDs[i], pPlayerInfo, &dwSize2, 0);
  1047. pPlayerInfo = (DPN_PLAYER_INFO*) malloc(dwSize2);
  1048. m_pDP->GetPeerInfo(pDPNIDs[i], pPlayerInfo, &dwSize2, 0);
  1049. if(pPlayerInfo->dwPlayerFlags & DPNPLAYER_HOST)
  1050. {
  1051. m_dpnidHost = pDPNIDs[i];
  1052. free(pPlayerInfo);
  1053. break;
  1054. }
  1055. free(pPlayerInfo);
  1056. }
  1057. free(pDPNIDs);
  1058. #ifdef _DEBUG
  1059. Log("FIND HOST: %dn", m_dpnidHost);
  1060. #endif
  1061. }
  1062. int cMultiplayer::GetMyId()
  1063. {
  1064. return m_dpnidSelf;
  1065. }
  1066. void cMultiplayer::ReleaseMessage()
  1067. {
  1068. #ifdef _DEBUG
  1069. //Log("LEAVING CRITICAL SECTIONn");
  1070. #endif
  1071. LeaveCriticalSection(&m_csMessages);
  1072. }
  1073. void cMultiplayer::SetHandler(cMessageHandler *pHandler)
  1074. {
  1075. m_pHandler = pHandler;
  1076. }