guide_server.cpp

来自「混乱竞技场的全套代码,客户端资源可以网上搜」· C++ 代码 · 共 481 行

CPP
481
字号
// Guide_Server.cpp: implementation of the Guide_Server class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "GuideServer.h"
#include "Guide_Server.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

Guide_Server::Guide_Server()
{

}

Guide_Server::~Guide_Server()
{

}

BOOL Guide_Server::InitServer()
{

	


	return TRUE;
}

void Guide_Server::Shutdown()
{
	m_thread_pool.Cleanup();
	m_socket_player.Shutdown();
	m_socket_game.Shutdown();
}

void Guide_Server::DoUpdate()
{
	//首先处理来自玩家的通信包
   	NET_Packet *ptr_packet = m_socket_player.PopRecvPacket();
	while (ptr_packet)
	{
		uint32 uid	= ptr_packet->getUID();
		switch(ptr_packet->getCmd()) 
		{
		case NLIBP_CONNECT:
			{				
				on_login(uid);
			}
			break;
		case NLIBP_DISCONNECT:
			{
				on_logout(uid);
			}
			break;
		case NLIBP_CHECK_CONNECT:
			{
				uint32 uid_logout	= ptr_packet->read32();
				time_t tm	= ptr_packet->read32();
				if(tm>20000)
				{//掉线
					m_socket_player.CloseSession(uid_logout);
					on_logout(uid_logout);
//					STRUCT_DEL_UNIT	sdu;
//					sdu.uid	= uid_logout;
//					std::map<uint32, USER_INFO>::iterator it = m_map_user_info.begin();
//					while(it==m_map_user_info.end())
//					{
//						if(it->second.uid_session)
//					}
//						break;
//					uint16 uid_game_server = it->second.uid_server;
//					m_map_user_info.erase(it);
//					//通知游戏世界服务器
//					NET_Packet*	pPacket	= new NET_Packet;
//					pPacket->setCmd(GSP_DEL_UNIT);
//					pPacket->write16(sdu.uid);
//					pPacket->writeData(&sdu, sizeof(STRUCT_DEL_UNIT));
//					m_socket_game.PushSendPacket(uid_game_server, pPacket);
				}
				else
				{
					if(ptr_packet->getUID()==0)
					{//ping
						NET_Session* pSession = m_socket_player.get_NET_Session(uid);
						if(pSession)
						{
							pSession->Ping();
						}
					}
				}			
			}
			break;
		case GSP_TALK:
			{
			}
			break;
		case GSP_SPEEK:
		case GSP_HANDLE_PLACE:
		case GSP_UPDATE_STATE:
		case GSP_HANDLE_UNIT:
			{//转发数据到相应的游戏世界服务器进行处理
				uint32 uid_player = ptr_packet->read32();//得到来源角色id
				//ptr_packet->readData();
				ptr_packet->skip_all();
				USER_INFO* pui	= get_user_info(uid);
				if(pui==NULL)
					break;
				m_socket_game.PushSendPacket(pui->uid_server, ptr_packet);
				ptr_packet	= NULL;
			}
			break;
		case GSP_LOGIN:
			{
				std::string str_account, str_password;
				str_account	= ptr_packet->readString();
				str_password = ptr_packet->readString();
				NET_Session* pSession = m_socket_player.get_NET_Session(uid);
				if(pSession)
				{
					NET_Packet*	pPacket	= new NET_Packet;
					pPacket->setCmd(GSP_LOGIN);
					pSession->PushSendPacket(pPacket);
				}
				//生成角色,这些数据应该从数据库里得到
				STRUCT_ADD_UNIT sau;
				memset(&sau, 0, sizeof(STRUCT_ADD_UNIT));
				sau.uid	= 0;
				sau.unit_type = ptr_packet->read16();//float(rand())/(RAND_MAX+1)*13+1;
				sau.pos_x	= 100+200*float(rand())/(RAND_MAX+1);
				sau.pos_y	= 100+100*float(rand())/(RAND_MAX+1);
				sau.pos_h	= 0;
				strcpy(sau.str_name, str_account.c_str());
				sau.base_level			= 1;
				sau.base_experience		= 0;
				sau.base_life			= 800;
				sau.base_mana			= 600;
				sau.base_damage			= 20;
				sau.base_strength		= 20;
				sau.base_agility		= 20;
				sau.base_magic			= 20;
				sau.life				= sau.base_life;
				sau.mana				= sau.base_mana;
				uint16 uid_game_server = 1;//这个值要从数据库里得到,是由角色所属的游戏世界服务器而定
				//通知游戏世界服务器有新的角色要加入
				{
					NET_Packet*	pPacket	= new NET_Packet;
					pPacket->setCmd(GSP_ADD_UNIT);
					pPacket->write32(0);//无来源,要求创建新的玩家
					pPacket->writeData(&sau, sizeof(STRUCT_ADD_UNIT));//数据
					pPacket->write32(uid);//通信接口的id
					m_socket_game.PushSendPacket(uid_game_server, pPacket);
				}
			}
			break;
		case GSP_LOGOUT:
			{
				STRUCT_DEL_UNIT	sdu;
				sdu.uid	= ptr_packet->read32();
				std::map<uint32, USER_INFO>::iterator it = m_map_user_info.find(uid);
				if(it==m_map_user_info.end())
					break;
				uint32 uid_game_server = it->second.uid_server;
				m_map_user_info.erase(it);
				//通知游戏世界服务器
				NET_Packet*	pPacket	= new NET_Packet;
				pPacket->setCmd(GSP_DEL_UNIT);
				pPacket->write32(sdu.uid);
				pPacket->writeData(&sdu, sizeof(STRUCT_DEL_UNIT));
				m_socket_game.PushSendPacket(uid_game_server, pPacket);
			}
			break;
		default:
			break;
		}
		if(ptr_packet)
			delete(ptr_packet);
		ptr_packet	= m_socket_player.PopRecvPacket();
	}
	//然后来自游戏世界服务器的通信包
   	ptr_packet = m_socket_game.PopRecvPacket();
	while (ptr_packet)
	{
		uint32 uid	= ptr_packet->getUID();
		uint16 cmd = ptr_packet->getCmd();
		switch(cmd) 
		{
		case NLIBP_CONNECT:
			{				
				//on_login(uid);
			}
			break;
		case NLIBP_DISCONNECT:
			{
				//on_logout(uid);
			}
			break;
		case NLIBP_CHECK_CONNECT:
			{
				uint32 uid	= ptr_packet->read32();
				time_t tm	= ptr_packet->read32();
				if(tm>20000)
				{//掉线
					m_socket_game.CloseSession(uid);
					//on_logout(uid);
				}
				else
				{
					if(ptr_packet->getUID()==0)
					{//ping
						NET_Session* pSession = m_socket_game.get_NET_Session(uid);
						if(pSession)
						{
							pSession->Ping();
						}
					}
				}			
			}
			break;
		case GSP_SPEEK:
			{
				uint32	uid_speeker		= ptr_packet->read32();
				const char* strSpeek	= ptr_packet->readString();
				uint16 num_players	= ptr_packet->read16();
				if(num_players==0)
				{
					std::map<uint32, USER_INFO>::iterator it = m_map_user_info.begin();
					while(it!=m_map_user_info.end())
					{
						if(it->second.uid_server==uid)
						{
							NET_Packet*		pPacket = new NET_Packet;
							pPacket->setCmd(cmd);
							pPacket->write32(uid_speeker);
							pPacket->writeString(strSpeek);
							m_socket_player.PushSendPacket(it->second.uid_session, pPacket);
						}
						it++;
					}
				}
				else
				{
					uint32* aPlayers	= (uint32*)ptr_packet->readData();
					for(int i=0; i<num_players && aPlayers; i++)
					{
						//USER_INFO* pui_player	= get_user_info(aPlayers[i]);
						//if(pui_player)
						{
							NET_Packet*		pPacket = new NET_Packet;
							pPacket->setCmd(cmd);
							pPacket->write32(uid_speeker);
							pPacket->writeString(strSpeek);
							m_socket_player.PushSendPacket(aPlayers[i], pPacket);
						}
					}
				}
			}
			break;
		case GSP_HANDLE_PLACE:
		case GSP_UPDATE_STATE:
		case GSP_HANDLE_UNIT:
			{//这里主要是根据广播列表实现广播,最简单的方法就是逐个会话发一个同样的数据包
				_PACKET_DATA pd = ptr_packet->readBinary();
				//广播
				uint16 num_players	= ptr_packet->read16();
				if(num_players==0)
				{
					std::map<uint32, USER_INFO>::iterator it = m_map_user_info.begin();
					while(it!=m_map_user_info.end())
					{
						if(it->second.uid_server==uid)
						{
							NET_Packet*		pPacket = new NET_Packet;
							pPacket->setCmd(cmd);
							pPacket->writeData(pd.ptr_data, pd.data_len);
							m_socket_player.PushSendPacket(it->second.uid_session, pPacket);
						}
						it++;
					}
				}
				else
				{
					uint32* aPlayers	= (uint32*)ptr_packet->readData();
					for(int i=0; i<num_players && aPlayers; i++)
					{
						//USER_INFO* pui_player	= get_user_info(aPlayers[i]);
						//if(pui_player)
						{
							NET_Packet*		pPacket = new NET_Packet;
							pPacket->setCmd(cmd);
							pPacket->writeData(pd.ptr_data, pd.data_len);
							m_socket_player.PushSendPacket(aPlayers[i], pPacket);
						}
					}
				}
			}
			break;
		case GSP_ADD_UNIT:
			{
				uint32 uid_player = ptr_packet->read32();//得到来源角色id
				_PACKET_DATA pd = ptr_packet->readBinary();
				uint32 uid_session	= ptr_packet->read32();
				USER_INFO* pui	= get_user_info(uid_session);
				if(pui==NULL&&uid_player!=0)
				{//新创的角色,加入信息列表中
					m_map_user_info[uid_session].uid_player = uid_player;
					m_map_user_info[uid_session].uid_server = uid;
					m_map_user_info[uid_session].uid_session = uid_session;
				}
				//广播
				uint16 num_players	= ptr_packet->read16();
				if(num_players==0)
				{
					std::map<uint32, USER_INFO>::iterator it = m_map_user_info.begin();
					while(it!=m_map_user_info.end())
					{
						if(it->second.uid_server==uid)
						{
							NET_Packet*		pPacket = new NET_Packet;
							pPacket->setCmd(cmd);
							pPacket->writeData(pd.ptr_data, pd.data_len);
							m_socket_player.PushSendPacket(it->second.uid_session, pPacket);
						}
						it++;
					}
				}
				else
				{
					uint32* aPlayers	= (uint32*)ptr_packet->readData();
					for(int i=0; i<num_players && aPlayers; i++)
					{
						//USER_INFO* pui_player	= get_user_info(aPlayers[i]);
						//if(pui_player)
						{
							NET_Packet*		pPacket = new NET_Packet;
							pPacket->setCmd(cmd);
							pPacket->writeData(pd.ptr_data, pd.data_len);
							m_socket_player.PushSendPacket(aPlayers[i], pPacket);
						}
					}
				}
			}
			break;
		case GSP_DEL_UNIT:
			{
				_PACKET_DATA pd = ptr_packet->readBinary();
				//广播
				uint16 num_players	= ptr_packet->read16();
				if(num_players==0)
				{
					std::map<uint32, USER_INFO>::iterator it = m_map_user_info.begin();
					while(it!=m_map_user_info.end())
					{
						if(it->second.uid_server==uid)
						{
							NET_Packet*		pPacket = new NET_Packet;
							pPacket->setCmd(cmd);
							pPacket->writeData(pd.ptr_data, pd.data_len);
							m_socket_player.PushSendPacket(it->second.uid_session, pPacket);
						}
						it++;
					}
				}
				else
				{
					uint32* aPlayers	= (uint32*)ptr_packet->readData();
					for(int i=0; i<num_players && aPlayers; i++)
					{
						//USER_INFO* pui_player	= get_user_info(aPlayers[i]);
						//if(pui_player)
						{
							NET_Packet*		pPacket = new NET_Packet;
							pPacket->setCmd(cmd);
							pPacket->writeData(pd.ptr_data, pd.data_len);
							m_socket_player.PushSendPacket(aPlayers[i], pPacket);
						}
					}
				}
			}
			break;
		default:
			break;
		}
		if(ptr_packet)
			delete(ptr_packet);
		ptr_packet	= m_socket_game.PopRecvPacket();
	}
}

