📄 bubble_server.cpp
字号:
// Bubble_Server.cpp: implementation of the Bubble_Server class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "BubbleServer.h"
#include "Bubble_Server.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
Bubble_Server::Bubble_Server()
{
}
Bubble_Server::~Bubble_Server()
{
}
BOOL Bubble_Server::InitServer()
{
return TRUE;
}
void Bubble_Server::Shutdown()
{
m_thread_pool.Cleanup();
m_socket_player.Shutdown();
m_socket_game.Shutdown();
}
void Bubble_Server::DoUpdate()
{
//更新游戏
std::map<USHORT, GameTable>::iterator it_g = m_map_game.begin();
while (it_g!=m_map_game.end())
{
it_g->second.DoUpdate();
it_g++;
}
//首先处理来自玩家的通信包
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:
{
ULONG id_user = ptr_packet->read32();
const char* strText = ptr_packet->readString();
GameUser* ptr_user = get_user(uid);
if (ptr_user)
{
NET_Packet* pPacket = new NET_Packet;
pPacket->setCmd(GSP_SPEEK);
pPacket->write32(uid);
pPacket->writeString(ptr_user->str_name);
pPacket->writeString(strText);
m_socket_player.PushSendPacket(id_user, pPacket);
}
}
break;
case GSP_SPEEK:
{
USHORT id_table = ptr_packet->read16();
const char* strText = ptr_packet->readString();
GameUser* ptr_user = get_user(uid);
if (ptr_user && strText)
{
GameTable* ptr_table = get_table(id_table);
NET_Packet* pPacket = new NET_Packet;
pPacket->setCmd(GSP_SPEEK);
pPacket->write32(uid);
pPacket->writeString(ptr_user->str_name);
pPacket->writeString(strText);
if (ptr_table)
{
ptr_table->BroadcastPacket(pPacket);
}
else
{
BroadcastPacket(pPacket);
}
}
}
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);
}
register_user(m_map_user_info[uid], str_account.c_str());
GameUser* ptr_user = &m_map_user_info[uid];
str_account = ptr_user->str_name;
char str[100];
sprintf(str, "data\\%s.ur", ptr_user->str_name);
FILE* pf = fopen(str, "rb");
if(pf)
{
fread((STRUCT_ADD_USER*)ptr_user, sizeof(STRUCT_ADD_USER), 1, pf);
fclose(pf);
if (ptr_packet->read8())
{
ptr_user->us_type = ptr_packet->read16();
}
}
else
{
ptr_user->n_score = 0;
ptr_user->us_lost = 0;
ptr_user->us_win = 0;
ptr_user->us_table = 0;
ptr_user->uc_chair = 0;
ptr_packet->read8();
ptr_user->us_type = ptr_packet->read16();
}
strcpy(ptr_user->str_name, str_account.c_str());
ptr_user->uid = uid;
NET_Packet* pPacket = new NET_Packet;
pPacket->setCmd(GSP_ADD_USER);
pPacket->writeData((STRUCT_ADD_USER*)ptr_user, sizeof(STRUCT_ADD_USER));
m_socket_player.PushSendPacket(uid, pPacket);
std::map<ULONG, GameUser>::iterator it = m_map_user_info.begin();
while(it!=m_map_user_info.end())
{
if(it->second.uid!=uid)
{
pPacket = new NET_Packet;
pPacket->setCmd(GSP_ADD_USER);
pPacket->writeData((STRUCT_ADD_USER*)ptr_user, sizeof(STRUCT_ADD_USER));
m_socket_player.PushSendPacket(it->second.uid, pPacket);
pPacket = new NET_Packet;
pPacket->setCmd(GSP_ADD_USER);
pPacket->writeData((STRUCT_ADD_USER*)(&(it->second)), sizeof(STRUCT_ADD_USER));
m_socket_player.PushSendPacket(uid, pPacket);
}
it++;
}
std::map<USHORT, GameTable>::iterator it_table = m_map_game.begin();
while(it_table!=m_map_game.end())
{//发送所有桌子信息
pPacket = it_table->second.CreateTableInfoPacket();
m_socket_player.PushSendPacket(uid, pPacket);
it_table++;
}
//m_map_game[m_map_user_info[uid].us_table].UserEnter(&m_map_user_info[uid], -1);
}
break;
case GSP_LOGOUT:
{
STRUCT_DEL_USER sdu;
sdu.uid = ptr_packet->read32();
GameUser* pUser = get_user(sdu.uid);
on_user_leave_table(&m_map_game[pUser->us_table], pUser);
std::map<ULONG, GameUser>::iterator it = m_map_user_info.find(uid);
if(it==m_map_user_info.end())
break;
save_user_info(&it->second);
m_map_user_info.erase(it);
//通知游戏世界服务器
it = m_map_user_info.begin();
while(it!=m_map_user_info.end())
{
NET_Packet* pPacket = new NET_Packet;
pPacket->setCmd(GSP_DEL_USER);
pPacket->write32(sdu.uid);
pPacket->writeData(&sdu, sizeof(STRUCT_DEL_USER));
m_socket_player.PushSendPacket(it->second.uid, pPacket);
it++;
}
}
break;
case GSP_ENTER_TABLE:
{
//ULONG id_user = pPacket->read32();
USHORT us_table = ptr_packet->read16();
if (us_table==0)
break;
USHORT us_chair = ptr_packet->read16();
GameUser* ptr_user = get_user(uid);
if (ptr_user)
{
if (ptr_user->us_table>0)
{
if (ptr_user->us_table==us_table)
break;
on_user_leave_table(&m_map_game[ptr_user->us_table], ptr_user);
}
m_map_game[us_table].uid = us_table;
m_map_game[us_table].UserEnter(ptr_user, us_chair);
std::map<ULONG, GameUser>::iterator it = m_map_user_info.begin();
while(it!=m_map_user_info.end())
{//广播该桌子信息
NET_Packet* pPacket = m_map_game[us_table].CreateTableInfoPacket();
if(it->second.us_table!=us_table)
{
m_socket_player.PushSendPacket(it->second.uid, pPacket);
}
it++;
}
}
}
break;
case GSP_LEAVE_TABLE:
{
//ULONG id_user = ptr_packet->read32();
GameUser* ptr_user = get_user(uid);
on_user_leave_table(&m_map_game[ptr_user->us_table], ptr_user);
}
break;
case GSP_SHOOT:
{
ULONG id_user = ptr_packet->read32();
GameUser* pUser = get_user(id_user);
if(pUser)
{
GameTable* pTable = get_table(pUser->us_table);
if(pTable)
{
STRUCT_SHOOT_DATA* pData = (STRUCT_SHOOT_DATA*)ptr_packet->readData();
pTable->on_msg_shoot(pUser, pData);
}
}
}
break;
case GSP_HANDLE_PLAYER:
{
STRUCT_HANDLE_PLAYER* pSHP = (STRUCT_HANDLE_PLAYER*)ptr_packet->readData();
GameUser* pUser = get_user(pSHP->user);
GameUser* pUser_obj = get_user(pSHP->object);
if(pUser && pUser_obj)
{
GameTable* pTable = get_table(pUser->us_table);
if(pTable)
{
pTable->on_msg_handle_player(pUser_obj, pUser);
}
}
}
break;
case GSP_TRIGGER_CARDS:
{
ULONG id_user = ptr_packet->read32();
GameUser* pUser = get_user(id_user);
if(pUser)
{
GameTable* pTable = get_table(pUser->us_table);
if(pTable)
{
BYTE* pData = (BYTE*)ptr_packet->readData();
pTable->on_msg_trigger_cards(pUser, pData);
}
}
}
break;
case GSP_UPDATE_SCENE:
{
ULONG id_user = ptr_packet->read32();
GameUser* pUser = get_user(id_user);
if(pUser)
{
GameTable* pTable = get_table(pUser->us_table);
if(pTable)
{
GamePlayer* pPlayer = pTable->get_player(id_user);
if(pPlayer)
{
NET_Packet* pPacket = pPlayer->CreateScenePacket();
m_socket_player.PushSendPacket(uid, pPacket);
}
}
}
}
break;
case GSP_UI_CMD:
{
ULONG id_user = ptr_packet->read32();
USHORT ui_cmd = ptr_packet->read16();
GameUser* pUser = get_user(id_user);
if(pUser)
{
GameTable* pTable = get_table(pUser->us_table);
if(pTable)
{
switch(ui_cmd)
{
case _UI_CMD_READY:
{
if(!pTable->on_ui_cmd_ready(pUser))
{
goto exit_msg_process;
}
}
break;
case _UI_CMD_START:
{
if(!pTable->Start())
{
goto exit_msg_process;
}
}
break;
default:
break;
}
NET_Packet* pPacket = ptr_packet->clone_packet();
pTable->BroadcastPacket(pPacket, id_user);
}
}
}
break;
default:
break;
}
exit_msg_process:
if(ptr_packet)
delete(ptr_packet);
ptr_packet = m_socket_player.PopRecvPacket();
}
}
bool Bubble_Server::IsActive()
{
return m_socket_player.is_active();
}
int Bubble_Server::get_thread_count()
{
return m_thread_pool.get_Thread_count();
}
int Bubble_Server::get_online_count()
{
return m_socket_player.GetSessionCount();
}
bool Bubble_Server::StartServer()
{
// if(m_str_path.empty()||m_str_ver.empty())
// {
// Sys_Log("服务器错误", "服务器没有初始化服务内容!");
// return false;
// }
CFG cfg;
cfg.open("Bubble_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);
}
}
srand(Sys_GetTime());
Sys_Log("服务器操作", "游戏管理服务器启动完成!");
return true;
}
void Bubble_Server::StopServer()
{
Shutdown();
Sys_Log("服务器操作", "服务器已经关闭!");
}
GameUser* Bubble_Server::get_user(ULONG id_user)
{
std::map<uint32, GameUser>::iterator it = m_map_user_info.find(id_user);
if(it!=m_map_user_info.end())
{
return &it->second;
}
return NULL;
}
GameUser* Bubble_Server::find_user(const char *strName)
{
std::map<ULONG, GameUser>::iterator it = m_map_user_info.begin();
while (it!=m_map_user_info.end())
{
if (0==strcmp(strName, it->second.str_name))
{
return &it->second;
}
it++;
}
return NULL;
}
void Bubble_Server::on_user_enter_table(ULONG id_user, USHORT id_table)
{
//test
}
GameTable* Bubble_Server::get_table(USHORT id_table)
{
std::map<USHORT, GameTable>::iterator it = m_map_game.find(id_table);
if(it!=m_map_game.end())
{
return &it->second;
}
return NULL;
}
void Bubble_Server::BroadcastPacket(NET_Packet *pPacket, ULONG id_except)
{
if(pPacket==NULL)
return;
std::map<ULONG, GameUser>::iterator it = m_map_user_info.begin();
if(it==m_map_user_info.end())
{
delete(pPacket);
return;
}
ULONG uid = it->second.uid;
it++;
if(uid==id_except)
{//skip except
if(it==m_map_user_info.end())
{
delete(pPacket);
return;
}
}
while( it !=m_map_user_info.end())
{
NET_Packet* ptr_packet = pPacket->clone_packet();
m_socket_player.PushSendPacket(uid, ptr_packet);
uid = it->second.uid;
it++;
if(uid==id_except)
{//skip except
if(it==m_map_user_info.end())
{
delete(pPacket);
return;
}
uid = it->second.uid;
it++;
}
}
m_socket_player.PushSendPacket(uid, pPacket);
}
void Bubble_Server::on_user_leave_table(GameTable *pTable, GameUser *pUser)
{
if (pTable==NULL || pUser==NULL)
return;
pTable->UserLeave(pUser);
std::map<ULONG, GameUser>::iterator it = m_map_user_info.begin();
while(it!=m_map_user_info.end())
{//广播该桌子信息
NET_Packet* pPacket = pTable->CreateTableInfoPacket();
if(it->second.us_table!=pTable->uid)
{
m_socket_player.PushSendPacket(it->second.uid, pPacket);
}
it++;
}
}
void Bubble_Server::on_update_table_info(GameTable *pTable)
{
std::map<ULONG, GameUser>::iterator it = m_map_user_info.begin();
while(it!=m_map_user_info.end())
{//广播该桌子信息
NET_Packet* pPacket = pTable->CreateTableInfoPacket();
if(it->second.us_table!=pTable->uid)
{
m_socket_player.PushSendPacket(it->second.uid, pPacket);
}
it++;
}
}
bool Bubble_Server::register_user(GameUser &user, const char* strName)
{
GameUser* ptr_user;
char str[100];
strcpy(str, strName);
int i=1;
while (ptr_user = find_user(str))
{
sprintf(str, "%s_%d", strName, i);
i++;
}
strcpy(user.str_name, str);
return true;
}
bool Bubble_Server::save_user_info(GameUser *ptr_user)
{
if (!ptr_user)
return false;
char str[100];
sprintf(str, "data\\%s.ur", ptr_user->str_name);
FILE* pf = fopen(str, "wb");
if(pf)
{
fwrite((STRUCT_ADD_USER*)ptr_user, sizeof(STRUCT_ADD_USER), 1, pf);
fclose(pf);
return true;
}
return false;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -