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

📄 net.cpp

📁 vc写的源程序,是关于游戏类的程序。调用了系统的很多API
💻 CPP
字号:
#include "graphics.h"

GUID LIB_GUID = {0x58fa98e0, 0x1999, 0x0507, {0x42, 0x01, 0x06, 0x74, 0x10, 0x16, 0x77, 0x30}};

LPDIRECTPLAY4A      lpDP = NULL;     // DirectPlay对象
LPDIRECTPLAYLOBBY3A lpDPL = NULL;    // DirectPlayLobby对象
DPID                DirectPlayID;    // DirectPlay的ID
LPGUID              lpGUID;          // 游戏标识
BOOL                IsHost = FALSE;  // 是否为主机
BOOL                NetInit = FALSE; // 网络正常标志
DPID                PlayerID = NULL; // 玩家标志
DWORD DP_Thread_ID;

LIST *ListSP = NULL;      // 建立连接类型列表
LIST *ListSession = NULL; // 会话列表
LIST *ListPlayer = NULL;  // 玩家列表
LPVOID tcpip = NULL, modem = NULL, serial = NULL;
HANDLE PlayerEvent, ExitEvent, DP_Thread = NULL;
NETSESSION entry_session; // 当前的会话的属性
DPCAPS dpcaps; // DirectPlay的通信能力

BOOL CALLBACK EnumConnectionsCallback(LPCGUID lpGuid, LPVOID lpConnection, DWORD dwConnectionSize,
										LPCDPNAME lpName, DWORD dwFlags, LPVOID lpContext);
BOOL CALLBACK EnumSessionsCallback(LPCDPSESSIONDESC2 lpThisSD, LPDWORD lpdwTimeOut, DWORD dwFlags, LPVOID lpContext);
BOOL CALLBACK EnumPlayersCallback(DPID dpID, DWORD dwPlayerType, LPCDPNAME lpName, DWORD dwFlags, LPVOID lpContext);
int (* NetMessageProc)(NETMESSAGE *);
DWORD WINAPI ReceiveMessage(LPVOID p);

// 初始化DirectPlay
BOOL init_directplay()
{
	// 初始化DirectPlay对象
	CoInitialize(NULL);
	if (FAILED(CoCreateInstance(CLSID_DirectPlay, NULL, CLSCTX_INPROC_SERVER, IID_IDirectPlay4A, (LPVOID *)&lpDP)))
		return FALSE;
	if (FAILED(CoCreateInstance(CLSID_DirectPlayLobby, NULL, CLSCTX_INPROC_SERVER, IID_IDirectPlayLobby3A, (LPVOID *)&lpDPL)))
		return FALSE;
	ListSP = create_list();
	lpDP->EnumConnections(&LIB_GUID, EnumConnectionsCallback, hWnd, 0);
	PlayerEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
	ExitEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
	DP_Thread = CreateThread(NULL, 0, ReceiveMessage, NULL, 0, &DP_Thread_ID);
	if (DP_Thread == NULL)
		return 0;

	entry_session.lpguid = new GUID;
	NetInit = TRUE;
	return TRUE;
}

// 枚举连接类型
BOOL CALLBACK EnumConnectionsCallback(LPCGUID lpGuid, LPVOID lpConnection, DWORD dwConnectionSize,
										LPCDPNAME lpName, DWORD dwFlags, LPVOID lpContext)
{
	CONNECT_TYPE *ct;
	ct = new CONNECT_TYPE;
	if (ct == NULL)
		return FALSE;
	strcpy(ct->name, lpName->lpszShortNameA);
	ct->size = dwConnectionSize;
	ct->connect = new char [dwConnectionSize];
	memcpy(ct->connect, lpConnection, dwConnectionSize);
	if (IsEqualGUID(*lpGuid, DPSPGUID_TCPIP))
		ct->type = CONNECT_TCPIP;
	else if (IsEqualGUID(*lpGuid, DPSPGUID_IPX))
		ct->type = CONNECT_IPX;
	else if (IsEqualGUID(*lpGuid, DPSPGUID_MODEM))
		ct->type = CONNECT_MODEM;
	else if (IsEqualGUID(*lpGuid, DPSPGUID_SERIAL))
		ct->type = CONNECT_SERIAL;
	add_point(ListSP, ct);
	return TRUE;
}

