diff --git a/server/masterserver/app.cc b/server/masterserver/app.cc index 452a169..e805585 100755 --- a/server/masterserver/app.cc +++ b/server/masterserver/app.cc @@ -383,6 +383,11 @@ void App::ProcessIMMsg() #endif } break; + case IM_IMSSocketDisconnect: + { + SvrMgr::Instance()->OnIMServerDisconnect(pdelnode->params); + } + break; case IM_ExecGM: { HandlerMgr::Instance()->ProcGMMsg(pdelnode->params.param3, diff --git a/server/masterserver/cachemgr.cc b/server/masterserver/cachemgr.cc index 691670e..d2adc2e 100644 --- a/server/masterserver/cachemgr.cc +++ b/server/masterserver/cachemgr.cc @@ -31,3 +31,9 @@ void CacheMgr::_SS_IM_IMServerList(f8::MsgHdr& hdr, const ss::SS_IM_IMServerList { } + +Friend* CacheMgr::GetFriendData(const std::string& account_id) +{ + auto itr = friend_hash_.find(account_id); + return itr != friend_hash_.end() ? itr->second : nullptr; +} diff --git a/server/masterserver/cachemgr.h b/server/masterserver/cachemgr.h index ac2074d..da5954b 100644 --- a/server/masterserver/cachemgr.h +++ b/server/masterserver/cachemgr.h @@ -21,8 +21,9 @@ class CacheMgr : public a8::Singleton void _SS_IM_PullUserList(f8::MsgHdr& hdr, const ss::SS_IM_PullUserList& msg); void _SS_IM_IMServerList(f8::MsgHdr& hdr, const ss::SS_IM_IMServerList& msg); - private: + Friend* GetFriendData(const std::string& account_id); private: + std::map friend_hash_; }; diff --git a/server/masterserver/svrmgr.cc b/server/masterserver/svrmgr.cc index ff0df1c..175fe89 100644 --- a/server/masterserver/svrmgr.cc +++ b/server/masterserver/svrmgr.cc @@ -8,6 +8,7 @@ #include "app.h" #include "GGListener.h" #include "IMListener.h" +#include "cachemgr.h" void SvrMgr::Init() { @@ -29,7 +30,7 @@ void SvrMgr::_SS_WSP_RequestTargetServer(f8::MsgHdr& hdr, const ss::SS_WSP_Reque { ss::SS_MS_ResponseTargetServer respmsg; respmsg.set_context_id(msg.context_id()); - SvrNode* node = AllocNode(); + SvrNode* node = AllocNode(msg.account_id()); if (node) { respmsg.set_host(node->ip); respmsg.set_port(node->port); @@ -43,10 +44,25 @@ void SvrMgr::_SS_WSP_RequestTargetServer(f8::MsgHdr& hdr, const ss::SS_WSP_Reque void SvrMgr::_SS_IM_ReportServerInfo(f8::MsgHdr& hdr, const ss::SS_IM_ReportServerInfo& msg) { SvrNode* svr = GetNodeBySocket(hdr.socket_handle); - std::string key = msg.ip() + ":" + a8::XValue(msg.port()).GetString(); - - svr = GetNodeByKey(key); if (svr) { + if (svr->instance_id != msg.instance_id() || + svr->ip != msg.ip() || + svr->port != msg.port() + ) { + a8::UdpLog::Instance()->Warning + ( + "serverA %s:%d-%d serverB %s:%d-%d", + { + svr->ip, + svr->port, + svr->instance_id, + msg.ip(), + msg.port(), + msg.instance_id() + }); + IMListener::Instance()->ForceCloseClient(hdr.socket_handle); + return; + } if (svr->online_num != msg.online_num() || svr->servicing != msg.servicing() ) { @@ -55,17 +71,19 @@ void SvrMgr::_SS_IM_ReportServerInfo(f8::MsgHdr& hdr, const ss::SS_IM_ReportServ RearrangeNode(); } svr->last_active_tick = a8::XGetTickCount(); - if (svr->instance_id != msg.instance_id()) { + } else { + std::string key = msg.ip() + ":" + a8::XValue(msg.port()).GetString(); + if (GetNodeByKey(key)) { a8::UdpLog::Instance()->Warning ( - "report server info %s %d %d", + "server %s:%d registered", { - key, - svr->instance_id, - msg.instance_id() + msg.ip(), + msg.port() }); + IMListener::Instance()->ForceCloseClient(hdr.socket_handle); + return; } - } else { svr = new SvrNode; svr->socket_handle = hdr.socket_handle; svr->key = key; @@ -128,8 +146,21 @@ void SvrMgr::___GSList(f8::JsonHttpRequest* request) } } -SvrNode* SvrMgr::AllocNode() +void SvrMgr::OnIMServerDisconnect(a8::XParams& param) { + SvrNode* svr = GetNodeBySocket(param.sender); + if (svr) { + RemoveNode(svr); + RearrangeNode(); + } +} + +SvrNode* SvrMgr::AllocNode(const std::string& account_id) +{ + Friend* friend_data = CacheMgr::Instance()->GetFriendData(account_id); + if (friend_data && friend_data->svr_node) { + return friend_data->svr_node; + } if (node_sorted_list_.empty()) { return nullptr; } @@ -186,17 +217,7 @@ void SvrMgr::ClearTimeOutNode() } } for (SvrNode* node : time_out_nodes) { - { - for (size_t i = 0; i < node_sorted_list_.size(); ++i) { - if (node_sorted_list_[i] == node) { - node_sorted_list_.erase(node_sorted_list_.begin() + i); - break; - } - } - } - node_key_hash_.erase(node->key); - socket_hash_.erase(node->socket_handle); - delete node; + RemoveNode(node); } RearrangeNode(); } @@ -212,3 +233,20 @@ SvrNode* SvrMgr::GetNodeBySocket(int socket_handle) auto itr = socket_hash_.find(socket_handle); return itr != socket_hash_.end() ? itr->second : nullptr; } + +void SvrMgr::RemoveNode(SvrNode* node) +{ + { + for (size_t i = 0; i < node_sorted_list_.size(); ++i) { + if (node_sorted_list_[i] == node) { + node_sorted_list_.erase(node_sorted_list_.begin() + i); + break; + } + } + } + { + node_key_hash_.erase(node->key); + socket_hash_.erase(node->socket_handle); + } + delete node; +} diff --git a/server/masterserver/svrmgr.h b/server/masterserver/svrmgr.h index 0cd685d..c6b2571 100644 --- a/server/masterserver/svrmgr.h +++ b/server/masterserver/svrmgr.h @@ -41,12 +41,15 @@ class SvrMgr : public a8::Singleton void ___GSList(f8::JsonHttpRequest* request); + void OnIMServerDisconnect(a8::XParams& param); + private: - SvrNode* AllocNode(); + SvrNode* AllocNode(const std::string& account_id); void RearrangeNode(); void ClearTimeOutNode(); SvrNode* GetNodeByKey(const std::string& key); SvrNode* GetNodeBySocket(int socket_handle); + void RemoveNode(SvrNode* node); private: