home *** CD-ROM | disk | FTP | other *** search
/ Visual Basic Game Programming for Teens / VBGPFT.cdr / DirectX8 / dx8a_sdk.exe / samples / multimedia / directplay / maze / mazeserver / server.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2000-11-04  |  11.6 KB  |  356 lines

  1. //----------------------------------------------------------------------------
  2. // File: server.cpp
  3. //
  4. // Desc: 
  5. //
  6. // Copyright (c) 1999-2000 Microsoft Corp. All rights reserved.
  7. //-----------------------------------------------------------------------------
  8. #define STRICT
  9. #include <windows.h>
  10. #include <process.h>
  11. #include <stdio.h>
  12. #include <math.h>
  13. #include <stdio.h>
  14. #include <tchar.h>
  15. #include <conio.h>
  16. #include <dplay8.h>
  17. #include <dpaddr.h>
  18. #include <DXErr8.h>
  19. #include "DXUtil.h"
  20. #include "server.h"
  21. #include "StressMazeGUID.h"
  22.  
  23. #define DPMAZESERVER_PORT       2309
  24.       
  25.  
  26.  
  27.  
  28. //-----------------------------------------------------------------------------
  29. // Name: 
  30. // Desc: 
  31. //-----------------------------------------------------------------------------
  32. CDPlay8Server::CDPlay8Server()
  33. {
  34.     m_pDPlay    = NULL;
  35.     m_pServer   = NULL;
  36. }
  37.  
  38.  
  39.  
  40.  
  41. //-----------------------------------------------------------------------------
  42. // Name: 
  43. // Desc: 
  44. //-----------------------------------------------------------------------------
  45. HRESULT CDPlay8Server::Start()
  46. {
  47.     HRESULT hr;
  48.     PDIRECTPLAY8ADDRESS   pDP8AddrLocal = NULL;
  49.     DWORD dwPort;
  50.  
  51.     // Create DirectPlay object
  52.     hr = CoCreateInstance( CLSID_DirectPlay8Server, NULL, 
  53.                            CLSCTX_ALL, IID_IDirectPlay8Server,
  54.                            (LPVOID*) &m_pDPlay );
  55.     if( FAILED(hr) )
  56.     {
  57.         DXTRACE_ERR( TEXT("CoCreateInstance"), hr );
  58.         goto LCleanup;
  59.     }
  60.  
  61.     hr = CoCreateInstance( CLSID_DirectPlay8Address, NULL, 
  62.                            CLSCTX_ALL, IID_IDirectPlay8Address, 
  63.                            (LPVOID*) &pDP8AddrLocal );
  64.     if( FAILED(hr) )
  65.     {
  66.         DXTRACE_ERR( TEXT("CoCreateInstance"), hr );
  67.         goto LCleanup;
  68.     }
  69.  
  70.     hr = pDP8AddrLocal->SetSP( &CLSID_DP8SP_TCPIP );
  71.     if( FAILED(hr) )
  72.     {
  73.         DXTRACE_ERR( TEXT("BuildLocalAddress"), hr );
  74.         goto LCleanup;
  75.     }
  76.  
  77.     dwPort = DPMAZESERVER_PORT;
  78.     hr = pDP8AddrLocal->AddComponent( DPNA_KEY_PORT, 
  79.                                       &dwPort, sizeof(dwPort),
  80.                                       DPNA_DATATYPE_DWORD );
  81.     if( FAILED(hr) )
  82.     {
  83.         DXTRACE_ERR( TEXT("BuildLocalAddress"), hr );
  84.         goto LCleanup;
  85.     }
  86.  
  87.     hr = m_pDPlay->Initialize( this, StaticReceiveHandler, 0 );
  88.     if( FAILED(hr) )
  89.     {
  90.         DXTRACE_ERR( TEXT("Initialize"), hr );
  91.         goto LCleanup;
  92.     }
  93.  
  94.     DPN_APPLICATION_DESC dpnAppDesc;
  95.     ZeroMemory( &dpnAppDesc, sizeof(DPN_APPLICATION_DESC) );
  96.     dpnAppDesc.dwSize = sizeof( DPN_APPLICATION_DESC );
  97.     dpnAppDesc.dwFlags = DPNSESSION_CLIENT_SERVER;
  98.     dpnAppDesc.guidApplication = StressMazeAppGUID;
  99.     dpnAppDesc.pwszSessionName = L"StressMazeServer Session";
  100.  
  101.     // Set host player context to non-NULL so we can determine which player indication is 
  102.     // the host's.
  103.     hr = m_pDPlay->Host( &dpnAppDesc, &pDP8AddrLocal, 1, NULL, NULL, (void *) 1, 0  );
  104.     if( FAILED(hr) )
  105.     {
  106.         DXTRACE_ERR( TEXT("Host"), hr );
  107.         goto LCleanup;
  108.     }
  109.  
  110. LCleanup:
  111.     SAFE_RELEASE( pDP8AddrLocal );
  112.     SAFE_RELEASE( pDP8AddrLocal );
  113.  
  114.     return hr;
  115. }
  116.  
  117.  
  118.  
  119.  
  120. //-----------------------------------------------------------------------------
  121. // Name: 
  122. // Desc: 
  123. //-----------------------------------------------------------------------------
  124. void CDPlay8Server::Shutdown()
  125. {
  126.     if( m_pDPlay != NULL )
  127.         m_pDPlay->Close(0);
  128.  
  129.     SAFE_RELEASE( m_pDPlay );
  130. }
  131.  
  132.  
  133.  
  134.  
  135. //-----------------------------------------------------------------------------
  136. // Name: 
  137. // Desc: 
  138. //-----------------------------------------------------------------------------
  139. HRESULT CDPlay8Server::RejectClient( DWORD dwID, HRESULT hrReason )
  140. {
  141.     HRESULT hrRet = S_OK;
  142.  
  143.     if( m_pDPlay )
  144.     {
  145.         hrRet = m_pDPlay->DestroyClient( dwID, &hrReason, sizeof(hrReason), 0 );
  146.     }
  147.  
  148.     return hrRet;
  149. }
  150.  
  151.  
  152.  
  153.  
  154. //-----------------------------------------------------------------------------
  155. // Name: 
  156. // Desc: 
  157. //-----------------------------------------------------------------------------
  158. HRESULT CDPlay8Server::StaticReceiveHandler( void *pvContext, DWORD dwMessageType, 
  159.                                              void *pvMessage )
  160. {
  161.     CDPlay8Server* pThisObject = (CDPlay8Server*) pvContext;
  162.  
  163.     return pThisObject->ReceiveHandler( pvContext, dwMessageType, pvMessage );
  164. }
  165.  
  166.  
  167.  
  168. //-----------------------------------------------------------------------------
  169. // Name: 
  170. // Desc: 
  171. //-----------------------------------------------------------------------------
  172. HRESULT CDPlay8Server::ReceiveHandler( void *pvContext, DWORD dwMessageType, 
  173.                                        void *pvMessage )
  174. {
  175.     switch( dwMessageType )
  176.     {
  177.         case DPN_MSGID_CREATE_PLAYER:
  178.         {
  179.             PDPNMSG_CREATE_PLAYER pCreatePlayer = (PDPNMSG_CREATE_PLAYER) pvMessage;
  180.  
  181.             if( pCreatePlayer->pvPlayerContext == NULL )
  182.                 m_pServer->OnAddConnection( pCreatePlayer->dpnidPlayer );
  183.             break;
  184.         }
  185.         
  186.         case DPN_MSGID_DESTROY_PLAYER:
  187.         {
  188.             PDPNMSG_DESTROY_PLAYER pDestroyPlayer = (PDPNMSG_DESTROY_PLAYER) pvMessage;
  189.  
  190.             if( pDestroyPlayer->pvPlayerContext == NULL )
  191.                 m_pServer->OnRemoveConnection( pDestroyPlayer->dpnidPlayer );
  192.             break;
  193.         }
  194.  
  195.         case DPN_MSGID_RECEIVE:
  196.         {
  197.             PDPNMSG_RECEIVE pRecvData = (PDPNMSG_RECEIVE) pvMessage;
  198.  
  199.             m_pServer->OnPacket( pRecvData->dpnidSender, pRecvData->pReceiveData, pRecvData->dwReceiveDataSize );
  200.             break;
  201.         }
  202.  
  203.         case DPN_MSGID_TERMINATE_SESSION:
  204.         {
  205.             m_pServer->OnSessionLost( DISCONNNECT_REASON_UNKNOWN );
  206.             break;
  207.         }
  208.     }
  209.     
  210.     return DPN_OK;
  211. }
  212.  
  213.  
  214.  
  215.  
  216. //-----------------------------------------------------------------------------
  217. // Name: 
  218. // Desc: 
  219. //-----------------------------------------------------------------------------
  220. HRESULT CDPlay8Server::SendPacket( DWORD dwTo, void* pData, 
  221.                                    DWORD dwSize, BOOL bGuaranteed,
  222.                                    DWORD dwTimeout )
  223. {
  224.     DPNHANDLE       hAsync;
  225.     DPNHANDLE*      phAsync;
  226.     DWORD           dwFlags = 0;
  227.     DPN_BUFFER_DESC dpnBufferDesc;
  228.  
  229.     if( bGuaranteed )
  230.     {
  231.         // If we are guaranteed then we must specify
  232.         // DPNSEND_NOCOMPLETE and pass in non-null for the 
  233.         // pvAsyncContext
  234.         dwFlags = DPNSEND_GUARANTEED;
  235.     }
  236.     else
  237.     {
  238.         // If we aren't guaranteed then we can
  239.         // specify DPNSEND_NOCOMPLETE.  And when 
  240.         // DPNSEND_NOCOMPLETE is on pvAsyncContext
  241.         // must be NULL.
  242.         dwFlags = DPNSEND_NOCOMPLETE;
  243.     }
  244.     //Must define an async handle for the SendTo call. 
  245.     phAsync = &hAsync;
  246.  
  247.     dpnBufferDesc.dwBufferSize = dwSize;
  248.     dpnBufferDesc.pBufferData = (PBYTE) pData;
  249.  
  250.     // DirectPlay will tell via the message handler 
  251.     // if there are any severe errors, so ignore any errors 
  252.     m_pDPlay->SendTo( dwTo, &dpnBufferDesc, 1, dwTimeout, NULL, phAsync, dwFlags );
  253.  
  254.     return S_OK;
  255. }
  256.  
  257.  
  258.  
  259.  
  260. //-----------------------------------------------------------------------------
  261. // Name: 
  262. // Desc: 
  263. //-----------------------------------------------------------------------------
  264. HRESULT CDPlay8Server::GetConnectionInfo( DWORD dwID, TCHAR* strConnectionInfo )
  265. {
  266.     HRESULT hr;
  267.  
  268.     // Call GetConnectionInfo and display results
  269.     DPN_CONNECTION_INFO dpnConnectionInfo;
  270.     ZeroMemory( &dpnConnectionInfo, sizeof(DPN_CONNECTION_INFO) );
  271.     dpnConnectionInfo.dwSize = sizeof(DPN_CONNECTION_INFO);
  272.     hr = m_pDPlay->GetConnectionInfo( dwID, &dpnConnectionInfo, 0 );
  273.  
  274.     if( SUCCEEDED(hr) )
  275.     {
  276.         DWORD dwHighPriMessages, dwHighPriBytes;
  277.         DWORD dwNormalPriMessages, dwNormalPriBytes;
  278.         DWORD dwLowPriMessages, dwLowPriBytes;
  279.  
  280.         hr = m_pDPlay->GetSendQueueInfo( dwID,
  281.                                       &dwHighPriMessages, &dwHighPriBytes, 
  282.                                       DPNGETSENDQUEUEINFO_PRIORITY_HIGH );
  283.  
  284.         hr = m_pDPlay->GetSendQueueInfo( dwID,
  285.                                       &dwNormalPriMessages, &dwNormalPriBytes, 
  286.                                       DPNGETSENDQUEUEINFO_PRIORITY_NORMAL );
  287.  
  288.         hr = m_pDPlay->GetSendQueueInfo( dwID,
  289.                                       &dwLowPriMessages, &dwLowPriBytes, 
  290.                                       DPNGETSENDQUEUEINFO_PRIORITY_LOW );
  291.  
  292.         _stprintf( strConnectionInfo, 
  293.                    "     Round Trip Latency MS=%dms\n"                      \
  294.                    "     Throughput BPS: Current=%d Peak=%d\n"              \
  295.                                                                             \
  296.                    "     Messages Received=%d\n"                            \
  297.                                                                             \
  298.                    "     Sent: GB=%d GP=%d NGB=%d NGP=%d\n"                 \
  299.                    "     Received: GB=%d GP=%d NGB=%d NGP=%d\n"             \
  300.                                                                             \
  301.                    "     Messages Transmitted: HP=%d NP=%d LP=%d\n"         \
  302.                    "     Messages Timed Out: HP=%d NP=%d LP=%d\n"           \
  303.                                                                             \
  304.                    "     Retried: GB=%d GP=%d\n"                            \
  305.                    "     Dropped: NGB=%d NGP=%d\n"                          \
  306.                                                                             \
  307.                    "     Send Queue Messages: HP=%d NP=%d LP=%d\n"          \
  308.                    "     Send Queue Bytes: HP=%d NP=%d LP=%d\n",            \
  309.                                                                             \
  310.                                                                             \
  311.                    dpnConnectionInfo.dwRoundTripLatencyMS, 
  312.                    dpnConnectionInfo.dwThroughputBPS, 
  313.                    dpnConnectionInfo.dwPeakThroughputBPS,
  314.  
  315.                    dpnConnectionInfo.dwMessagesReceived,
  316.  
  317.                    dpnConnectionInfo.dwBytesSentGuaranteed,
  318.                    dpnConnectionInfo.dwPacketsSentGuaranteed,
  319.                    dpnConnectionInfo.dwBytesSentNonGuaranteed,
  320.                    dpnConnectionInfo.dwPacketsSentNonGuaranteed,
  321.  
  322.                    dpnConnectionInfo.dwBytesReceivedGuaranteed,
  323.                    dpnConnectionInfo.dwPacketsReceivedGuaranteed,
  324.                    dpnConnectionInfo.dwBytesReceivedNonGuaranteed,
  325.                    dpnConnectionInfo.dwPacketsReceivedNonGuaranteed,
  326.  
  327.                    dpnConnectionInfo.dwMessagesTransmittedHighPriority,
  328.                    dpnConnectionInfo.dwMessagesTransmittedNormalPriority,
  329.                    dpnConnectionInfo.dwMessagesTransmittedLowPriority,
  330.  
  331.                    dpnConnectionInfo.dwMessagesTimedOutHighPriority,
  332.                    dpnConnectionInfo.dwMessagesTimedOutNormalPriority,
  333.                    dpnConnectionInfo.dwMessagesTimedOutLowPriority,
  334.  
  335.                    dpnConnectionInfo.dwBytesRetried,
  336.                    dpnConnectionInfo.dwPacketsRetried,
  337.  
  338.                    dpnConnectionInfo.dwBytesDropped,
  339.                    dpnConnectionInfo.dwPacketsDropped,
  340.  
  341.                    dwHighPriMessages, dwNormalPriMessages, dwLowPriMessages, 
  342.                    dwHighPriBytes, dwNormalPriBytes, dwLowPriBytes
  343.  
  344.                    );
  345.  
  346.     }
  347.     else
  348.     {
  349.         strcpy( strConnectionInfo, "DPNID not found.\n" );
  350.     }
  351.  
  352.     return S_OK;
  353. }
  354.  
  355.  
  356.