diff --git a/server/gameserver/custom_battle.cc b/server/gameserver/custom_battle.cc index fdb95028..3dce9f4f 100644 --- a/server/gameserver/custom_battle.cc +++ b/server/gameserver/custom_battle.cc @@ -5,6 +5,9 @@ #include "custom_member.h" #include "netdata.h" +#include "mt/Map.h" +#include "mt/Param.h" + void CustomBattle::Init() { ob_team_ = std::make_shared(); @@ -27,9 +30,17 @@ void CustomBattle::ParseResult(a8::XObject& obj) room_uuid_ = obj.Get("room_uuid").GetString(); zone_id_ = obj.Get("zone_id"); node_id_ = obj.Get("node_id"); + map_id_ = obj.Get("map_id"); start_time_ = obj.Get("start_time"); sign_ = obj.Get("sign").GetString(); - + const mt::Map* map_meta = mt::Map::GetById(map_id_); + if (!map_meta || !map_meta->IsOpen()) { + parse_ok_ = false; + return; + } + { + is_moba_ = map_meta->is_moba() ? true : false; + } { auto team_list = obj.At("team_list"); if (!team_list || !team_list->IsArray()) { @@ -56,6 +67,7 @@ void CustomBattle::ParseResult(a8::XObject& obj) team->team_uuid_ = team_uuid; team->is_view_ = false; uuid_hash_[team->team_uuid_] = team; + team_list_.push_back(team); } for (int ii = 0; ii < member_list->Size(); ++ii) { auto member_obj = member_list->At(ii); @@ -133,21 +145,10 @@ void CustomBattle::ParseResult(a8::XObject& obj) raw_data_ = std::make_shared(); obj.DeepCopy(*raw_data_); + CalcTeam1AverageHeroLv(); parse_ok_ = true; } -bool CustomBattle::CanAdd(const std::string& account_id, const std::string& session_id) -{ - auto member = GetMemberByAccountId(account_id); - if (!member) { - return false; - } - if (member->IsJoined()) { - return false; - } - return true; -} - std::shared_ptr CustomBattle::GetMemberByAccountId(const std::string& account_id) { auto itr = member_id_hash_.find(account_id); @@ -220,3 +221,55 @@ void CustomBattle::TraverseObList(std::functionGetAverageHeroLv(); + } +} + +RoomType_e CustomBattle::GetRoomType() +{ + if (IsMoba()) { + return RoomType_MidBrid; + } + if (IsCustomMode()) { + return RoomType_MidBrid; + } + if (GetRoomMode() == kPvpRankMode) { + auto rank_mode_conf = mt::Param::GetRankModeConfByHeroLv(team1_average_hero_lv_); + if (!rank_mode_conf) { + abort(); + } + return rank_mode_conf->room_type; + } else { + if (team1_average_hero_lv_ < mt::Param::s().new_room_max_level) { + return RoomType_OldBrid1; + } + if (team1_average_hero_lv_ < mt::Param::s().mid_room_max_level) { + return RoomType_OldBrid2; + } + return RoomType_OldBrid3; + } +} + +std::shared_ptr CustomBattle::GetTeamByIdx(int idx) +{ + if (GetTeamNum() <= 0) { + return nullptr; + } + if (idx < 0 || idx >= GetTeamNum()) { + return nullptr; + } + return team_list_.at(idx); +} diff --git a/server/gameserver/custom_battle.h b/server/gameserver/custom_battle.h index 1679e80e..fca744fb 100644 --- a/server/gameserver/custom_battle.h +++ b/server/gameserver/custom_battle.h @@ -1,8 +1,7 @@ #pragma once -const int CUSTOM_ROOM_PVP = 0; -const int CUSTOM_ROOM_MOBA = 1; -const int CUSTOM_ROOM_NORMAL = 2; +const int CUSTOM_ROOM_CUSTOM = 0; +const int CUSTOM_ROOM_NORMAL = 1; class Room; class CustomTeam; @@ -23,10 +22,13 @@ class CustomBattle const std::shared_ptr& GetRawData() { return raw_data_; } int GetZoneId() { return zone_id_; } int GetNodeId() { return zone_id_; } + int GetMapId() { return map_id_; } + RoomType_e GetRoomType(); + RoomMode_e GetRoomMode(); int GetStartTime() { return start_time_; } void ParseResult(a8::XObject& obj); - bool CanAdd(const std::string& account_id, const std::string& session_id); std::shared_ptr GetTeamByAccountId(const std::string& account_id); + std::shared_ptr GetTeamByIdx(int idx); std::shared_ptr GetMemberByAccountId(const std::string& account_id); std::shared_ptr GetTeamByTeamUuid(const std::string& team_uuid); std::shared_ptr GetObByAccountId(const std::string& account_id); @@ -37,20 +39,30 @@ class CustomBattle void TraverseTeamList(std::function)> cb); void TraverseObList(std::function)> cb); void SetCustomRoomType(int custom_room_type) { custom_room_type_ = custom_room_type; } - bool IsPvp() { return custom_room_type_ == CUSTOM_ROOM_PVP; } - bool IsMoba() { return custom_room_type_ == CUSTOM_ROOM_MOBA; } + bool IsNormalMode() { return custom_room_type_ == CUSTOM_ROOM_NORMAL; } + bool IsCustomMode() { return custom_room_type_ == CUSTOM_ROOM_CUSTOM; } + bool IsPvp() { return !is_moba_; } + bool IsMoba() { return is_moba_; } + +private: + + void CalcTeam1AverageHeroLv(); private: bool parse_ok_ = false; Room *room_ = nullptr; - int custom_room_type_ = CUSTOM_ROOM_PVP; + int custom_room_type_ = CUSTOM_ROOM_CUSTOM; + bool is_moba_ = false; std::string room_id_; std::string room_uuid_; int zone_id_ = 0; int node_id_ = 0; + int map_id_ = 0; int start_time_ = 0; + int team1_average_hero_lv_ = 0; std::string sign_; std::shared_ptr raw_data_; + std::vector> team_list_; std::map> uuid_hash_; std::shared_ptr ob_team_; std::map> account_hash_; diff --git a/server/gameserver/custom_team.cc b/server/gameserver/custom_team.cc index a831a185..bf79927f 100644 --- a/server/gameserver/custom_team.cc +++ b/server/gameserver/custom_team.cc @@ -1,6 +1,8 @@ #include "precompile.h" #include "custom_team.h" +#include "custom_member.h" +#include "netdata.h" std::shared_ptr CustomTeam::GetMember(const std::string& account_id) { @@ -21,3 +23,23 @@ int CustomTeam::GetMemberNum() { return member_hash_.size(); } + +int CustomTeam::GetAverageHeroLv() +{ + if (GetMemberNum() <= 0) { + return 0; + } + int total_hero_lv = 0; + TraverseMember + ( + [&total_hero_lv] (std::shared_ptr m) -> bool + { + long long hero_uniid = 0; + int hero_lv = 0; + int quality = 0; + m->GetNetData()->GetHeroLvQuality(hero_uniid, hero_lv, quality); + total_hero_lv += hero_lv; + return true; + }); + return total_hero_lv / GetMemberNum(); +} diff --git a/server/gameserver/custom_team.h b/server/gameserver/custom_team.h index e3b26243..4393a02e 100644 --- a/server/gameserver/custom_team.h +++ b/server/gameserver/custom_team.h @@ -10,6 +10,7 @@ class CustomTeam bool IsView() { return is_view_; } void TraverseMember(std::function)> cb); int GetMemberNum(); + int GetAverageHeroLv(); private: std::string team_uuid_; diff --git a/server/gameserver/pbutils.cc b/server/gameserver/pbutils.cc index 1335b3a5..b429056e 100644 --- a/server/gameserver/pbutils.cc +++ b/server/gameserver/pbutils.cc @@ -2810,6 +2810,119 @@ int Room::InitWithCustomBattle(long ip_saddr, int socket_handle, std::shared_ptr return 0; } +int Room::JoinWithCustomBattle(long ip_saddr, int socket_handle, std::shared_ptr msg, + std::shared_ptr p) +{ + std::vector> room_teams; + std::vector> net_teams; + p->TraverseTeamList + ( + [this, &room_teams, &net_teams] (std::shared_ptr team) -> bool + { + auto new_team = NewTeam(); + new_team->SetInitTeamMemberNum(0); + new_team->SetAutoFill(true); + room_teams.push_back(new_team); + net_teams.push_back(team); + return true; + }); + if (room_teams.empty()) { + abort(); + } + if (IsMobaModeRoom() && + room_teams.size() > 2) { + abort(); + } + cs::CMJoin join_msg = *msg; + for (size_t i = 0; i < net_teams.size(); ++i) { + auto net_team = net_teams.at(i); + auto room_team = room_teams.at(i); + room_team->SetInitTeamMemberNum(net_team->GetMemberNum()); + net_team->TraverseMember + ( + [join_msg, p, room_team] (std::shared_ptr m) mutable -> bool + { + Player* hum = InternalCreatePlayer(p, m, room_team, join_msg); + return true; + } + ); + } + if (IsMobaModeRoom()) { + if (room_teams.size() < 2) { + auto new_team = NewTeam(); + new_team->SetInitTeamMemberNum(0); + new_team->SetAutoFill(true); + room_teams.push_back(new_team); + } + int side = a8::RandEx(1, 2); + for (size_t i = 0; i < 2; ++i) { + auto team = room_teams.at(i); + if (team->GetMemberNum() < MAX_TEAM_NUM) { + CreateAndroid(MAX_TEAM_NUM - team->GetMemberNum(), team); + } + if (i == 0) { + moba_team_a_ = team.get(); + } else { + moba_team_b_ = team.get(); + } + team->TraverseMembers + ( + [this, side] (Human* hum) -> bool + { + hum->side = side; + std::shared_ptr born_point = std::make_shared(); + born_point->wo_meta = std::get<0>(GetMapMeta()->moba_born_points.at(side - 1)); + hum->SetBornPoint(born_point); + hum->InitMobaRoad(); +#ifdef MYDEBUG + a8::XPrintf("moba init uniid:%d team_id:%d side:%d wo_meta:%d\n", + { + hum->GetUniId(), + hum->GetTeam()->GetTeamId(), + hum->side, + (long long)hum->GetBornPoint()->wo_meta.get() + }); +#endif + return true; + }); + if (side == 1) { + side = 2; + } else { + side = 1; + } + } + } + { + p->TraverseObList + ( + [this, join_msg, p] (std::shared_ptr m) mutable -> bool + { + auto new_team = NewViewTeam(); + new_team->SetInitTeamMemberNum(0); + new_team->SetAutoFill(true); + Player* hum = InternalCreatePlayer(p, m, new_team, join_msg, + [p] (Player* hum) + { + a8::SetBitFlag(hum->status, CS_IsOb); + p->GetRoom()->GetRoomOb()->AddOb(hum); + }); + return true; + }); + } + { + auto hum = GetPlayerByAccountId(msg->account_id()); + if (hum) { + hum->ReJoin(ip_saddr, socket_handle, msg); + } else { + auto hum = p->GetRoom()->GetRoomOb()->GetByAccountId(msg->account_id()); + if (hum) { + hum->ReJoin(ip_saddr, socket_handle, msg); + } + } + } + return 0; +} + void SyncObject::FillSMSyncPosition(cs::SMSyncPosition& sync_msg) { if (!c.Get()) { diff --git a/server/gameserver/room.cc b/server/gameserver/room.cc index e1cecec5..1b1be6e6 100644 --- a/server/gameserver/room.cc +++ b/server/gameserver/room.cc @@ -3601,3 +3601,50 @@ void Room::DecAliveCount() alive_count_chged_frameno_ = GetFrameNo(); --PerfMonitor::Instance()->alive_count; } + +bool Room::CanJoin(std::shared_ptr p) +{ + if (p->IsMoba()) { + return false; + } + if (!p->IsNormalMode()) { + return false; + } + if (p->GetTeamNum() > 1) { + return false; + } + if (p->GetTeamNum() < 1) { + return false; + } + + if (lock_room_) { + return false; + } + if (IsCustomBattle()) { + return false; + } + if (IsMobaModeRoom()) { + return false; + } + if (room_mode_ != p->GetRoomMode()) { + return false; + } + if (GetGasData().GetGasMode() != GasInactive) { + return false; + } + if (map_meta_->map_id() != p->GetMapId()) { + return false; + } + + auto p_team = p->GetTeamByIdx(0); + if (GetPlayerNum() + p_team->GetMemberNum() > GetRoomMaxPlayerNum()) { + return false; + } + int try_count = 0; + while (GetHumanNum() + p_team->GetMemberNum() > GetRoomMaxPlayerNum() && + try_count < 100) { + ++try_count; + RandRemoveAndroid(); + } + return GetHumanNum() + p_team->GetMemberNum() <= GetRoomMaxPlayerNum(); +} diff --git a/server/gameserver/room.h b/server/gameserver/room.h index 48d62c73..d20fb637 100644 --- a/server/gameserver/room.h +++ b/server/gameserver/room.h @@ -209,6 +209,7 @@ public: int self_channel, int init_map_id, const cs::CMJoin& msg); + bool CanJoin(std::shared_ptr p); void OnPlayerOffline(Player* hum); void FillSMUiUpdate(cs::SMUiUpdate& msg); void NotifyUiUpdate(); @@ -282,6 +283,8 @@ public: int GenShotUniid() { return ++current_shot_uniid_; } int InitWithCustomBattle(long ip_saddr, int socket_handle, std::shared_ptr msg, std::shared_ptr p); + int JoinWithCustomBattle(long ip_saddr, int socket_handle, std::shared_ptr msg, + std::shared_ptr p); void CreateAndroid(int android_num, std::shared_ptr team = nullptr); int GetFullLevelIdx() { return ++curr_full_level_idx_;} std::shared_ptr GetRoomOb(); diff --git a/server/gameserver/roommgr.cc b/server/gameserver/roommgr.cc index ef6b9ef0..160e9dec 100644 --- a/server/gameserver/roommgr.cc +++ b/server/gameserver/roommgr.cc @@ -125,15 +125,15 @@ void RoomMgr::_CMJoin(f8::MsgHdr* hdr, const cs::CMJoin& msg) }); #endif } + if (!msg.payload_data().empty()) { + DispatchSpecRoom(hdr, msg); + return; + } const mt::Map* map_meta = mt::Map::GetById(msg.mapid()); if (!map_meta || !map_meta->IsOpen()) { JoinErrorHandle(msg, 3, hdr->socket_handle); return; } - if (!msg.payload_data().empty()) { - DispatchSpecRoom(hdr, msg); - return; - } std::shared_ptr join_msg = std::make_shared(); *join_msg = msg; std::vector> join_msgs{join_msg}; @@ -324,16 +324,60 @@ std::shared_ptr RoomMgr::GetJoinableRoom(const cs::CMJoin& msg, } } } - return CreateRoom(msg, - self_room_type, + return CreateRoom(self_room_type, game_times, creator_register_time, proto_version, channel, msg.mapid(), + (RoomMode_e)msg.room_mode(), nullptr); } +std::shared_ptr RoomMgr::GetJoinableRoom(std::shared_ptr p) +{ + if (p->IsMoba()) { + return nullptr; + } + if (p->IsCustomMode()) { + return nullptr; + } + std::vector>> group_rooms; + for (int i = 0; i < RoomType_Max; ++i) { + group_rooms.push_back(std::vector>()); + } + for (auto& pair : inactive_room_hash_) { + auto& room = pair.second; + if (!room->GetCustomBattle() && + room->CanJoin(p)) { + group_rooms.at(room->GetRoomType()).push_back(room); + } + } + + if (!group_rooms.at(p->GetRoomType()).empty()) { + return group_rooms[p->GetRoomType()][rand() % group_rooms[p->GetRoomType()].size()]; + } + if (p->GetRoomType() == kPvpRankMode) { + } else { + if (p->GetRoomType() == RoomType_OldBrid2) { + for (auto& room : group_rooms[RoomType_OldBrid3]) { + if (room->GetGasInactiveReaminTime() > 8 && + room->GetPlayerNum() + 8 < room->GetRoomMaxPlayerNum()) { + return room; + } + } + } else if (p->GetRoomType() == RoomType_OldBrid3) { + for (auto& room : group_rooms[RoomType_OldBrid2]) { + if (room->GetGasInactiveReaminTime() > 8 && + room->GetPlayerNum() + 8 < room->GetRoomMaxPlayerNum()) { + return room; + } + } + } + } + return nullptr; +} + std::shared_ptr RoomMgr::GetRoomByUuid(const std::string& room_uuid) { auto itr = room_hash_.find(room_uuid); @@ -500,13 +544,13 @@ int RoomMgr::AllocRoomIdx() return current_room_idx_; } -std::shared_ptr RoomMgr::CreateRoom(const cs::CMJoin& msg, - RoomType_e room_type, +std::shared_ptr RoomMgr::CreateRoom(RoomType_e room_type, int game_times, int creator_register_time, int creator_proto_version, int creator_channel, int map_id, + RoomMode_e room_mode, std::shared_ptr custom_battle) { int room_idx = AllocRoomIdx(); @@ -518,14 +562,16 @@ std::shared_ptr RoomMgr::CreateRoom(const cs::CMJoin& msg, init_info.room_idx = room_idx; init_info.room_uuid = f8::App::Instance()->NewGlobalUuid(); init_info.room_type = room_type; - init_info.room_mode = (RoomMode_e)msg.room_mode(); + init_info.room_mode = room_mode; init_info.init_map_id = map_id; init_info.creator_game_times = game_times; init_info.creator_register_time = creator_register_time; init_info.creator_proto_version = creator_proto_version; init_info.creator_channel = creator_channel; +#if 0 init_info.pve_instance_id = msg.pve_instance_id(); init_info.pve_human_num = std::max(1, msg.team_members_size()); +#endif init_info.custom_battle = custom_battle; if (GetRoomByUuid(init_info.room_uuid)) { A8_ABORT(); @@ -1009,35 +1055,69 @@ void RoomMgr::_CMJoinCustomBattle(f8::MsgHdr* hdr, const cs::CMJoin& msg, int cu } return; } + const mt::Map* map_meta = mt::Map::GetById(p->GetMapId()); + if (!map_meta || !map_meta->IsOpen()) { + RoomMgr::Instance()->JoinErrorHandle(msg, 3, socket_handle); + return; + } int game_times = 0; - RoomType_e self_room_type = RoomType_OldBrid1; + RoomType_e self_room_type = p->GetRoomType(); time_t register_time = f8::ExtractRegisterTimeFromSessionId(msg.session_id()); int proto_version = msg.proto_version(); int channel = f8::ExtractChannelIdFromAccountId(msg.account_id()); std::shared_ptr room = nullptr; - if (p->IsPvp()) { - room = RoomMgr::Instance()->CreateRoom - (*join_msg, - self_room_type, - game_times, - register_time, - join_msg->proto_version(), - channel, - msg.mapid(), - p); + if (p->IsNormalMode()) { + room = RoomMgr::Instance()->GetJoinableRoom(p); + if (!room) { + if (p->IsPvp()) { + room = RoomMgr::Instance()->CreateRoom + (self_room_type, + game_times, + register_time, + join_msg->proto_version(), + channel, + p->GetMapId(), + p->GetRoomMode(), + nullptr); + } else { + room = RoomMgr::Instance()->CreateRoom + (self_room_type, + game_times, + register_time, + join_msg->proto_version(), + channel, + p->GetMapId(), + p->GetRoomMode(), + nullptr); + } + } + p->SetRoom(room.get()); + room->JoinWithCustomBattle(ip_saddr, socket_handle, join_msg, p); } else { - room = RoomMgr::Instance()->CreateRoom - (*join_msg, - self_room_type, - game_times, - register_time, - join_msg->proto_version(), - channel, - msg.mapid(), - nullptr); + if (p->IsPvp()) { + room = RoomMgr::Instance()->CreateRoom + (self_room_type, + game_times, + register_time, + join_msg->proto_version(), + channel, + p->GetMapId(), + p->GetRoomMode(), + p); + } else { + room = RoomMgr::Instance()->CreateRoom + (self_room_type, + game_times, + register_time, + join_msg->proto_version(), + channel, + p->GetMapId(), + p->GetRoomMode(), + nullptr); + } + p->SetRoom(room.get()); + room->InitWithCustomBattle(ip_saddr, socket_handle, join_msg, p); } - p->SetRoom(room.get()); - room->InitWithCustomBattle(ip_saddr, socket_handle, join_msg, p); }; SendGetCustomBattleData(join_msg, cb, custom_room_type); } @@ -1084,11 +1164,11 @@ void RoomMgr::SendGetCustomBattleData(std::shared_ptr join_msg, { std::string url; JsonDataMgr::Instance()->GetApiUrl(url); - if (custom_room_type == CUSTOM_ROOM_MOBA) { + if (custom_room_type == CUSTOM_ROOM_CUSTOM) { if (url.find('?') != std::string::npos) { - url += "&c=Battle&a=getMobaBattleData"; + url += "&c=Battle&a=getCustomBattleDataNew"; } else { - url += "?&c=Battle&a=getMobaBattleData"; + url += "?&c=Battle&a=getCustomBattleDataNew"; } } else if (custom_room_type == CUSTOM_ROOM_NORMAL) { if (url.find('?') != std::string::npos) { @@ -1096,13 +1176,8 @@ void RoomMgr::SendGetCustomBattleData(std::shared_ptr join_msg, } else { url += "?&c=Battle&a=getNormalBattleData"; } - } else { - if (url.find('?') != std::string::npos) { - url += "&c=Battle&a=getCustomBattleData"; - } else { - url += "?&c=Battle&a=getCustomBattleData"; - } + A8_ABORT(); } auto url_params = a8::MutableXObject::CreateObject(); url_params->SetVal("account_id", join_msg->account_id()); @@ -1183,14 +1258,14 @@ void RoomMgr::DispatchSpecRoom(f8::MsgHdr* hdr, const cs::CMJoin& msg) a8::Split(head, strings, ':'); if (strings.size() > 1) { if (strings.at(1) == "custom_room") { - _CMJoinCustomBattle(hdr, msg, CUSTOM_ROOM_PVP); + _CMJoinCustomBattle(hdr, msg, CUSTOM_ROOM_CUSTOM); } else if (strings.at(1) == "normal_room") { _CMJoinCustomBattle(hdr, msg, CUSTOM_ROOM_NORMAL); - } else if (strings.at(1) == "moba_room") { - _CMJoinCustomBattle(hdr, msg, CUSTOM_ROOM_MOBA); + } else { + A8_ABORT(); } } else { - _CMJoinCustomBattle(hdr, msg, CUSTOM_ROOM_PVP); + A8_ABORT(); } } diff --git a/server/gameserver/roommgr.h b/server/gameserver/roommgr.h index 96964850..97ba59dc 100644 --- a/server/gameserver/roommgr.h +++ b/server/gameserver/roommgr.h @@ -96,18 +96,19 @@ class RoomMgr : public a8::Singleton int creator_register_time, int proto_version, int channel); + std::shared_ptr GetJoinableRoom(std::shared_ptr p); void ReportServerState(int instance_id, const std::string& host, int port); void FreeOverRoom(const std::string& room_uuid); bool IsLimitJoin(); int AllocRoomIdx(); - std::shared_ptr CreateRoom(const cs::CMJoin& msg, - RoomType_e room_type, + std::shared_ptr CreateRoom(RoomType_e room_type, int game_times, int creator_register_time, int creator_proto_version, int creator_channel, int map_id, + RoomMode_e room_mode, std::shared_ptr custom_battle); void JoinErrorHandle(const cs::CMJoin& msg, int error_code, int socket_handle); std::string GenTeamHashData(const std::string& team_uuid, std::map* team_hash); diff --git a/server/gameserver/team.cc b/server/gameserver/team.cc index 134f6c17..8acfb96b 100644 --- a/server/gameserver/team.cc +++ b/server/gameserver/team.cc @@ -373,6 +373,7 @@ void Team::GenBattleReportData(Human* player, a8::MutableXObject* params) } member_pb->SetVal("move_distance", hum->stats->move_distance); member_pb->SetVal("full_level_idx", hum->stats->full_level_idx); + member_pb->SetVal("hero_level", hum->GetHeroLevel()); member_pb->SetVal("is_run_away", hum->stats->is_run_away); member_pb->SetVal("hero_id", hum->meta->id());