📄 cmultiplayer.cpp
字号:
// CMAIN LIB - APPLICATION AND DIRECT WRAPPER
//
// Written by Mauricio Teichmann Ritter
//
// Copyright (C) 2002, Brazil. All rights reserved.
//
//
// cMultiplayer.cpp: implementation of the cMultiplayer class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "cMultiplayer.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
cMultiplayer::cMultiplayer()
{
m_pdnSPInfo = NULL;
m_pdnDeviceInfo = NULL;
m_pDP = NULL;
m_pDeviceAddress = NULL;
m_iSPIndex = 0;
m_iSerialDevice = NULL;
m_iModemDevice = NULL;
m_dwTcpPort = NULL;
m_dwBaudRate = NULL;
m_sFlowControl[0] = NULL;
m_sParity[0] = NULL;
m_sStopBits[0] = NULL;
m_pHostList = NULL;
m_iNumHosts = 0;
m_bCanConnect = TRUE;
m_iPlayerType = 0;
m_dpnidHost = 0;
m_dpnidSelf = 0;
m_pDP = NULL;
m_pHandler = NULL;
}
cMultiplayer::~cMultiplayer()
{
}
BOOL cMultiplayer::Initialize()
{
HRESULT hr;
hr = CoCreateInstance( CLSID_DirectPlay8Peer, NULL,
CLSCTX_INPROC_SERVER,
IID_IDirectPlay8Peer,
(LPVOID*) &m_pDP);
if(hr != 0)
{
#ifdef _DEBUG
Log("HRES: %d - %s\n", hr, DXGetErrorString8(hr));
#endif
return FALSE;
}
// Initialize DirectPlay
hr = m_pDP->Initialize(this, StaticDirectPlayMessageHandler, 0);
if(hr != 0)
{
#ifdef _DEBUG
Log("HRES: %d - %s\n", hr, DXGetErrorString8(hr));
#endif
return FALSE;
}
m_lstPlayers.clear();
InitializeCriticalSection(&m_csMessages);
m_dpnidSelf = 0;
m_dpnidHost = 0;
return TRUE;
}
HRESULT WINAPI cMultiplayer::StaticDirectPlayMessageHandler(
PVOID pvUserContext,
DWORD dwMessageId,
PVOID pMsgBuffer )
{
return ((cMultiplayer*)pvUserContext)->DirectPlayMessageHandler(pvUserContext, dwMessageId, pMsgBuffer);
}
HRESULT WINAPI cMultiplayer::DirectPlayMessageHandler(
PVOID pvUserContext,
DWORD dwMessageId,
PVOID pMsgBuffer )
{
switch( dwMessageId )
{
case DPN_MSGID_CREATE_PLAYER:
DPNMSG_CREATE_PLAYER* pCreatePlayer;
pCreatePlayer = (DPNMSG_CREATE_PLAYER*)pMsgBuffer;
if(m_iPlayerType == PLAYERTYPE_HOST)
{
PLAYER_INFO* pPlayerInfo;
pPlayerInfo = new PLAYER_INFO;
pPlayerInfo->dpnidPlayer = pCreatePlayer->dpnidPlayer;
PLAYERINFO_VECTOR::iterator theIterator;
BOOL bAdd = TRUE;
for(theIterator = m_lstPlayers.begin();theIterator != m_lstPlayers.end();theIterator++)
{
if( (*theIterator)->dpnidPlayer == pCreatePlayer->dpnidPlayer)
bAdd = FALSE;
}
if(bAdd)
{
if(m_dpnidSelf == 0)
m_dpnidSelf = pCreatePlayer->dpnidPlayer;
else
m_lstPlayers.push_back(pPlayerInfo);
#ifdef _DEBUG
Log("DPN_MSGID_CREATE_PLAYER: %d\n", pCreatePlayer->dpnidPlayer);
#endif
}
}
else
{
if(m_dpnidSelf == 0)
m_dpnidSelf = pCreatePlayer->dpnidPlayer;
#ifdef _DEBUG
Log("DPN_MSGID_CREATE_PLAYER SELF: %d\n", m_dpnidSelf);
#endif
FindHost();
}
break;
case DPN_MSGID_CONNECT_COMPLETE:
DPNMSG_CONNECT_COMPLETE* pConnect;
pConnect = (DPNMSG_CONNECT_COMPLETE*)pMsgBuffer;
//m_iMyId = *((int*)pConnect->pvApplicationReplyData);
#ifdef _DEBUG
Log("DPN_MSGID_CONNECT_COMPLETE\n");
#endif
break;
case DPN_MSGID_INDICATE_CONNECT:
#ifdef _DEBUG
Log("DPN_MSGID_INDICATE_CONNECT: %d\n", m_bCanConnect);
#endif
if(m_bCanConnect)
return DPN_OK;
else
return DPNERR_GENERIC;
break;
case DPN_MSGID_ENUM_HOSTS_QUERY:
return DPN_OK;
break;
case DPN_MSGID_ENUM_HOSTS_RESPONSE:
PDPNMSG_ENUM_HOSTS_RESPONSE pEnumHostsResponseMsg;
const DPN_APPLICATION_DESC* pAppDesc;
HOST_NODE* pHostNode;
WCHAR* pwszSession;
pwszSession = NULL;
pHostNode = NULL;
pEnumHostsResponseMsg = (PDPNMSG_ENUM_HOSTS_RESPONSE) pMsgBuffer;
pAppDesc = pEnumHostsResponseMsg->pApplicationDescription;
// Insert each host response if it isn't already present
//EnterCriticalSection(&g_csHostList);
for (pHostNode = m_pHostList; pHostNode; pHostNode = pHostNode->pNext)
{
if( pAppDesc->guidInstance == pHostNode->pAppDesc->guidInstance)
{
// This host is already in the list
pHostNode = NULL;
goto Break_ENUM_HOSTS_RESPONSE;
}
}
// This host session is not in the list then so insert it.
pHostNode = new HOST_NODE;
if( pHostNode == NULL)
{
goto Break_ENUM_HOSTS_RESPONSE;
}
ZeroMemory(pHostNode, sizeof(HOST_NODE));
// Copy the Host Address
if( FAILED( pEnumHostsResponseMsg->pAddressSender->Duplicate(&pHostNode->pHostAddress ) ) )
{
goto Break_ENUM_HOSTS_RESPONSE;
}
pHostNode->pAppDesc = new DPN_APPLICATION_DESC;
if( pHostNode == NULL)
{
goto Break_ENUM_HOSTS_RESPONSE;
}
ZeroMemory(pHostNode->pAppDesc, sizeof(DPN_APPLICATION_DESC));
memcpy(pHostNode->pAppDesc, pAppDesc, sizeof(DPN_APPLICATION_DESC));
// Null out all the pointers we aren't copying
pHostNode->pAppDesc->pwszSessionName = NULL;
pHostNode->pAppDesc->pwszPassword = NULL;
pHostNode->pAppDesc->pvReservedData = NULL;
pHostNode->pAppDesc->dwReservedDataSize = 0;
pHostNode->pAppDesc->pvApplicationReservedData = NULL;
pHostNode->pAppDesc->dwApplicationReservedDataSize = 0;
m_iNumHosts++;
if( pAppDesc->pwszSessionName)
{
pwszSession = new WCHAR[wcslen(pAppDesc->pwszSessionName) + 1];
if( pwszSession)
{
wcscpy(pwszSession, pAppDesc->pwszSessionName);
}
}
pHostNode->pwszSessionName = pwszSession;
// Insert it onto the front of the list
pHostNode->pNext = m_pHostList;// ? m_pHostList->pNext : NULL;
m_pHostList = pHostNode;
pHostNode = NULL;
Break_ENUM_HOSTS_RESPONSE:
//LeaveCriticalSection(&g_csHostList);
if( pHostNode )
{
if(pHostNode->pHostAddress)
pHostNode->pHostAddress->Release();
if(pHostNode->pAppDesc)
{
delete[] pHostNode->pAppDesc;
}
delete pHostNode;
}
break;
case DPN_MSGID_RECEIVE:
{
PDPNMSG_RECEIVE pMsg;
PLAYER_MESSAGE* pPlayerMessage;
pMsg = (PDPNMSG_RECEIVE) pMsgBuffer;
//int iTmp;
pPlayerMessage = (PLAYER_MESSAGE*) pMsg->pReceiveData;
#ifdef _DEBUG
//Log("DPN_MSGID_RECEIVE - dwSize:%d dwDataSize: %d Type %d\n", pMsg->dwSize, pMsg->dwReceiveDataSize, pPlayerMessage->m_iType);
#endif
if(m_pHandler)
{
m_pHandler->IncomingMessage(pPlayerMessage->m_iType, pMsg->dpnidSender, pMsg->pReceiveData+sizeof(int), pMsg->dwReceiveDataSize-sizeof(int));
}
break;
}
}
return DPN_OK;
}
void cMultiplayer::EnumServiceProviders()
{
HRESULT hr;
DWORD dwSize = 0;
// 确定需要的buffer大小
hr = m_pDP->EnumServiceProviders(NULL, NULL, NULL, &dwSize, &m_dwNumSP, 0);
m_pdnSPInfo = (DPN_SERVICE_PROVIDER_INFO*) new BYTE[dwSize];
#ifdef _DEBUG
Log("SP Size: %d NumSP: %d\n", dwSize, m_dwNumSP);
#endif
//Fill the buffer with service provider information
hr = m_pDP->EnumServiceProviders(NULL, NULL, m_pdnSPInfo, &dwSize, &m_dwNumSP, 0);
DWORD dwSp;
dwSp = GetRegDWValue("ServiceProvider");
if(dwSp != NULL)
{
int i = 0;
SetRegDWValue("ServiceProvider", (DWORD) i);
for(i=0;i<(int)m_dwNumSP;i++)
{
if(*GetSPGuid(i) == CLSID_DP8SP_TCPIP)
{
SetRegDWValue("ServiceProvider", (DWORD) i);
m_iSPIndex = i;
return;
}
}
}
else
{
m_iSPIndex = dwSp;
}
if(*GetSPGuid(m_iSPIndex) == CLSID_DP8SP_MODEM ||
*GetSPGuid(m_iSPIndex) == CLSID_DP8SP_SERIAL)
{
EnumDevices();
}
}
void cMultiplayer::Destroy()
{
HRESULT hr;
if(m_pdnSPInfo)
delete[] m_pdnSPInfo;
if(m_pdnDeviceInfo)
delete[] m_pdnDeviceInfo;
if(m_pDP)
{
hr = m_pDP->Close(0);
}
if(m_pDeviceAddress)
m_pDeviceAddress->Release();
if(m_pDP)
{
m_pDP->Release();
m_pDP = NULL;
}
if(m_pHostList)
{
HOST_NODE* pTmp;
pTmp = m_pHostList;
while(pTmp != NULL)
{
pTmp = m_pHostList->pNext;
delete m_pHostList;
m_pHostList = pTmp;
}
}
PLAYERINFO_VECTOR::iterator theIterator;
for(theIterator = m_lstPlayers.begin();theIterator != m_lstPlayers.end();theIterator++)
{
delete *theIterator;
}
m_lstPlayers.clear();
PLAYERMESSAGE_ELEMENT MessageIterator;
for(MessageIterator = m_lstMessages.begin();MessageIterator != m_lstMessages.end();MessageIterator++)
{
free( (*MessageIterator)->pReceiveData);
delete *MessageIterator;
}
m_lstMessages.clear();
}
long cMultiplayer::GetNumSPs()
{
return m_dwNumSP;
}
char* cMultiplayer::GetSPName(int iIndex)
{
if(iIndex >= (int) m_dwNumSP)
return NULL;
DPN_SERVICE_PROVIDER_INFO* pSPInfoEnum;
pSPInfoEnum = m_pdnSPInfo;
int iTmp = 0;
while(iTmp != iIndex)
{
pSPInfoEnum++;
iTmp++;
}
if(pSPInfoEnum->guid == CLSID_DP8SP_MODEM)
return "MODEM";
if(pSPInfoEnum->guid == CLSID_DP8SP_TCPIP)
return "TCP-IP NETWORK";
if(pSPInfoEnum->guid == CLSID_DP8SP_IPX)
return "IPX NETWORK";
if(pSPInfoEnum->guid == CLSID_DP8SP_SERIAL)
return "SERIAL PORT";
/*case CLSID_DP8SP_TCPIP:
return "TCPIP NETWORK";
case CLSID_DP8SP_SERIAL:
return "SERIAL PORT";*/
return NULL;
}
GUID* cMultiplayer::GetSPGuid(int iIndex)
{
if(iIndex >= (int) m_dwNumSP)
return NULL;
DPN_SERVICE_PROVIDER_INFO* pSPInfoEnum;
pSPInfoEnum = m_pdnSPInfo;
int iTmp = 0;
while(iTmp != iIndex)
{
pSPInfoEnum++;
iTmp++;
}
return &pSPInfoEnum->guid;
}
int cMultiplayer::GetNumSPOptions()
{
if(*GetSPGuid(m_iSPIndex) == CLSID_DP8SP_MODEM)
return 2;
if(*GetSPGuid(m_iSPIndex) == CLSID_DP8SP_TCPIP)
return 1;
if(*GetSPGuid(m_iSPIndex) == CLSID_DP8SP_SERIAL)
return 5;
if(*GetSPGuid(m_iSPIndex) == CLSID_DP8SP_IPX)
return 1;
return 0;
}
void cMultiplayer::NextSP()
{
m_iSPIndex++;
if(m_iSPIndex >= (int) m_dwNumSP)
m_iSPIndex = 0;
SetRegDWValue("ServiceProvider", (DWORD) m_iSPIndex);
if(*GetSPGuid(m_iSPIndex) == CLSID_DP8SP_MODEM ||
*GetSPGuid(m_iSPIndex) == CLSID_DP8SP_SERIAL)
{
EnumDevices();
}
}
int cMultiplayer::GetSPIndex()
{
return m_iSPIndex;
}
void cMultiplayer::GetSPOption(int iOption, char* szBuffer, DWORD dwBufferSize)
{
DPN_SERVICE_PROVIDER_INFO* pDeviceInfoEnum;
pDeviceInfoEnum = m_pdnDeviceInfo;
int iTmp = 0;
if(*GetSPGuid(m_iSPIndex) == CLSID_DP8SP_MODEM)
{
switch(iOption)
{
case 0:
return;
case 1:
return;
}
}
if(*GetSPGuid(m_iSPIndex) == CLSID_DP8SP_TCPIP)
{
switch(iOption)
{
case 0:
if(!m_dwTcpPort)
m_dwTcpPort = GetRegDWValue("TcpIpPort");
if(!m_dwTcpPort)
{
m_dwTcpPort = -1;
SetRegDWValue("TcpIpPort", m_dwTcpPort);
}
if(m_dwTcpPort == -1)
sprintf(szBuffer, "DEFAULT");
else
sprintf(szBuffer, "%d", m_dwTcpPort);
break;
}
}
if(*GetSPGuid(m_iSPIndex) == CLSID_DP8SP_SERIAL)
{
switch(iOption)
{
case 0:
if(!m_iSerialDevice)
m_iSerialDevice = GetRegDWValue("SerialDevice");
if(!m_iSerialDevice)
{
m_iSerialDevice = 0;
SetRegDWValue("SerialDevice", m_iSerialDevice);
}
while(iTmp != m_iSerialDevice)
{
pDeviceInfoEnum++;
iTmp++;
}
sprintf(szBuffer, "%S", pDeviceInfoEnum->pwszName);
break;
case 1:
if(!m_dwBaudRate)
m_dwBaudRate = GetRegDWValue("BaudRate");
if(!m_dwBaudRate)
{
m_dwBaudRate = DPNA_BAUD_RATE_9600;
SetRegDWValue("BaudRate", m_dwBaudRate);
}
sprintf(szBuffer, "%d BPS", m_dwBaudRate);
break;
case 2:
if(!m_sFlowControl[0])
GetRegStringValue("FlowControl", m_sFlowControl, 10);
if(!m_sFlowControl[0])
{
sprintf(m_sFlowControl, "%S", DPNA_FLOW_CONTROL_NONE);
SetRegStringValue("FlowControl", m_sFlowControl);
}
sprintf(szBuffer, "%s", m_sFlowControl);
break;
case 3:
if(!m_sParity[0])
GetRegStringValue("Parity", m_sParity, 10);
if(!m_sParity[0])
{
sprintf(m_sParity, "%S", DPNA_PARITY_NONE);
SetRegStringValue("Parity", m_sParity);
}
sprintf(szBuffer, "%s", m_sParity);
break;
case 4:
if(!m_sStopBits[0])
GetRegStringValue("StopBits", m_sStopBits, 10);
if(!m_sStopBits[0])
{
sprintf(m_sStopBits, "%S", DPNA_STOP_BITS_ONE);
SetRegStringValue("StopBits", m_sStopBits);
}
sprintf(szBuffer, "%s", m_sStopBits);
break;
}
}
if(*GetSPGuid(m_iSPIndex) == CLSID_DP8SP_IPX)
{
switch(iOption)
{
case 0:
break;
}
}
return;
}
char* cMultiplayer::GetSPOptionName(int iOption)
{
if(*GetSPGuid(m_iSPIndex) == CLSID_DP8SP_MODEM)
{
switch(iOption)
{
case 0:
return "DEVICE";
case 1:
return "PHONE NUMBER";
}
}
if(*GetSPGuid(m_iSPIndex) == CLSID_DP8SP_TCPIP)
{
switch(iOption)
{
case 0:
return "PORT NUMBER";
}
}
if(*GetSPGuid(m_iSPIndex) == CLSID_DP8SP_SERIAL)
{
switch(iOption)
{
case 0:
return "DEVICE";
case 1:
return "BAUD RATE";
case 2:
return "FLOW CONTROL";
case 3:
return "PARITY";
case 4:
return "STOP BITS";
}
}
if(*GetSPGuid(m_iSPIndex) == CLSID_DP8SP_IPX)
{
switch(iOption)
{
case 0:
return "PORT NUMBER";
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -