diff --git a/server/gameserver/handlermgr.cc b/server/gameserver/handlermgr.cc index dcf4192..d8c794f 100644 --- a/server/gameserver/handlermgr.cc +++ b/server/gameserver/handlermgr.cc @@ -84,6 +84,7 @@ void HandlerMgr::RegisterNetMsgHandlers() RegisterNetMsgHandler(&ggmsghandler, &PlayerMgr::_SS_WSP_SocketDisconnect); RegisterNetMsgHandler(&ggmsghandler, &PlayerMgr::_SS_Ping); RegisterNetMsgHandler(&ggmsghandler, &RoomMgr::_CMJoin); + RegisterNetMsgHandler(&ggmsghandler, &RoomMgr::_CMReconnect); RegisterNetMsgHandler(&ggmsghandler, &Player::_CMMove); RegisterNetMsgHandler(&ggmsghandler, &Player::_CMEmote); diff --git a/server/gameserver/jsondatamgr.cc b/server/gameserver/jsondatamgr.cc index 2cc6dba..ff19a58 100644 --- a/server/gameserver/jsondatamgr.cc +++ b/server/gameserver/jsondatamgr.cc @@ -34,6 +34,7 @@ void JsonDataMgr::Init() gameserver_cluster_json_.ReadFromFile(gameserver_cluster_json_file); ip = GetConf()->At("ip")->AsXValue().GetString(); listen_port = GetConf()->At("listen_port")->AsXValue(); + server_info = a8::Format("%s:%d", {ip, listen_port}); Reload(); } diff --git a/server/gameserver/jsondatamgr.h b/server/gameserver/jsondatamgr.h index c430855..dd59b1e 100644 --- a/server/gameserver/jsondatamgr.h +++ b/server/gameserver/jsondatamgr.h @@ -15,6 +15,7 @@ public: std::string ip; int listen_port = 0; + std::string server_info; void Reload(); diff --git a/server/gameserver/player.cc b/server/gameserver/player.cc index 4aa742b..6f9a327 100644 --- a/server/gameserver/player.cc +++ b/server/gameserver/player.cc @@ -912,6 +912,26 @@ void Player::_CMMove(f8::MsgHdr& hdr, const cs::CMMove& msg) } } +void Player::_CMReconnect(f8::MsgHdr& hdr, const cs::CMReconnect& msg) +{ + socket_handle = hdr.socket_handle; + #if 0 + TouchAllLayerHumanList + ( + [this] (Human* hum, bool& stop) + { + AddToNewObjects(hum); + } + ); + #endif + need_sync_active_player = true; + cs::SMReconnect respmsg; + respmsg.set_errcode(0); + respmsg.set_errmsg("战斗重连成功"); + SendNotifyMsg(respmsg); + PlayerMgr::Instance()->ReBindSocket(this); +} + void Player::UpdateDropWeapon() { if (drop_weapon_idx >= 0 && drop_weapon_idx < weapons.size()) { diff --git a/server/gameserver/player.h b/server/gameserver/player.h index 2fc409c..4b64c96 100644 --- a/server/gameserver/player.h +++ b/server/gameserver/player.h @@ -5,8 +5,9 @@ namespace cs { class CMMove; + class CMReconnect; class CMDropItem; - class CMEmote; + class CMmEmote; class CMVoice; class MFActivePlayerData; class MFGasData; @@ -83,6 +84,7 @@ class Player : public Human void ProcPrepareItems(const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >& prepare_items); void _CMMove(f8::MsgHdr& hdr, const cs::CMMove& msg); + void _CMReconnect(f8::MsgHdr& hdr, const cs::CMReconnect& msg); void _CMEmote(f8::MsgHdr& hdr, const cs::CMEmote& msg); void _CMVoice(f8::MsgHdr& hdr, const cs::CMVoice& msg); void _CMGameOver(f8::MsgHdr& hdr, const cs::CMGameOver& msg); diff --git a/server/gameserver/playermgr.cc b/server/gameserver/playermgr.cc index 985be4f..31862ad 100644 --- a/server/gameserver/playermgr.cc +++ b/server/gameserver/playermgr.cc @@ -113,3 +113,8 @@ void PlayerMgr::RemovePlayerBySocket(int socket_handle) socket_hash_.erase(itr); } } + +void PlayerMgr::ReBindSocket(Player* hum) +{ + socket_hash_[hum->socket_handle] = hum; +} diff --git a/server/gameserver/playermgr.h b/server/gameserver/playermgr.h index 6e5cd80..e45b551 100644 --- a/server/gameserver/playermgr.h +++ b/server/gameserver/playermgr.h @@ -33,6 +33,7 @@ class PlayerMgr : public a8::Singleton Player* CreatePlayerByCMJoin(long ip_saddr, int socket, const cs::CMJoin& msg); void OnClientDisconnect(a8::XParams& param); void RemovePlayerBySocket(int socket_handle); + void ReBindSocket(Player* hum); private: std::map socket_hash_; diff --git a/server/gameserver/room.cc b/server/gameserver/room.cc index fbcbf64..f887042 100644 --- a/server/gameserver/room.cc +++ b/server/gameserver/room.cc @@ -746,14 +746,19 @@ bool Room::CanJoin(const std::string& accountid) void Room::OnPlayerOffline(Player* hum) { - bool has_player = false; - for (auto& pair : accountid_hash_) { - if (pair.second->socket_handle != 0) { - has_player = true; - } - } - if (!has_player) { - RoomMgr::Instance()->AddOverRoom(room_uuid); + if (GetOnlinePlayerNum() <= 0) { + xtimer.AddDeadLineTimer + ( + SERVER_FRAME_RATE * 40, + a8::XParams() + .SetSender(this), + [] (const a8::XParams& param) + { + Room* room = (Room*)param.sender.GetUserData(); + if (room->GetOnlinePlayerNum() <= 0) { + RoomMgr::Instance()->AddOverRoom(room->room_uuid); + } + }); } } @@ -1544,3 +1549,14 @@ void Room::CreateMapSpawnPoint(MetaData::MapTplThing& thing_tpl) born_point.thing_tpl = &thing_tpl; born_point_hash_[AllocUniid()] = born_point; } + +int Room::GetOnlinePlayerNum() +{ + int num = 0; + for (auto& pair : accountid_hash_) { + if (pair.second->socket_handle != 0) { + ++num; + } + } + return num; +} diff --git a/server/gameserver/room.h b/server/gameserver/room.h index ae3390d..9030048 100644 --- a/server/gameserver/room.h +++ b/server/gameserver/room.h @@ -99,6 +99,7 @@ public: void UpdateCarObject(int old_uniid, int new_uniid, a8::Vec2 pos); void TakeOnCarObject(int car_uniid); void TakeOffCarObject(int car_uniid, a8::Vec2 pos); + int GetOnlinePlayerNum(); private: int AllocUniid(); diff --git a/server/gameserver/roommgr.cc b/server/gameserver/roommgr.cc index 51b8bb7..6d4deb0 100644 --- a/server/gameserver/roommgr.cc +++ b/server/gameserver/roommgr.cc @@ -99,6 +99,7 @@ void RoomMgr::_CMJoin(f8::MsgHdr& hdr, const cs::CMJoin& msg) { cs::SMJoinedNotify notifymsg; notifymsg.set_error_code(0); + notifymsg.set_server_info(JsonDataMgr::Instance()->server_info); room->FillSMJoinedNotify(hum, notifymsg); GGListener::Instance()->SendToClient(hdr.socket_handle, hdr.seqid, notifymsg); } @@ -111,6 +112,40 @@ void RoomMgr::_CMJoin(f8::MsgHdr& hdr, const cs::CMJoin& msg) } } +void RoomMgr::_CMReconnect(f8::MsgHdr& hdr, const cs::CMReconnect& msg) +{ + auto send_reconnect_failed = + [] (int socket_handle, int errcode, const std::string& errmsg) + { + cs::SMReconnect respmsg; + respmsg.set_errcode(errcode); + respmsg.set_errmsg(errmsg); + GGListener::Instance()->SendToClient(socket_handle, 0, respmsg); + a8::Timer::Instance()->AddDeadLineTimer + ( + 1000 * 3, + a8::XParams() + .SetSender(socket_handle), + [] (const a8::XParams& param) + { + GGListener::Instance()->ForceCloseClient(param.sender); + } + ); + }; + + Room* room = GetRoomByUuid(a8::XValue(msg.room_uuid())); + if (!room) { + send_reconnect_failed(hdr.socket_handle, 1, "房间已销毁"); + return; + } + Player* hum = room->GetPlayerByAccountId(msg.account_id()); + if (!hum) { + send_reconnect_failed(hdr.socket_handle, 1, "accountid未在房间列表"); + return; + } + hum->_CMReconnect(hdr, msg); +} + int RoomMgr::RoomNum() { return room_hash_.size(); diff --git a/server/gameserver/roommgr.h b/server/gameserver/roommgr.h index 426e6ac..031a969 100644 --- a/server/gameserver/roommgr.h +++ b/server/gameserver/roommgr.h @@ -5,6 +5,7 @@ namespace cs { class CMJoin; + class CMReconnect; } class Room; @@ -23,6 +24,7 @@ class RoomMgr : public a8::Singleton void Update(int delta_time); void _CMJoin(f8::MsgHdr& hdr, const cs::CMJoin& msg); + void _CMReconnect(f8::MsgHdr& hdr, const cs::CMReconnect& msg); void ActiveRoom(long long room_uuid); int RoomNum(); int OverRoomNum(); diff --git a/server/tools/protobuild/cs_msgid.proto b/server/tools/protobuild/cs_msgid.proto index 7421f83..89b8938 100644 --- a/server/tools/protobuild/cs_msgid.proto +++ b/server/tools/protobuild/cs_msgid.proto @@ -6,6 +6,7 @@ enum CMMessageId_e _CMPing = 101; _CMJoin = 103; + _CMReconnect = 104; _CMMove = 201; _CMEmote = 204; _CMVoice = 206; @@ -25,6 +26,7 @@ enum SMMessageId_e _SMLeave = 209; _SMJoinedNotify = 103; + _SMReconnect = 104; _SMMapInfo = 1002; _SMPlayerInfo = 1003; _SMUpdate = 1004; diff --git a/server/tools/protobuild/cs_proto.proto b/server/tools/protobuild/cs_proto.proto index ac99fb7..fe63cee 100755 --- a/server/tools/protobuild/cs_proto.proto +++ b/server/tools/protobuild/cs_proto.proto @@ -659,6 +659,24 @@ message CMJoin optional int32 today_enter_times = 28; //今天进入游戏的次数 } +//断线重连 +message CMReconnect +{ + optional int32 server_id = 1; //保留 + optional string team_uuid = 2; //保留 + optional string account_id = 3; //账号id + optional string session_id = 4; //session_id + optional string room_uuid = 5; //房间唯一id + optional string server_info = 6; //服务器信息 +} + +//断线重连回复 +message SMReconnect +{ + optional int32 errcode = 1; //错误码 0:成功 1:重连失败 + optional string errmsg = 2; //错误描述 +} + //移动 message CMMove { @@ -763,6 +781,7 @@ message SMJoinedNotify optional bool elo_start = 6; //目前没用到 optional int32 error_code = 7; //错误 1:服务器维护中 2:服务器繁忙请稍后再进入 + optional string server_info = 8; //服务器信息 } //地图信息