// 释放DirectPlay对象
void free_directplay()
{
	LIST_POINT *p;
	if (ListSP != NULL)
	{
		seek_to_first(ListSP);
		while(ListSP->entry != NULL)
		{
			p = ListSP->entry;
			ListSP->entry = ListSP->entry->next;
			CONNECT_TYPE *ct;
			ct = (CONNECT_TYPE *)(((LIST_POINT *)p)->data);
			delete ct->connect;
			delete ct;
			delete p;
		}
	}
	if (ListSession != NULL)
	{
		seek_to_first(ListSession);
		while(ListSession->entry != NULL)
		{
			p = ListSession->entry;
			ListSession->entry = ListSession->entry->next;
			NETSESSION *ns;
			ns = (NETSESSION *)(((LIST_POINT *)p)->data);
			delete ns->lpguid;
			delete p;
		}
	}
	CloseHandle(PlayerEvent);
	delete entry_session.lpguid;
	lpDP->Release();
	lpDP = NULL;
	lpDPL->Release();
	lpDPL = NULL;
}

// 初始化连接
BOOL init_connect(int type)
{
	seek_to_first(ListSP);
	for (DWORD i = 0; i < ListSP->count; i++)
	{
		CONNECT_TYPE *ct;
		ct = (CONNECT_TYPE *)(ListSP->entry->data);
		if (ct->type == type)
		{
			LPVOID lpdata = NULL;
			switch(type)
			{
			case CONNECT_TCPIP:
				lpdata = tcpip;
				break;
			case CONNECT_MODEM:
				lpdata = modem;
				break;
			case CONNECT_SERIAL:
				lpdata = serial;
			}
			if (lpdata == NULL)
			{
				if (FAILED(lpDP->InitializeConnection(ct->connect, 0)))
					continue;
			}
			else
			{
				if (FAILED(lpDP->InitializeConnection(lpdata, 0)))
					if (FAILED(lpDP->InitializeConnection(ct->connect, 0)))
						continue;
			}
			dpcaps.dwSize = sizeof(dpcaps);
			lpDP->GetCaps(&dpcaps, 0);
			return TRUE;
		}
		seek_to_next(ListSP);
	}
	return FALSE;
}

// 建立一个会话
BOOL create_session(int max_play, char *name)
{
	DPSESSIONDESC2 dpsd;
	ZeroMemory(&dpsd, sizeof(DPSESSIONDESC2));
	dpsd.dwSize = sizeof(DPSESSIONDESC2);
	dpsd.dwFlags = DPSESSION_MIGRATEHOST | DPSESSION_KEEPALIVE;
	dpsd.guidApplication = LIB_GUID;
	dpsd.dwMaxPlayers = max_play;
	dpsd.lpszSessionNameA = name;

	if (FAILED(lpDP->Open(&dpsd, DPOPEN_CREATE)))
		return FALSE;
	*(entry_session.lpguid) = dpsd.guidInstance;
	entry_session.maxplayer = dpsd.dwMaxPlayers;
	strcpy(entry_session.name, name);
	IsHost = TRUE;
	return TRUE;
}

// 加入一个会话
BOOL join_session(char *name)
{
	if (ListSession == NULL)
		return FALSE;
	seek_to_first(ListSession);
	for (DWORD i = 0; i < ListSession->count; i++)
	{
		if (strcmp(name, ((NETSESSION *)(ListSession->entry->data))->name) == 0)
		{
			DPSESSIONDESC2 dpsd;
			ZeroMemory(&dpsd, sizeof(dpsd));
			dpsd.dwSize = sizeof(dpsd);
			dpsd.guidInstance = *(((NETSESSION *)(ListSession->entry->data))->lpguid);
			if (FAILED(lpDP->Open(&dpsd, DPOPEN_JOIN)))
				return FALSE;
			*(entry_session.lpguid) = dpsd.guidInstance;
			entry_session.maxplayer = dpsd.dwMaxPlayers;
			strcpy(entry_session.name, name);
			return TRUE;
		}
		seek_to_next(ListSession);
	}
	return FALSE;
}

