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 + -
显示快捷键?