game_server.cpp

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

CPP
988
字号
// Game_Server.cpp: implementation of the Game_Server class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"

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

#define BROADCAST_LIST_MAX 200
int	base_magic_damage_list[]	= {26, 23, 28, 25, 40, 50, 70, 50, 50, 50};

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

Game_Server::Game_Server()
{
	m_uid_session	= 0;
	m_game_unit_mgr.set_game_server(this);
	m_tick_loop	= 0;
	m_last_tick	= 0;
}

Game_Server::~Game_Server()
{

}

BOOL Game_Server::InitServer()
{

	


	return TRUE;
}

void Game_Server::Shutdown()
{
	m_thread_pool.Cleanup();
	m_socket.Shutdown();
}

void Game_Server::DoUpdate()
{
	uint32 tick = Sys_GetTime();
	if(m_last_tick==0)
		m_last_tick	= tick;
	m_tick_loop		= tick-m_last_tick;
	m_last_tick		= tick;
	//处理游戏世界的逻辑、怪物活动和生成
	m_game_unit_mgr.DoUpdate();
	//处理游戏操作和消息
   	NET_Packet *ptr_packet = m_socket.PopRecvPacket();
	while (ptr_packet)
	{
		uint32 uid	= ptr_packet->getUID();
		switch(ptr_packet->getCmd()) 
		{
		case NLIBP_CONNECT:
			{			
				m_uid_session = uid;
				on_login(uid);
			}
			break;
		case NLIBP_DISCONNECT:
			{
				m_uid_session = 0;
				on_logout(uid);
			}
			break;
		case NLIBP_CHECK_CONNECT:
			{
				uint32 uid	= ptr_packet->read32();
				time_t tm	= ptr_packet->read32();
				if(tm>20000)
				{//掉线
					m_socket.CloseSession(uid);
					on_logout(uid);
				}
				else
				{
					if(ptr_packet->getUID()==0)
					{//ping
						NET_Session* pSession = m_socket.get_NET_Session(uid);
						if(pSession)
						{
							pSession->Ping();
						}
					}
				}			
			}
			break;
		case	GSP_ADD_UNIT://来源|数据|接口id|广播列表
			{
				//uint16 unit_id	= ptr_packet->readString();
				//生成角色
				uint32 uid_player	= ptr_packet->read32();
				STRUCT_ADD_UNIT* pSAU	= (STRUCT_ADD_UNIT*)ptr_packet->readData();
				uint32 uid_session	= ptr_packet->read32();
				on_add_unit(uid_session, pSAU);
			}
			break;
		case GSP_DEL_UNIT://来源|数据|广播列表
			{
				uint32 uid_player	= ptr_packet->read32();
				STRUCT_DEL_UNIT*	pSDU	= (STRUCT_DEL_UNIT*)ptr_packet->readData();
				on_del_unit(uid_player, pSDU);
			}
			break;
		case GSP_SPEEK:
			{
				NET_Session* pSession = m_socket.get_NET_Session(uid);
				if(pSession)
				{
					uint32 uid_player = ptr_packet->read32();
					uint32 uid_speeker = ptr_packet->read32();
					const char* strSpeek = ptr_packet->readString();
					on_speek(uid_player, uid_speeker, strSpeek);
				}
			}
			break;
		case GSP_HANDLE_PLACE://数据|广播列表
			{
				NET_Session* pSession = m_socket.get_NET_Session(uid);
				if(pSession)
				{
					uint32 uid_player = ptr_packet->read32();
					STRUCT_HANDLE_PLACE* p = (STRUCT_HANDLE_PLACE*)ptr_packet->readData();
					on_handle_place(uid_player, p);
				}

			}
			break;
		case GSP_UPDATE_STATE:
			{
				NET_Session* pSession = m_socket.get_NET_Session(uid);
				if(pSession)
				{
					uint32 uid_player = ptr_packet->read32();
					STRUCT_UPDATE_STATE* p = (STRUCT_UPDATE_STATE*)ptr_packet->readData();
					on_update_state(uid_player, p);
				}
				
			}
			break;
		case GSP_HANDLE_UNIT://数据|广播列表
			{
				NET_Session* pSession = m_socket.get_NET_Session(uid);
				if(pSession)
				{
					uint32 uid_player = ptr_packet->read32();
					STRUCT_HANDLE_UNIT* p = (STRUCT_HANDLE_UNIT*)ptr_packet->readData();
					on_handle_unit(uid_player, p);
				}
				
			}
			break;
		default:
			break;
		}
		delete(ptr_packet);
		ptr_packet	= m_socket.PopRecvPacket();
	}
	
}