bool Guide_Server::IsActive()
{
	return m_socket_player.is_active();
}


int Guide_Server::get_thread_count()
{
	return m_thread_pool.get_Thread_count();
}

int Guide_Server::get_online_count()
{
	return m_socket_player.GetSessionCount();
}

bool Guide_Server::StartServer()
{
//	if(m_str_path.empty()||m_str_ver.empty())
//	{
//		Sys_Log("服务器错误", "服务器没有初始化服务内容!");
//		return false;
//	}
	CFG	cfg;
	cfg.open("guide_server.ini");
	uint16 port = cfg.GetLong("main", "port_client");

	//创建与客户端的通信接口
	if (!m_socket_player.Create(port))//SERVER_PORT))
	{
		Sys_Log("服务器错误", "服务器玩家通信接口创建失败!");
		return false;
	}
	m_socket_player.RunTransfersThread();	
	//创建与服务器端的通信接口,并读取配置连接各个游戏世界服务器
	port = cfg.GetLong("main", "port_game");
	if (!m_socket_game.Create(port))//SERVER_PORT))
	{
		Sys_Log("服务器错误", "服务器游戏通信接口创建失败!");
		return false;
	}
	m_socket_game.RunTransfersThread();	
	 
	for(int i=1; i<1000; i++)
	{
		char str[100];
		sprintf(str, "game_server_%d", i);
		uint16 uid_game = cfg.GetLong(str, "uid");
		if(uid_game==0)
			break;
		uint32 ip_game = ntohl(inet_addr(cfg.GetString(str, "ip", "0.0.0.0")));
		if(ip_game==0)
		{
			ip_game	= ntohl(NET_GetLocalIP());
		}
		uint32 port_game = cfg.GetLong(str, "port");
		NET_Session*	pSession = m_socket_game.CreateUniqueSession(ip_game, port_game, uid_game);
		if(pSession)
		{
			pSession->Connect();
			Sys_Log("服务器操作", "游戏世界服务器(%d)连接成功!", i);
		}
	}

	Sys_Log("服务器操作", "游戏管理服务器启动完成!");
	return true;
}

void Guide_Server::StopServer()
{
	Shutdown();
	Sys_Log("服务器操作", "服务器已经关闭!");
}

USER_INFO* Guide_Server::get_user_info(uint32 uid_session)
{
	std::map<uint32, USER_INFO>::iterator it = m_map_user_info.find(uid_session);
	if(it!=m_map_user_info.end())
	{
		return &it->second;
	}
	return NULL;
}

⌨️ 快捷键说明

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