BOOL CALLBACK EnumSessionsCallback(LPCDPSESSIONDESC2 lpThisSD, LPDWORD lpdwTimeOut, DWORD dwFlags, LPVOID lpContext)
{
	if (lpThisSD == NULL)
		return FALSE;
	NETSESSION *ns = new NETSESSION;
	if (ns == NULL)
		return FALSE;
	strcpy(ns->name, lpThisSD->lpszSessionNameA);
	ns->maxplayer = lpThisSD->dwMaxPlayers;
	ns->lpguid = new GUID;
	if (ns->lpguid == NULL)
		return FALSE;
	*(ns->lpguid) = lpThisSD->guidInstance;
	add_point(ListSession, ns);
	return TRUE;
}

// 枚举当前的会话
BOOL enum_session()
{
	if (ListSession != NULL)
		free_list(&ListSession);
	ListSession = create_list();
	DPSESSIONDESC2 dpsd;
	ZeroMemory(&dpsd, sizeof(DPSESSIONDESC2));
	dpsd.dwSize = sizeof(dpsd);
	dpsd.guidApplication = LIB_GUID;
	if (lpDP->EnumSessions(&dpsd, 0, EnumSessionsCallback, 0, DPENUMSESSIONS_ASYNC | DPENUMSESSIONS_AVAILABLE | DPENUMSESSIONS_RETURNSTATUS) != DP_OK)
		return FALSE;
	if (ListSession->count <= 0)
		return FALSE;
	return TRUE;
}

// 设置TCP/IP连接的IP地址
void set_net_ip(char *address)
{
	DPCOMPOUNDADDRESSELEMENT dpcp[2];
	DWORD size = 0;

	if (tcpip)
	{
		delete tcpip;
		tcpip = NULL;
	}
	dpcp[0].guidDataType = DPAID_ServiceProvider;
	dpcp[0].dwDataSize = sizeof(GUID);
	dpcp[0].lpData = (LPVOID)&DPSPGUID_TCPIP;
	dpcp[1].guidDataType = DPAID_INet;
	dpcp[1].dwDataSize = strlen(address) + 1;
	dpcp[1].lpData = address;
	lpDPL->CreateCompoundAddress(dpcp, 2, NULL, &size);
	tcpip = new char [size];
	if (tcpip == NULL)
		return;
	if (FAILED(lpDPL->CreateCompoundAddress(dpcp, 2, tcpip, &size)))
	{
		delete tcpip;
		tcpip = NULL;
	}
}

// 设置用Modem连接的电话号码
void set_net_phone(char *phone)
{
	DPCOMPOUNDADDRESSELEMENT dpcp[2];
	DWORD size = 0;

	if (modem)
	{
		delete modem;
		modem = NULL;
	}
	dpcp[0].guidDataType = DPAID_ServiceProvider;
	dpcp[0].dwDataSize = sizeof(GUID);
	dpcp[0].lpData = (LPVOID)&DPSPGUID_MODEM;
	dpcp[1].guidDataType = DPAID_Phone;
	dpcp[1].dwDataSize = strlen(phone) + 1;
	dpcp[1].lpData = phone;
	lpDPL->CreateCompoundAddress(dpcp, 2, NULL, &size);
	modem = new char [size];
	if (modem == NULL)
		return;
	if (FAILED(lpDPL->CreateCompoundAddress(dpcp, 2, modem, &size)))
	{
		delete modem;
		modem = NULL;
	}
}

