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

📄 cmultiplayer.cpp

📁 一个2D的赛车游戏 在VC下运行 开发库DIRECTX8.1以上
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// 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 + -