📄 sessioninfo.cpp
字号:
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 + -