gateway.cpp 6.4 KB
#include "gateway.h"
#include <common_msg.pb.h>
#include <lobby_gateway.pb.h>
#include "lobby.h"

#include "user.h"


gateway_mgr_t* g_gateway_mgr;

void gateway_mgr_t::del_fd_gateway( int fd ){
	gateway_t* gateway = this->find(fd);
	if (NULL == gateway){
		ERROR_LOG("[fd:%d]", fd);
		return;
	}

	SAFE_DELETE(gateway);
	this->gateway_map.erase(fd);
}

void gateway_mgr_t::add_gateway( el::lib_tcp_peer_info_t* peer_fd_info ){
	gateway_t* gateway = this->find(peer_fd_info->fd);
	if (NULL != gateway){
		ERROR_LOG("[fd:%d]", peer_fd_info->fd);
		return;
	}

	gateway = new gateway_t(peer_fd_info);
	this->gateway_map[peer_fd_info->fd] = gateway;
	peer_fd_info->data = gateway;
}

gateway_t* gateway_mgr_t::find( int fd )
{
	auto it = this->gateway_map.find(fd);
	if (this->gateway_map.end() == it){
		return NULL;
	}
	return it->second;
}

void gateway_t::send_msg( CMD_ID cmd_id, google::protobuf::Message* msg, uint32_t seq, USER_ID uid )
{
	static char msgBuf[MAXMESSAGE_LEN];
	static void* sb = msgBuf + proto_head_t::PROTO_HEAD_LEN;
	static const int sb_len = sizeof(msgBuf) - proto_head_t::PROTO_HEAD_LEN;
	try{
		msg->SerializeToArray(sb, sb_len);

		PROTO_LEN pkg_len = proto_head_t::PROTO_HEAD_LEN + msg->ByteSize();

		proto_head_t::pack(msgBuf, pkg_len, seq, cmd_id, 0, uid);

		TRACE_LOG("======> send to gateway [cmd_id:0x%x, len:%u bytes]", cmd_id, pkg_len);
		if (!msg->Utf8DebugString().empty()){
			TRACE_LOG("[%s]", msg->Utf8DebugString().c_str());
		}
		
		el_async::s2peer(this->fd_info, msgBuf, pkg_len);
	}catch (...){
		ERROR_LOG("[cmd_id:0x%x]", cmd_id);
	}
 }

int gateway_t::send_err( CMD_ID cmd_id, uint32_t ret, uint32_t seq, USER_ID uid )
{
	TRACE_LOG("[cmd:0x%x, ret:%u]", cmd_id, ret);

	static char msgBuf[proto_head_t::PROTO_HEAD_LEN];

	proto_head_t::pack(msgBuf, proto_head_t::PROTO_HEAD_LEN, seq, cmd_id, ret, uid);

	el_async::s2peer(this->fd_info, msgBuf, proto_head_t::PROTO_HEAD_LEN);
	return 0;
}

gateway_t::gateway_t( el::lib_tcp_peer_info_t* peer_fd_info )
{
	this->fd_info = peer_fd_info;
}

gateway_t::~gateway_t()
{
	{	//del user
		std::vector<user_t*> del_user_vec;
		FOREACH(g_user_mgr->user_map, it){
			user_t* user = it->second;
			if (user->gateway != this){
				continue;
			}
			del_user_vec.push_back(user);
		}
		FOREACH(del_user_vec, it){
			user_t* user = *it;
			g_user_mgr->del_user(user->user_show.uid());
		}
	}
}

void gateway_t::send_msg_res( google::protobuf::Message* msg )
{
	this->send_msg(g_gateway_mgr->proto_head.cmd, msg, g_gateway_mgr->proto_head.seq, g_gateway_mgr->proto_head.id);
}

int gateway_mgr_t::on_recv( el::lib_tcp_peer_info_t* peer_fd_info, char* pdata, int len )
{
	gateway_t* gateway = (gateway_t*)peer_fd_info->data;

	CMD_ID cmd_id = this->proto_head.cmd;

//	TRACE_LOG("msg in [cmd_id:0x%x]", cmd_id);
	auto it = this->msg_map.find(cmd_id);
	if(this->msg_map.end() == it){
		ALERT_LOG("no msg define for [cmd_id:0x%x]", cmd_id);
		return SUCC;
	}

	USER_ID uid = this->proto_head.id;

	try{
		it->second.prototype->Clear();
		if(!it->second.prototype->ParseFromArray(pdata, len)){
			ERROR_LOG("decode message [cmd_id:0x%x] with %u bytes failed", cmd_id, len);
			return SUCC;
		}

		TRACE_LOG("<======recv gateway [uid:%" PRIu64 ", cmd_id:0x%x, body_len:%u]", 
			this->proto_head.id, cmd_id, len);
		if (!it->second.prototype->Utf8DebugString().empty()){
			TRACE_LOG("[%s]", it->second.prototype->Utf8DebugString().c_str());
		}

		int ret = (this->*it->second.func)(peer_fd_info, it->second.prototype, gateway, uid);
		if (SUCC != ret){
			TRACE_LOG("======>send error gateway [uid:%" PRIu64 ", cmd_id:0x%x, ret:%u]", 
				this->proto_head.id, cmd_id, ret);
			gateway->send_err(cmd_id, ret, this->proto_head.seq, this->proto_head.id);
		}
		return ret;
	}catch(...){
		ERROR_LOG("parse message failed cmd_id:0x%x]", cmd_id);
		return SUCC;
	}
	return SUCC;
}