// 设置串行口连接的参数
void set_net_port(int port, int speed)
{
	DPCOMPORTADDRESS comport = {port, CBR_115200, ONESTOPBIT, NOPARITY, DPCPA_RTSFLOW};
	DPCOMPOUNDADDRESSELEMENT dpcp[2];
	DWORD size = 0;

	if (serial)
	{
		delete serial;
		serial = NULL; 
	}
	switch(speed)
	{
	case 256000:
		comport.dwBaudRate = CBR_256000;
		break;
	case 128000:
		comport.dwBaudRate = CBR_128000;
		break;
	case 115200:
		comport.dwBaudRate = CBR_115200;
		break;
	case 57600:
		comport.dwBaudRate = CBR_57600;
		break;
	case 56000:
		comport.dwBaudRate = CBR_56000;
		break;
	case 38400:
		comport.dwBaudRate = CBR_38400;
		break;
	case 19200:
		comport.dwBaudRate=CBR_19200;
		break;
	case 14400:
		comport.dwBaudRate = CBR_14400;
	}
	dpcp[0].guidDataType = DPAID_ServiceProvider;
	dpcp[0].dwDataSize = sizeof(GUID);
	dpcp[0].lpData = (LPVOID)&DPSPGUID_SERIAL;
	dpcp[1].guidDataType = DPAID_ComPort;
	dpcp[1].dwDataSize = sizeof(comport);
	dpcp[1].lpData = (LPVOID)&comport;
	lpDPL->CreateCompoundAddress(dpcp, 2, NULL, &size);
	serial = new char [size];
	if (serial == NULL)
		return;
	if (FAILED(lpDPL->CreateCompoundAddress(dpcp, 2, serial, &size)))
	{
		delete serial;
		serial = NULL;
	}
}

// 建立一个玩家
BOOL create_player(char *name, char *namel, LPVOID lpdata, DWORD size)
{
	DPNAME dpname;

	ZeroMemory(&dpname,sizeof(dpname));
	dpname.dwSize=sizeof(dpname);
	dpname.lpszShortNameA=name;
	dpname.lpszLongNameA=namel;
	if (FAILED(lpDP->CreatePlayer(&PlayerID, &dpname, PlayerEvent, NULL, 0, 0)))
		return FALSE;
	return TRUE;
}

BOOL CALLBACK EnumPlayersCallback(DPID dpID, DWORD dwPlayerType, LPCDPNAME lpName, DWORD dwFlags, LPVOID lpContext)
{
	PLAYER *py = new PLAYER;
	if (py == NULL)
		return FALSE;
	py->playerid = dpID;
	py->type = dwPlayerType;
	if (lpName->lpszShortNameA == NULL)
		*py->names = NULL;
	else
		strcpy(py->names, lpName->lpszShortNameA);
	if (lpName->lpszLongNameA == NULL)
		*py->namel = NULL;
	else
		strcpy(py->namel, lpName->lpszLongNameA);
	add_point(ListPlayer, py);
	return TRUE;
}

// 枚举玩家
BOOL enum_player()
{
	if (ListPlayer != NULL)
		free_list(&ListPlayer);
	ListPlayer = create_list();
	if (FAILED(lpDP->EnumPlayers(entry_session.lpguid, EnumPlayersCallback, NULL, 0)))
		return FALSE;
	return TRUE;
}