void Game_Server::on_add_unit(uint32 uid_session, STRUCT_ADD_UNIT* pSAU)
{
	GAME_UNIT* pUnit = m_game_unit_mgr.create_unit();
	pUnit->monster_index	= 0;
	pUnit->nick_name	= pSAU->str_name;
	m_game_unit_mgr.update_unit_pos(pUnit->uid, pSAU->pos_x, pSAU->pos_y);
	pUnit->pos_h		= pSAU->pos_h;
	pUnit->face_to		= pSAU->face_to;
	pUnit->unit_type	= pSAU->unit_type;
	pUnit->m_uid_session	= uid_session;
		
	pUnit->base_level		= pSAU->base_level;
	pUnit->base_experience	= pSAU->base_experience;;
	pUnit->base_life		= pSAU->base_life;
	pUnit->base_mana		= pSAU->base_mana;
	pUnit->base_damage		= pSAU->base_damage;
	pUnit->base_strength	= pSAU->base_strength;
	pUnit->base_agility		= pSAU->base_agility;
	pUnit->base_magic		= pSAU->base_magic;
	pUnit->life				= pSAU->life;
	pUnit->mana				= pSAU->mana;			
			
	pUnit->count_die		= pSAU->count_die;
	pUnit->count_hunter		= pSAU->count_hunter;
	pUnit->count_pk			= pSAU->count_pk;
				
	pSAU->uid			= pUnit->uid;
//	//计算升级的经验
	if(pUnit->base_level>1)
	{
		pUnit->exp_level			= pow(1.25, (int)pUnit->base_level-2)*2000.0f-1500;
	}
	else
	{
		pUnit->exp_level=0;
	}
	pUnit->exp_level_up		= pow(1.25, (int)pUnit->base_level-1)*2000.0f-1500;
//	pUnit->exp_level				= pSAU->exp_level;			
//	pUnit->exp_level_up				= pSAU->exp_level_up;
	pSAU->exp_level			= pUnit->exp_level;	
	pSAU->exp_level_up		= pUnit->exp_level_up;	
			
				//pSAU->unit_flag		= 0;
				//告诉GuideServer广播的信息和广播的列表
	NET_Packet*	pPacket	= new NET_Packet;
	pPacket->setCmd(GSP_ADD_UNIT);
	pPacket->write32(pUnit->uid);//来源
	pPacket->writeData(pSAU, sizeof(STRUCT_ADD_UNIT));//数据
	pPacket->write32(uid_session);//通信接口id
	GAME_UNIT_MAP::iterator it = m_game_unit_mgr.m_game_unit_map.begin();
	uint32 aPlayers[BROADCAST_LIST_MAX];
	int i=0;
//	while(it!= m_game_unit_mgr.m_game_unit_map.end())
//	{
//		//生成列表
//		if(it->second.m_uid_session>0 && i<BROADCAST_LIST_MAX)
//		{
//			aPlayers[i]	= it->second.m_uid_session;
//			i++;
//		}
//		it++;
//	}
	pPacket->write16(i);//广播人数
	if(i>0)
		pPacket->writeData(aPlayers, i*sizeof(uint32));//广播列表
	m_socket.PushSendPacket(m_uid_session, pPacket);
				
	//把新增角色周围的角色资料通知该角色
	it = m_game_unit_mgr.m_game_unit_map.begin();
	while(it!= m_game_unit_mgr.m_game_unit_map.end())
	{
		if(it->second.uid!=pUnit->uid)
		{
			STRUCT_ADD_UNIT sau_temp;
			sau_temp.uid	= it->second.uid;
			sau_temp.unit_type = it->second.unit_type;
			sau_temp.pos_x	= it->second.pos_x;
			sau_temp.pos_y	= it->second.pos_y;
			sau_temp.pos_h	= it->second.pos_h;
			sau_temp.face_to	= it->second.face_to;
						
			strcpy(sau_temp.str_name, it->second.nick_name.c_str());
			sau_temp.base_level		= it->second.base_level;
			sau_temp.base_experience	= it->second.base_experience;;
			sau_temp.base_life		= it->second.base_life;
			sau_temp.base_mana		= it->second.base_mana;
			sau_temp.base_damage		= it->second.base_damage;
			sau_temp.base_strength		= it->second.base_strength;
			sau_temp.base_agility		= it->second.base_agility;
			sau_temp.base_magic			= it->second.base_magic;
			sau_temp.life				= it->second.life;
			sau_temp.mana				= it->second.mana;
			sau_temp.count_die		= it->second.count_die;
			sau_temp.count_hunter		= it->second.count_hunter;
			sau_temp.count_pk			= it->second.count_pk;
			
						
			NET_Packet*	pPacket	= new NET_Packet;
			pPacket->setCmd(GSP_ADD_UNIT);
			pPacket->write32(pUnit->uid);
			pPacket->writeData(&sau_temp, sizeof(STRUCT_ADD_UNIT));
			pPacket->write32(uid_session);//通信接口id
			pPacket->write16(1);
			pPacket->writeData(&pUnit->m_uid_session, sizeof(uint32));
			m_socket.PushSendPacket(m_uid_session, pPacket);
		}
		it++;
	}
}
void Game_Server::on_del_unit(uint32 uid_player, STRUCT_DEL_UNIT* pSDU)
{
	GAME_UNIT_MAP::iterator it;// = m_game_unit_mgr.m_game_unit_map.find(pSDU->uid);
	//if(it!= m_game_unit_mgr.m_game_unit_map.end())
	//	m_game_unit_mgr.m_game_unit_map.erase(it);					
	m_game_unit_mgr.delete_unit(pSDU->uid);
	//告诉GuideServer广播的信息和广播的列表
	NET_Packet*	pPacket	= new NET_Packet;
	pPacket->setCmd(GSP_DEL_UNIT);
	pPacket->writeData(pSDU, sizeof(STRUCT_DEL_UNIT));
	it = m_game_unit_mgr.m_game_unit_map.begin();
	uint32 aPlayers[BROADCAST_LIST_MAX];
	int i=0;
//	while(it!= m_game_unit_mgr.m_game_unit_map.end())
//	{
//		//生成列表
//		if(it->second.m_uid_session>0 && i<BROADCAST_LIST_MAX)
//		{
//			aPlayers[i]	= it->second.m_uid_session;
//			i++;
//		}
//		it++;
//	}
	pPacket->write16(i);
	if(i>0)
		pPacket->writeData(aPlayers, i*sizeof(uint32));
	m_socket.PushSendPacket(m_uid_session, pPacket);
}
void Game_Server::on_update_state(uint32 uid_player, STRUCT_UPDATE_STATE* p_sus)
{
	GAME_UNIT* pUnit = m_game_unit_mgr.get_game_unit(p_sus->uid);
	if(pUnit)
	{
		m_game_unit_mgr.update_unit_pos(pUnit->uid, p_sus->src_x, p_sus->src_y);
		pUnit->pos_h	= p_sus->src_h;
		pUnit->face_to	= p_sus->face_to;
	}
}
void Game_Server::on_handle_place(uint32 uid_player, STRUCT_HANDLE_PLACE* p_shp)
{
	GAME_UNIT* pUnit = m_game_unit_mgr.get_game_unit(p_shp->uid);
	if(pUnit)
	{
		m_game_unit_mgr.update_unit_pos(pUnit->uid, p_shp->pos.src_x, p_shp->pos.src_y);
		pUnit->pos_h	= p_shp->pos.src_h;
		//if(pUnit->)
	}
	//算出广播列表
	uint32 aPlayers[BROADCAST_LIST_MAX];
	uint16 i=0;
	i = m_game_unit_mgr.select_range_player_session(aPlayers, pUnit->pos_x, pUnit->pos_y, GMS_UPDATE_RANGE);
	if(i>0)
	{
		//告诉GuideServer广播的信息和广播的列表
		NET_Packet*	pPacket	= new NET_Packet;
		pPacket->setCmd(GSP_HANDLE_PLACE);
		pPacket->writeData(p_shp, sizeof(STRUCT_HANDLE_PLACE));//数据
		pPacket->write16(i);
		pPacket->writeData(aPlayers, i*sizeof(uint32));
		m_socket.PushSendPacket(m_uid_session, pPacket);
	}
}
void Game_Server::on_handle_unit(uint32 uid_player, STRUCT_HANDLE_UNIT* p_shu)
{
	GAME_UNIT* pUnit = m_game_unit_mgr.get_game_unit(p_shu->uid);
	GAME_UNIT* pUnit_obj = m_game_unit_mgr.get_game_unit(p_shu->uid_obj);
	if(pUnit)
	{
		m_game_unit_mgr.update_unit_pos(pUnit->uid, p_shu->pos.src_x, p_shu->pos.src_y);
		pUnit->pos_h	= p_shu->pos.src_h;
		//if(pUnit->)
		//pUnit->pos_x	= p->src_x;
		//pUnit->pos_y	= p->src_y;
		//pUnit_obj->pos_x	= p->dest_x;
		//pUnit_obj->pos_y	= p->dest_y;
		switch(p_shu->action) 
		{
		case GSACT_AIM_OBJECT:
			{
				if(pUnit_obj)
				{
					m_game_unit_mgr.update_unit_pos(pUnit_obj->uid, p_shu->pos.dest_x, p_shu->pos.dest_y);
					pUnit_obj->pos_h	= p_shu->pos.dest_h;
				}
				else
				{
					pUnit->uid_aim_unit	= 0;
					m_game_unit_mgr.update_unit_pos(pUnit->uid, p_shu->pos.src_x, p_shu->pos.src_y);
					pUnit->pos_h	= p_shu->pos.src_h;
					STRUCT_HANDLE_PLACE shp;
					shp.uid		= pUnit->uid;
					shp.pos.src_x	= pUnit->pos_x;
					shp.pos.src_y	= pUnit->pos_y;
					shp.pos.src_h	= pUnit->pos_h;
					shp.pos.dest_x	= pUnit->pos_x;
					shp.pos.dest_y	= pUnit->pos_y;
					shp.pos.dest_h	= pUnit->pos_h;
					//算出广播列表
					uint32 aPlayers[BROADCAST_LIST_MAX];
					uint16 i=0;
					i = m_game_unit_mgr.select_range_player_session(aPlayers, pUnit->pos_x, pUnit->pos_y, GMS_UPDATE_RANGE);
					//if(i>0)
					{
						//告诉GuideServer广播的信息和广播的列表
						NET_Packet*	pPacket	= new NET_Packet;
						pPacket->setCmd(GSP_HANDLE_PLACE);
						pPacket->writeData(&shp, sizeof(STRUCT_HANDLE_PLACE));//数据
						pPacket->write16(i);
						if(i>0)
							pPacket->writeData(aPlayers, i*sizeof(uint32));
						m_socket.PushSendPacket(m_uid_session, pPacket);
					}
				}
			}
			break;
		case GSACT_ATTACK:
			{//告诉GuideServer广播的信息和广播的列表
				if(pUnit_obj)
				{
					m_game_unit_mgr.update_unit_pos(pUnit_obj->uid, p_shu->pos.dest_x, p_shu->pos.dest_y);
					pUnit_obj->pos_h	= p_shu->pos.dest_h;
//					if(pUnit_obj->life<=0)
//					{//目标已经死了
//						break;
//					}
					BOOL bValid = (pUnit_obj->life>0);
					memset(&p_shu->effect_specific, 0, sizeof(STRUCT_EFFECT_SPECIFIC));
					//p_shu->effect_specific.life_alter	= 0;
					if(bValid)
						p_shu->effect_specific.life_alter_obj	= -(pUnit->base_damage*0.7F+0.3F*pUnit->base_damage*pUnit->base_strength/pUnit_obj->base_strength)*(float(rand())/(RAND_MAX)*0.8+0.7);//算出攻击的伤害
					//p_shu->effect_specific.mana_alter	= 0;
					//p_shu->effect_specific.mana_alter_obj	= 0;
					//p_shu->effect_specific.value_special	= pUnit->base_life*pUnit->base_strength/pUnit_obj->base_life/pUnit_obj->base_strength;
					p_shu->effect_specific.uid_action_type	= p_shu->uid_action_type;
					p_shu->effect_specific.uid_victim	= p_shu->uid_obj;
					//p_shu->effect_specific.experience_alter	= 0;
					if(float(rand())/(RAND_MAX)>0.2)
					{
						p_shu->effect_specific.flag_special		= 11;
						if(bValid)
						{
							if(p_shu->effect_specific.uid_action_type>=100 &&  p_shu->effect_specific.uid_action_type<1000
								&& float(rand())/(RAND_MAX)>0.7)
							{
								if(pUnit->m_uid_session<=0)
									p_shu->effect_specific.life_alter_obj	*= 1.5;
								else
									p_shu->effect_specific.life_alter_obj	*= 3;
								p_shu->effect_specific.uid_action_type	+= 50;
							}
							pUnit->life += p_shu->effect_specific.life_alter;
							pUnit->mana += p_shu->effect_specific.mana_alter;
							pUnit_obj->life += p_shu->effect_specific.life_alter_obj;
							pUnit_obj->mana += p_shu->effect_specific.mana_alter_obj;

							pUnit->learn_physics	++;
						}
						if(pUnit_obj->life<=0)
						{
							if(bValid)
							{
								pUnit_obj->count_die++;
								if(pUnit_obj->m_uid_session>0)
								{
									pUnit->count_pk++;
									p_shu->effect_specific.flag_special	= 2;
								}
								else
								{
									pUnit->count_hunter++;
									p_shu->effect_specific.flag_special	= 1;
								}
							}
							else
							{
								p_shu->effect_specific.flag_special	= 3;
							}
							//if(pUnit_obj->m_uid_session<=0)
							pUnit_obj->uid_aim_unit	= 0;
						}
						calc_experience(p_shu->effect_specific, pUnit, pUnit_obj);
						
					}
					else
					{
						p_shu->effect_specific.flag_special = 10;
					}
					uint32 aPlayers[BROADCAST_LIST_MAX];
					uint16 i=0;
//					i = m_game_unit_mgr.select_range_player_session(aPlayers, pUnit->pos_x, pUnit->pos_y, GMS_UPDATE_RANGE);
//					if(i>0)
//					{
						NET_Packet*	pPacket	= new NET_Packet;
						pPacket->setCmd(GSP_HANDLE_UNIT);
						pPacket->writeData(p_shu, sizeof(STRUCT_HANDLE_UNIT));
						pPacket->write16(i);
						if(i>0)
							pPacket->writeData(aPlayers, i*sizeof(uint32));
						m_socket.PushSendPacket(m_uid_session, pPacket);
//					}
					if(pUnit_obj->uid_aim_unit==0 && pUnit_obj->m_uid_session<=0 
						&& pUnit_obj->life>0 && pUnit->life>0)
					{//是怪物被打了,那么就还击
						on_monster_aim_unit(pUnit_obj->uid, pUnit->uid);
						pUnit_obj->uid_aim_unit	= pUnit->uid;
						pUnit_obj->enmity		= ENMITY_VALUE;
					}
				}
				else
				{
				}

				if(pUnit->m_uid_session<=0 
//					&& p_shu->effect_specific.uid_action_type<100

⌨️ 快捷键说明

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