diff --git a/server/imserver/WSListener.cc b/server/imserver/WSListener.cc index 28270fa..9759110 100644 --- a/server/imserver/WSListener.cc +++ b/server/imserver/WSListener.cc @@ -60,7 +60,7 @@ public: virtual void OnDisConnect() override { - App::Instance()->AddIMMsg(IM_WSProxySocketDisconnect, + App::Instance()->AddIMMsg(IM_WSProxyDisconnect, a8::XParams() .SetSender(socket_handle) .SetParam1(1)); diff --git a/server/imserver/app.cc b/server/imserver/app.cc index 912550f..da19e78 100644 --- a/server/imserver/app.cc +++ b/server/imserver/app.cc @@ -206,6 +206,7 @@ int App::Run() a8::UdpLog::Instance()->Info("friend_imserver running", {}); while (!terminated) { a8::tick_t begin_tick = a8::XGetTickCount(); + nowtime = time(nullptr); QuickExecute(); SlowerExecute(); a8::tick_t end_tick = a8::XGetTickCount(); @@ -491,12 +492,9 @@ void App::ProcessIMMsg() while (im_work_node_) { IMMsgNode *pdelnode = im_work_node_; switch (im_work_node_->msgid) { - case IM_WSProxySocketDisconnect: + case IM_WSProxyDisconnect: { - #if 0 - GameClientMgr::Instance()->OnClientDisconnect(pdelnode->params); - MasterSvrMgr::Instance()->RemoveRequest(pdelnode->params.param1, pdelnode->params.sender, true); - #endif + PlayerMgr::Instance()->OnWSProxyDisconnect(pdelnode->params); } break; #if 0 diff --git a/server/imserver/app.h b/server/imserver/app.h index f38d789..131bedd 100644 --- a/server/imserver/app.h +++ b/server/imserver/app.h @@ -65,6 +65,7 @@ private: public: int instance_id = 0; + int nowtime = 0; private: std::mutex *loop_mutex_ = nullptr; diff --git a/server/imserver/constant.h b/server/imserver/constant.h index 18afbee..a2b8b25 100644 --- a/server/imserver/constant.h +++ b/server/imserver/constant.h @@ -10,7 +10,7 @@ enum SocketFrom_e enum InnerMesssage_e { - IM_WSProxySocketDisconnect = 100, + IM_WSProxyDisconnect = 100, IM_PlayerOffline, IM_ExecGM, IM_MasterSvrDisconnect, diff --git a/server/imserver/dbengine.cc b/server/imserver/dbengine.cc index dd523af..0693138 100644 --- a/server/imserver/dbengine.cc +++ b/server/imserver/dbengine.cc @@ -1,5 +1,7 @@ #include "precompile.h" +#include + #include "dbengine.h" void DBEngine::Init() @@ -51,7 +53,12 @@ void DBEngine::ExecAsyncScript(a8::XObject conn_info, ); } -a8::XObject DBEngine::GetConnInfoByHash(long long hash_code) +a8::XObject DBEngine::GetConnInfo(const std::string& data) +{ + return GetConnInfo(a8::openssl::Crc32((unsigned char*)data.data(), data.size())); +} + +a8::XObject DBEngine::GetConnInfo(long long data) { a8::XObject conn_info; return conn_info; diff --git a/server/imserver/dbengine.h b/server/imserver/dbengine.h index 001b06d..e059951 100644 --- a/server/imserver/dbengine.h +++ b/server/imserver/dbengine.h @@ -29,5 +29,6 @@ class DBEngine : public a8::Singleton f8::AsyncDBOnErrorFunc on_error, long long hash_code = 0); - a8::XObject GetConnInfoByHash(long long hash_code); + a8::XObject GetConnInfo(const std::string& data); + a8::XObject GetConnInfo(long long data); }; diff --git a/server/imserver/player.cc b/server/imserver/player.cc index b43f721..9ed60ba 100644 --- a/server/imserver/player.cc +++ b/server/imserver/player.cc @@ -1,10 +1,12 @@ #include "precompile.h" #include "player.h" +#include "playermgr.h" +#include "WSListener.h" void Player::Init() { - + SyncLocToMasterServer(); } void Player::UnInit() @@ -66,3 +68,16 @@ void Player::_CMGroupRename(f8::MsgHdr& hdr, const cs::CMGroupRename& msg) { } + +void Player::ReLogin(f8::MsgHdr& hdr, const cs::CMLogin& msg) +{ + cs::SMLogin respmsg; + WSListener::Instance()->SendToClient(hdr.socket_handle, 0, respmsg); + PlayerMgr::Instance()->ReBindSocket(hdr.socket_handle, this); + SyncLocToMasterServer(); +} + +void Player::SyncLocToMasterServer() +{ + +} diff --git a/server/imserver/player.h b/server/imserver/player.h index 4262d4e..fcf360d 100644 --- a/server/imserver/player.h +++ b/server/imserver/player.h @@ -9,6 +9,11 @@ class Player public: int socket_handle = 0; + std::string account_id; + std::string nickname; + std::string avatar_url; + int sex = 0; + long long group_id = 0; public: void Init(); @@ -26,4 +31,7 @@ class Player void _CMGroupQuit(f8::MsgHdr& hdr, const cs::CMGroupQuit& msg); void _CMGroupDismiss(f8::MsgHdr& hdr, const cs::CMGroupDismiss& msg); void _CMGroupRename(f8::MsgHdr& hdr, const cs::CMGroupRename& msg); + + void ReLogin(f8::MsgHdr& hdr, const cs::CMLogin& msg); + void SyncLocToMasterServer(); }; diff --git a/server/imserver/playermgr.cc b/server/imserver/playermgr.cc index f776964..d1a78ff 100644 --- a/server/imserver/playermgr.cc +++ b/server/imserver/playermgr.cc @@ -1,9 +1,13 @@ #include "precompile.h" +#include + #include "playermgr.h" #include "player.h" #include "cs_proto.pb.h" #include "dbengine.h" +#include "WSListener.h" +#include "app.h" #include "framework/cpp/utils.h" @@ -17,10 +21,7 @@ void PlayerMgr::UnInit() void PlayerMgr::_SS_WSP_SocketDisconnect(f8::MsgHdr& hdr, const ss::SS_WSP_SocketDisconnect& msg) { - Player* hum = GetPlayerBySocket(hdr.socket_handle); - if (hum) { - RemovePlayerBySocket(hdr.socket_handle); - } + OnClientSocketDisconnect(hdr.socket_handle); } void PlayerMgr::_SS_MS_PushUserList(f8::MsgHdr& hdr, const ss::SS_MS_PushUserList& msg) @@ -37,9 +38,20 @@ void PlayerMgr::_CMLogin(f8::MsgHdr& hdr, const cs::CMLogin& msg) { Player* hum = GetPlayerByAccountId(msg.account_id()); if (hum) { + hum->ReLogin(hdr, msg); return; } - + if (GetHdrBySocket(hdr.socket_handle) || + GetHdrByAccountId(msg.account_id())) { + cs::SMLogin respmsg; + respmsg.set_error_code(1); + WSListener::Instance()->SendToClient(hdr.socket_handle, 0, respmsg); + return; + } + f8::MsgHdr* new_hdr = hdr.Clone(); + pending_socket_hash_[hdr.socket_handle] = new_hdr; + pending_account_hash_[msg.account_id()] = new_hdr; + AsyncLogin1(msg); } int PlayerMgr::OnlineNum() @@ -59,6 +71,29 @@ Player* PlayerMgr::GetPlayerByAccountId(const std::string& account_id) return itr != accountid_hash_.end() ? itr->second : nullptr; } +void PlayerMgr::ReBindSocket(int socket_handle, Player* hum) +{ + socket_hash_.erase(hum->socket_handle); + socket_hash_[socket_handle] = hum; + hum->socket_handle = socket_handle; +} + +void PlayerMgr::OnWSProxyDisconnect(a8::XParams& param) +{ + int ws_socket = param.sender; + + std::vector socket_list; + for (auto& pair : socket_hash_) { + unsigned short parent_socket_handle = (pair.first >> 16) & 0xFFFF; + if (parent_socket_handle == ws_socket) { + socket_list.push_back(pair.first); + } + } + for (int socket_handle : socket_list) { + OnClientSocketDisconnect(socket_handle); + } +} + void PlayerMgr::OnClientDisconnect(a8::XParams& param) { int gg_socket = param.sender; @@ -86,3 +121,191 @@ void PlayerMgr::RemovePlayerBySocket(int socket_handle) socket_hash_.erase(itr); } } + +f8::MsgHdr* PlayerMgr::GetHdrBySocket(int socket_handle) +{ + auto itr = pending_socket_hash_.find(socket_handle); + return itr != pending_socket_hash_.end() ? itr->second : nullptr; +} + +f8::MsgHdr* PlayerMgr::GetHdrByAccountId(const std::string& account_id) +{ + auto itr = pending_account_hash_.find(account_id); + return itr != pending_account_hash_.end() ? itr->second : nullptr; +} + +void PlayerMgr::AsyncLogin1(const cs::CMLogin& msg) +{ + auto on_ok = + [] (a8::XParams& param, const f8::DataSet* data_set) + { + cs::CMLogin* msg = (cs::CMLogin*)param.sender.GetUserData(); + PlayerMgr::Instance()->AsyncLogin2(*msg); + delete msg; + }; + auto on_error = + [] (a8::XParams& param, int error_code, const std::string& error_msg) + { + cs::CMLogin* msg = (cs::CMLogin*)param.sender.GetUserData(); + PlayerMgr::Instance()->AsyncLoginOnError( + msg->account_id(), + 1, + 1, + "" + ); + delete msg; + }; + cs::CMLogin* msg_copy = new cs::CMLogin(); + *msg_copy = msg; + a8::XObject conn_info = DBEngine::Instance()->GetConnInfo(msg.account_id()); + DBEngine::Instance()->ExecAsyncScript(conn_info, + "INSERT INTO `user`(account_id, nickname, avatar_url," + " sex, group_id, createtime, modifytime, registertime)" + "VALUES ('%s', '%s', '%s', %d, 0, %d, %d, %d)" + "ON DUPLICATE KEY UPDATE nickname='%s', avatar_url='%s'," + " sex=%d, last_logintime=%d;", + { + msg.account_id(), + msg.nickname(), + msg.avatar_url(), + msg.sex(), + App::Instance()->nowtime, + App::Instance()->nowtime, + f8::ExtractRegisterTimeFromSessionId(msg.session_id()), + msg.nickname(), + msg.avatar_url(), + msg.sex(), + App::Instance()->nowtime + }, + a8::XParams() + .SetSender((void*)msg_copy), + on_ok, + on_error, + a8::openssl::Crc32((unsigned char*)msg.account_id().data(), + msg.account_id().size()) + ); +} + +void PlayerMgr::AsyncLogin2(const cs::CMLogin& msg) +{ + auto on_ok = + [] (a8::XParams& param, const f8::DataSet* data_set) + { + cs::CMLogin* msg = (cs::CMLogin*)param.sender.GetUserData(); + if (data_set->empty()) { + PlayerMgr::Instance()->AsyncLoginOnError( + msg->account_id(), + 2, + 1, + "" + ); + } else { + PlayerMgr::Instance()->AsyncLoginOnOk( + data_set->at(0).at(0), + data_set->at(0).at(1), + data_set->at(0).at(2), + a8::XValue(data_set->at(0).at(3)), + a8::XValue(data_set->at(0).at(4)) + ); + } + delete msg; + }; + auto on_error = + [] (a8::XParams& param, int error_code, const std::string& error_msg) + { + cs::CMLogin* msg = (cs::CMLogin*)param.sender.GetUserData(); + PlayerMgr::Instance()->AsyncLoginOnError( + msg->account_id(), + 2, + 1, + "" + ); + delete msg; + }; + cs::CMLogin* msg_copy = new cs::CMLogin(); + *msg_copy = msg; + a8::XObject conn_info = DBEngine::Instance()->GetConnInfo(msg.account_id()); + DBEngine::Instance()->ExecAsyncQuery(conn_info, + "SELECT account_id, nickname, avatar_url, sex, group_id " + "FROM `user` WHERE account_id='%s';", + { + msg.account_id(), + }, + a8::XParams() + .SetSender((void*)msg_copy), + on_ok, + on_error, + a8::openssl::Crc32((unsigned char*)msg.account_id().data(), + msg.account_id().size()) + ); +} + +void PlayerMgr::AsyncLoginOnOk(const std::string& account_id, + const std::string& nickname, + const std::string& avatar_url, + int sex, + long long group_id) +{ + f8::MsgHdr* hdr = GetHdrByAccountId(account_id); + if (hdr) { + Player* hum = GetPlayerByAccountId(account_id); + if (hum) { + abort(); + } + hum = GetPlayerBySocket(hdr->socket_handle); + if (hum) { + abort(); + } + { + hum = new Player(); + hum->socket_handle = hdr->socket_handle; + hum->account_id = account_id; + hum->nickname = nickname; + hum->avatar_url = avatar_url; + hum->sex = sex; + hum->group_id = group_id; + hum->Init(); + socket_hash_[hdr->socket_handle] = hum; + accountid_hash_[account_id] = hum; + } + pending_socket_hash_.erase(hdr->socket_handle); + pending_account_hash_.erase(account_id); + if (hdr->buf) { + free((void*)hdr->buf); + } + free((void*)hdr); + } +} + +void PlayerMgr::AsyncLoginOnError(const std::string& account_id, int step, + int error_code, const std::string& error_msg) +{ + f8::MsgHdr* hdr = GetHdrByAccountId(account_id); + if (hdr) { + pending_socket_hash_.erase(hdr->socket_handle); + pending_account_hash_.erase(account_id); + if (hdr->buf) { + free((void*)hdr->buf); + } + free((void*)hdr); + } +} + +void PlayerMgr::OnClientSocketDisconnect(int socket_handle) +{ + { + f8::MsgHdr* hdr = GetHdrBySocket(socket_handle); + if (hdr) { + if (hdr->buf) { + free((void*)hdr->buf); + } + free((void*)hdr); + } + } + { + Player* hum = GetPlayerBySocket(socket_handle); + if (hum) { + + } + } +} diff --git a/server/imserver/playermgr.h b/server/imserver/playermgr.h index 5ccb8f2..4fe5132 100644 --- a/server/imserver/playermgr.h +++ b/server/imserver/playermgr.h @@ -34,13 +34,32 @@ class PlayerMgr : public a8::Singleton Player* GetPlayerBySocket(int socket); Player* GetPlayerByAccountId(const std::string& account_id); + void ReBindSocket(int socket_handle, Player* hum); + void OnWSProxyDisconnect(a8::XParams& param); private: int OnlineNum(); void OnClientDisconnect(a8::XParams& param); void RemovePlayerBySocket(int socket_handle); + f8::MsgHdr* GetHdrBySocket(int socket_handle); + f8::MsgHdr* GetHdrByAccountId(const std::string& account_id); + void AsyncLogin1(const cs::CMLogin& msg); + void AsyncLogin2(const cs::CMLogin& msg); + void AsyncLoginOnOk(const std::string& account_id, + const std::string& nickname, + const std::string& avatar_url, + int sex, + long long group_id); + void AsyncLoginOnError(const std::string& account_id, + int step, + int error_code, + const std::string& error_msg); + void OnClientSocketDisconnect(int socket_handle); private: std::map socket_hash_; std::map accountid_hash_; + + std::map pending_socket_hash_; + std::map pending_account_hash_; }; diff --git a/server/tools/protobuild/cs_proto.proto b/server/tools/protobuild/cs_proto.proto index 3964883..82067af 100644 --- a/server/tools/protobuild/cs_proto.proto +++ b/server/tools/protobuild/cs_proto.proto @@ -35,6 +35,8 @@ message CMLogin } message SMLogin { + optional int32 error_code = 1; + optional string error_msg = 2; } message CMFriendList diff --git a/sql/relationdb_n.sql b/sql/relationdb_n.sql index abd7171..bbe466b 100644 --- a/sql/relationdb_n.sql +++ b/sql/relationdb_n.sql @@ -46,6 +46,7 @@ CREATE TABLE `user` ( `createtime` int(11) NOT NULL DEFAULT '0' COMMENT '创建时间', `modifytime` int(11) NOT NULL DEFAULT '0' COMMENT '修改时间', `registertime` int(11) NOT NULL DEFAULT '0' COMMENT '创建时间', + `last_logintime` int(11) NOT NULL DEFAULT '0' COMMENT '创建时间', PRIMARY KEY (`idx`), UNIQUE KEY `account_id` (`account_id`), KEY `nickname` (`nickname`),