⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sessioninfo.cpp

📁 Visual C++ 游戏开发与设计实例 源代码(所有)
💻 CPP
📖 第 1 页 / 共 5 页
字号:
        m_dpnidLocal = pPlayerInfo->dpnID;
    if( pPlayerInfo->dwFlags & DPNPLAYER_HOST )
        m_dpnidHost = pPlayerInfo->dpnID;


    hr = S_OK;

LCleanReturn:
    Unlock();
    return hr;
}




//-----------------------------------------------------------------------------
// Name: OnGroupInfoReceive()
// Desc: Handles the extraction and storage of incoming group data
//-----------------------------------------------------------------------------
HRESULT CSessionInfo::OnGroupInfoReceive( SI_MSG_GROUPINFO* pGroupInfo )
{
    HRESULT hr = S_OK;

    // Extract the name
    LPWSTR pStr = (LPWSTR) (pGroupInfo+1);
    pStr[ pGroupInfo->dwNameLength ] = 0;

    // Set the data
    Lock();
    
    // Search for the group with the given ID
    CSIGroup* pGroup = FindGroup( pGroupInfo->dpnID );
    
    // If not found, create a new group
    if( NULL == pGroup )
    {
        hr = CreateGroup( pGroupInfo->dpnID );
        if( FAILED(hr) )
            goto LCleanReturn;

        pGroup = FindGroup( pGroupInfo->dpnID );
    }

    // Set updated information
    DXUtil_ConvertWideStringToGenericCch( pGroup->strName, pStr, 256 ); 
    
    hr = S_OK;

LCleanReturn:
    Unlock();
    return hr;
}




//-----------------------------------------------------------------------------
// Name: OnDpInfoChange()
// Desc: Handles PEER_INFO, CLIENT_INFO, and SERVER_INFO messages
//-----------------------------------------------------------------------------
HRESULT CSessionInfo::OnDpInfoChange( DPNID dpnid )
{
    RefreshPlayerInfo( dpnid );
    
    if( m_eType == SERVER )
        SendPlayerInfoToAll( dpnid );

    // Invalidate the dialog
    m_bDlgValid = FALSE;

    return S_OK;
}




//-----------------------------------------------------------------------------
// Name: GetDpPlayerInfo()
// Desc: Get the DirectPlay player info using the stored connection interface
//-----------------------------------------------------------------------------
HRESULT CSessionInfo::GetDpPlayerInfo( DPNID dpnid, DPN_PLAYER_INFO** ppPlayerInfo )
{
    HRESULT hr;
    DWORD dwSize = 0;

#ifdef _DEBUG
    if( NULL == ppPlayerInfo || NULL == dpnid )
        return E_INVALIDARG;
#endif // _DEBUG
    
    switch( m_eType )
    {
        case PEER:
        {
            // GetPeerInfo might return DPNERR_CONNECTING when connecting, 
            // so just keep calling it if it does
            do 
            {
                hr = m_pPeer->GetPeerInfo( dpnid, *ppPlayerInfo, &dwSize, 0 ); 
            }
            while( hr == DPNERR_CONNECTING );

            break;
        }

        case SERVER:
        {
            // Special case: Server can't query for local information, so
            // this should be filled in manually
            if( m_dpnidLocal == dpnid )
            {
                dwSize = sizeof( DPN_PLAYER_INFO );
                hr = DPNERR_BUFFERTOOSMALL;
            }
            else
            {
                hr = m_pServer->GetClientInfo( dpnid, *ppPlayerInfo, &dwSize, 0 );
            }

            break;
        }

        case CLIENT:
        {
            if( m_dpnidHost == dpnid )
                hr = m_pClient->GetServerInfo( *ppPlayerInfo, &dwSize, 0 );
            else
                hr = DPNERR_INVALIDPLAYER;
            break;
        }

        default:
            // Unknown type
            return E_FAIL;
    }
      
    // DirectPlay should return BufferTooSmall to give the correct allocation size
    if( hr != DPNERR_BUFFERTOOSMALL )
        return hr;

    // Allocate the memory
    *ppPlayerInfo = (DPN_PLAYER_INFO*) new BYTE[ dwSize ];
    if( NULL == *ppPlayerInfo )
        return E_OUTOFMEMORY;

    // Initialize the struct
    ZeroMemory( *ppPlayerInfo, dwSize );
    (*ppPlayerInfo)->dwSize = sizeof(DPN_PLAYER_INFO);
    
    // Get peer info
    switch( m_eType )
    {
        case PEER: 
            hr = m_pPeer->GetPeerInfo( dpnid, *ppPlayerInfo, &dwSize, 0 ); 
            break;

        case SERVER: 
            // Special case: Server can't query for local information, so
            // this should be filled in manually
            if( m_dpnidLocal == dpnid )
            {  
                (*ppPlayerInfo)->dwInfoFlags = DPNINFO_NAME | DPNINFO_DATA;
                (*ppPlayerInfo)->pwszName = L"(Server)";
                (*ppPlayerInfo)->dwPlayerFlags = DPNPLAYER_LOCAL | DPNPLAYER_HOST;
                hr = S_OK;
            }
            else
            {
                hr = m_pServer->GetClientInfo( dpnid, *ppPlayerInfo, &dwSize, 0 ); 
            }
            break;

        case CLIENT:
            hr = m_pClient->GetServerInfo( *ppPlayerInfo, &dwSize, 0 );
            break;

        default: 
            SAFE_DELETE_ARRAY( *ppPlayerInfo );
            return E_FAIL;
    }

    return hr;
}