// 接收消息的进程
DWORD WINAPI ReceiveMessage(LPVOID p)
{
	while(TRUE)
	{
	DPID idfrom, idto;
	LPVOID buffer = NULL;
	DWORD size = 0,bs = 1024;
	LPDPMSG_GENERIC lpmsg;
	LPDPMSG_CHAT chat;
	LPDPMSG_CREATEPLAYERORGROUP createplayer;
	LPDPMSG_DESTROYPLAYERORGROUP destplayer;
	LPDPMSG_SETPLAYERORGROUPNAME setname;
	LPDPMSG_SETSESSIONDESC sessiondesc;
	NETMESSAGE netmsg;
	HRESULT err;

	HANDLE e[2] = {PlayerEvent, ExitEvent};
	buffer = new char [1024];
	if (buffer == NULL)
		return -1;
	while(WaitForMultipleObjects(2, e, FALSE, INFINITE) == WAIT_OBJECT_0)
	{
		idfrom = idto = 0;
		size = bs;
		err = lpDP->Receive(&idfrom, &idto, DPRECEIVE_ALL, buffer, &size);
		while(err == DPERR_BUFFERTOOSMALL)
		{
			if (buffer)
				delete buffer;
			buffer = new char [size];
			if (buffer == NULL)
				return -1;
			bs=size;
			err = lpDP->Receive(&idfrom, &idto, DPRECEIVE_ALL, buffer, &size);
		}
		if(idfrom == DPID_SYSMSG)
		{
			lpmsg = (DPMSG_GENERIC *)buffer;
			switch(lpmsg->dwType)
			{
			case DPSYS_CHAT:
				chat = (DPMSG_CHAT *)buffer;
				netmsg.type = NETDSYS_CHAT;
				netmsg.idfrom = chat->idFromPlayer;
				netmsg.idto = chat->idToPlayer;
				netmsg.message = chat->lpChat->lpszMessageA;
				break;
			case DPSYS_CREATEPLAYERORGROUP:
				createplayer = (DPMSG_CREATEPLAYERORGROUP *)buffer;
				netmsg.type = NETDSYS_CREATEPLAYER;
				netmsg.idfrom = createplayer->dpId;
				netmsg.currentplayer = createplayer->dwCurrentPlayers;
				netmsg.shortname = createplayer->dpnName.lpszShortNameA;
				netmsg.longname = createplayer->dpnName.lpszLongNameA;
				break;
			case DPSYS_DESTROYPLAYERORGROUP:
				destplayer = (DPMSG_DESTROYPLAYERORGROUP *)buffer;
				netmsg.type = NETDSYS_DESTROYPLAYER;
				netmsg.idfrom = destplayer->dpId;
				break;
			case DPSYS_HOST:
				netmsg.type=NETDSYS_HOST;
				break;
			case DPSYS_SESSIONLOST:
				netmsg.type = NETDSYS_SESSIONLOST;
				break;
			case DPSYS_SETPLAYERORGROUPNAME:
				setname = (DPMSG_SETPLAYERORGROUPNAME *)buffer;
				netmsg.type = NETDSYS_PLAYERNAME;
				netmsg.idfrom = setname->dpId;
				netmsg.shortname = setname->dpnName.lpszShortNameA;
				netmsg.longname = setname->dpnName.lpszLongNameA;
				break;
			case DPSYS_SETSESSIONDESC:
				sessiondesc = (DPMSG_SETSESSIONDESC *)buffer;
				netmsg.type = NETDSYS_SESSIONDESC;
				netmsg.desc = &sessiondesc->dpDesc;
				break;
			default:
			case DPSYS_SENDCOMPLETE:
				netmsg.type = NETDSYS_SEND;
				continue;
			}
		}
		else
		{
			netmsg.type = NETDSYS_USERMSG;
			netmsg.data = buffer;
			netmsg.size = size;
		}
		if (NetMessageProc)
			NetMessageProc(&netmsg);
	}
	return 0;
	}
	return 0;
}

// 发送数据
BOOL send_data(NETMESSAGE *netmsg)
{
	if (dpcaps.dwFlags & DPCAPS_ASYNCSUPPORTED)
		if (FAILED(lpDP->SendEx(PlayerID, netmsg->idto, DPSEND_ASYNC, netmsg->data, netmsg->size, 0, 0, NULL, NULL)))
			return FALSE;
	else
		if (FAILED(lpDP->SendEx(PlayerID, netmsg->idto, 0, netmsg->data, netmsg->size, 0, 0, NULL, NULL)))
			return FALSE;
	return TRUE;
}

// 发送对话消息
BOOL send_chat(NETMESSAGE *netmsg)
{
	DPCHAT chat= {sizeof(DPCHAT), 0, NULL};

	chat.lpszMessageA = netmsg->message;
	if (FAILED(lpDP->SendChatMessage(PlayerID, netmsg->idto, 0, &chat)))
		return FALSE;
	return TRUE;
}

// 设置玩家名称
BOOL set_player_name(char * names, char * namel)
{
	DPNAME dpname;

	dpname.dwSize = sizeof(dpname);
	dpname.dwFlags = 0;
	dpname.lpszShortNameA = names;
	dpname.lpszLongNameA = namel;
	if (FAILED(lpDP->SetPlayerName(PlayerID, &dpname, DPSET_REMOTE)))
		return FALSE;
	return TRUE;
}

// 设置会话名称
BOOL set_session_name(char * name)
{
	DPSESSIONDESC2 dpsd;
	DWORD size = 0;

	lpDP->GetSessionDesc(&dpsd, &size);
	dpsd.lpszSessionNameA = name;
	if (FAILED(lpDP->SetSessionDesc(&dpsd, 0)))
		return FALSE;
	return TRUE;
}

⌨️ 快捷键说明

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