gateway_mgr_t::gateway_mgr_t()
{
	this->init_msg_map();
}

gateway_mgr_t::~gateway_mgr_t()
{
	this->release_msg_map();
}

void gateway_mgr_t::init_msg_map()
{
#undef  BIND_PROTO_CMD
#undef  BIND_PROTO_CMD_NO_CB

#define BIND_PROTO_CMD_NO_CB(__cmd_id__, fun_name, proto_name)
#define BIND_PROTO_CMD(__cmd_id__, fun_name, proto_name)\
	{\
	if (this->msg_map.end() != this->msg_map.find(__cmd_id__)){\
	ALERT_LOG("cmd inster err![0x%x]", __cmd_id__);\
	exit(0);\
	} else {\
 	this->msg_map[__cmd_id__] = MSG_HANDLE_GATEWAY_MGR_T(new lobby_gateway_msg::proto_name(), &gateway_mgr_t::fun_name, true);\
	}\
}
#include <lobby_gateway_cmd.h>

#undef  BIND_PROTO_CMD
#undef  BIND_PROTO_CMD_NO_CB
}

void gateway_mgr_t::release_msg_map()
{
	FOREACH(this->msg_map, it){
		delete it->second.prototype;
	}
	this->msg_map.clear();
}

//////////////////////////////////////////////////////////////////////////
// handle msg from gateway



int gateway_mgr_t::on_lobby_enter_msg(el::lib_tcp_peer_info_t* fd_info,
									  google::protobuf::Message* msg,
									  gateway_t* gateway, USER_ID uid){
	user_t* user = g_user_mgr->find(uid);
	if (NULL != user){
		WARN_LOG("");
		return 0;
	}
	auto in = (lobby_gateway_msg::lobby_enter_msg*)msg;

	user = g_user_mgr->add_user(uid, gateway);

	{
		lobby_gateway_msg::lobby_enter_msg_res out;
		gateway->send_msg_res(&out);
	}	

	{
		user->user_show.CopyFrom(in->user_show());
		FOREACH_PB(in->pet_btl, idx){
			const share_msg::pet_btl_t& pb = in->pet_btl(idx);
			pet_t pet;
			pet.pet_btl.CopyFrom(pb);
			pet.pet_btl.set_key(g_lobby->gen_pet_key());

			pet.pet_cfg = g_pet_cfg_mgr->find_pet_cfg(pet.pet_btl.id());
			if (NULL == pet.pet_cfg){
				g_user_mgr->del_user(user->uid());
				return 0;
			}
			pet.skill = user->pet_mgr.find_skill(pet.pet_btl.id());
			pet.pet_mgr = &user->pet_mgr;

			user->pet_mgr.pet_vec.push_back(pet);
		}

		if (2 <= g_user_mgr->user_map.size()){
			room_t room;

			FOREACH(g_user_mgr->user_map, it){
				user_t* user = it->second;
				room.user_vec.push_back(user);
				if (2 == room.user_vec.size()){
					break;
				}
			}

			std::random_shuffle(room.user_vec.begin(), room.user_vec.end());

			room.ack()->room = &room;
			room.def()->room = &room;

			g_lobby->btl(&room);
			// 4.战斗结束
			{

			}

			{
				g_user_mgr->del_user(room.ack()->uid());
				g_user_mgr->del_user(room.def()->uid());
			}
		}
	}
	return 0;
}

int gateway_mgr_t::on_lobby_out_msg(el::lib_tcp_peer_info_t* fd_info,
									google::protobuf::Message* msg,
									gateway_t* gateway, USER_ID uid){
	user_t* user = g_user_mgr->find(uid);
	if (NULL == user){
		WARN_LOG("");
		return 0;
	}
	g_user_mgr->del_user(uid);

	return 0;
}