//-----------------------------------------------------------------------------
// Name: GetDpGroupInfo
// Desc: Get the DirectPlay group info using the stored connection interface
//-----------------------------------------------------------------------------
HRESULT CSessionInfo::GetDpGroupInfo( DPNID dpnid, DPN_GROUP_INFO** ppGroupInfo )
{
    HRESULT hr;
    DWORD dwSize = 0;

#ifdef _DEBUG
    if( NULL == ppGroupInfo )
        return E_INVALIDARG;
#endif // _DEBUG
    
    switch( m_eType )
    {
        case PEER:
            hr = m_pPeer->GetGroupInfo( dpnid, NULL, &dwSize, NULL );
            break;

        case SERVER:
            hr = m_pServer->GetGroupInfo( dpnid, NULL, &dwSize, NULL );
            break;

        default:
            return E_FAIL;
    }

    // DirectPlay should return BufferTooSmall to give the correct allocation size
    if( hr != DPNERR_BUFFERTOOSMALL )
        return hr;

    // Allocate the memory
    *ppGroupInfo = (DPN_GROUP_INFO*) new BYTE[ dwSize ];
    if( NULL == *ppGroupInfo )
        return E_OUTOFMEMORY;

    // Initialize the struct
    ZeroMemory( *ppGroupInfo, dwSize );
    (*ppGroupInfo)->dwSize = sizeof(DPN_GROUP_INFO);
    
    // Get group info
    switch( m_eType )
    {
        case PEER:
            hr = m_pPeer->GetGroupInfo( dpnid, *ppGroupInfo, &dwSize, 0 );
            break;

        case SERVER:
            hr = m_pServer->GetGroupInfo( dpnid, *ppGroupInfo, &dwSize, 0 );
            break;

        default:
            SAFE_DELETE_ARRAY( *ppGroupInfo );
            return E_FAIL;
    }

    return hr;
}




//-----------------------------------------------------------------------------
// Name: GetDpAppDesc
// Desc: Get the DirectPlay application description using the stored connection 
//       interface
//-----------------------------------------------------------------------------
HRESULT CSessionInfo::GetDpAppDesc( DPN_APPLICATION_DESC** ppAppDesc )
{
    HRESULT hr;
    DWORD dwSize = 0;

#ifdef _DEBUG
    if( NULL == ppAppDesc )
        return E_INVALIDARG;
#endif // _DEBUG
    
    switch( m_eType )
    {
        case PEER:
            hr = m_pPeer->GetApplicationDesc( NULL, &dwSize, NULL );
            break;

        case SERVER:
            hr = m_pServer->GetApplicationDesc( NULL, &dwSize, NULL );
            break;

        case CLIENT:
            hr = m_pClient->GetApplicationDesc( NULL, &dwSize, NULL );
            break;

        default:
            return E_FAIL;
    }

    // DirectPlay should return BufferTooSmall to give the correct allocation size
    if( hr != DPNERR_BUFFERTOOSMALL )
        return hr;

    // Allocate the memory
    *ppAppDesc = (DPN_APPLICATION_DESC*) new BYTE[ dwSize ];
    if( NULL == *ppAppDesc )
        return E_OUTOFMEMORY;

    // Initialize the struct
    ZeroMemory( *ppAppDesc, dwSize );
    (*ppAppDesc)->dwSize = sizeof(DPN_APPLICATION_DESC);
    
    // Get group info
    switch( m_eType )
    {
           case PEER:
            hr = m_pPeer->GetApplicationDesc( *ppAppDesc, &dwSize, NULL );
            break;

        case SERVER:
            hr = m_pServer->GetApplicationDesc( *ppAppDesc, &dwSize, NULL );
            break;

        case CLIENT:
            hr = m_pClient->GetApplicationDesc( *ppAppDesc, &dwSize, NULL );
            break;

        default:
            return E_FAIL;
    }

    return hr;
}




//-----------------------------------------------------------------------------
// Name: SendPlayerInfoToPlayer()
// Desc: Send all stored player information with the given player ID to the
//       player(s) with the given target ID
//-----------------------------------------------------------------------------
HRESULT CSessionInfo::SendPlayerInfoToPlayer( DPNID idPlayer, DPNID idTarget )
{
    HRESULT hr = S_OK;

    Lock();
    
    CSIPlayer* pPlayer = FindPlayer( idPlayer );
    if( NULL == pPlayer )
    {
        Unlock();
        return E_INVALIDARG;
    }

    // Package and send the given player info
    DWORD dwNameLen = lstrlen( pPlayer->strName );
    
    DPN_BUFFER_DESC dpBufDesc = {0};
    dpBufDesc.dwBufferSize = sizeof(SI_MSG_PLAYERINFO) + 
                           ( sizeof( WCHAR ) * (dwNameLen + 1) );
                           
    // Allocate space
    SI_MSG_PLAYERINFO* pMsg = (SI_MSG_PLAYERINFO*) new BYTE[ dpBufDesc.dwBufferSize ];
    if( NULL == pMsg )
    {
        Unlock();
        return E_OUTOFMEMORY;
    }

    // Set the data pointer
    dpBufDesc.pBufferData = (BYTE*) pMsg;

    // Store values
    pMsg->dwMsgID       = SI_MSGID_PLAYERINFO;
    pMsg->dpnID         = pPlayer->id;
    pMsg->dwFlags       = 0;
    pMsg->dwNameLength  = dwNameLen;
    
    // Set flags
    if( pPlayer->bIsHost )
        pMsg->dwFlags |= DPNPLAYER_HOST;
    if( idPlayer == idTarget )
        pMsg->dwFlags |= DPNPLAYER_LOCAL;

    // Pack the string
    LPWSTR pStr = (LPWSTR) (pMsg+1);
    DXUtil_ConvertGenericStringToWideCch( pStr, pPlayer->strName, dwNameLen+1 );
    
    // Release the lock
    Unlock();

    // Send the information
    DPNHANDLE dpAsync;

    switch( m_eType )
    {
        case PEER:
            hr = m_pPeer->SendTo( idTarget, &dpBufDesc, 1, 0, SI_ASYNC_CONTEXT, &dpAsync, DPNSEND_NOCOMPLETE | DPNSEND_NOLOOPBACK );
            break;

        case SERVER:
            hr = m_pServer->SendTo( idTarget, &dpBufDesc, 1, 0, SI_ASYNC_CONTEXT, &dpAsync, DPNSEND_NOCOMPLETE | DPNSEND_NOLOOPBACK );
            break;

        case CLIENT:
            hr = m_pClient->Send( &dpBufDesc, 1, 0, SI_ASYNC_CONTEXT, &dpAsync, DPNSEND_NOCOMPLETE | DPNSEND_NOLOOPBACK );
            break;

        default:
            hr = E_FAIL;
            break;
    }

    // Release allocated memory and return
    SAFE_DELETE_ARRAY( pMsg );
    return hr;
}




//-----------------------------------------------------------------------------
// Name: SendGroupInfoToPlayer
// Desc: Send all stored information about the given group ID to the player(s)
//       with the given target ID
//-----------------------------------------------------------------------------
HRESULT CSessionInfo::SendGroupInfoToPlayer( DPNID idGroup, DPNID idTarget )
{
    HRESULT hr = S_OK;

    Lock();

    CSIGroup* pGroup = FindGroup( idGroup ); 
    if( NULL == pGroup )
    {
        Unlock();
        return E_INVALIDARG;
    }

    // Package and send the given player info
    DWORD dwNameLen = lstrlen( pGroup->strName );
   
    DPN_BUFFER_DESC dpBufDesc = {0};
    dpBufDesc.dwBufferSize = sizeof(SI_MSG_GROUPINFO) + 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -