This commit is contained in:
aozhiwei 2024-03-22 15:56:43 +08:00
commit 7be35d366c
10 changed files with 394 additions and 66 deletions

View File

@ -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<CustomTeam>();
@ -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<a8::XObject>();
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<CustomMember> CustomBattle::GetMemberByAccountId(const std::string& account_id)
{
auto itr = member_id_hash_.find(account_id);
@ -220,3 +221,55 @@ void CustomBattle::TraverseObList(std::function<bool (std::shared_ptr<CustomMemb
}
}
}
RoomMode_e CustomBattle::GetRoomMode()
{
if (IsMoba()) {
return kMobaMode;
} else {
return kPvpMode;
}
}
void CustomBattle::CalcTeam1AverageHeroLv()
{
if (!team_list_.empty()) {
team1_average_hero_lv_ = team_list_.at(0)->GetAverageHeroLv();
}
}
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<CustomTeam> CustomBattle::GetTeamByIdx(int idx)
{
if (GetTeamNum() <= 0) {
return nullptr;
}
if (idx < 0 || idx >= GetTeamNum()) {
return nullptr;
}
return team_list_.at(idx);
}

View File

@ -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<a8::XObject>& 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<CustomTeam> GetTeamByAccountId(const std::string& account_id);
std::shared_ptr<CustomTeam> GetTeamByIdx(int idx);
std::shared_ptr<CustomMember> GetMemberByAccountId(const std::string& account_id);
std::shared_ptr<CustomTeam> GetTeamByTeamUuid(const std::string& team_uuid);
std::shared_ptr<CustomMember> GetObByAccountId(const std::string& account_id);
@ -37,20 +39,30 @@ class CustomBattle
void TraverseTeamList(std::function<bool (std::shared_ptr<CustomTeam>)> cb);
void TraverseObList(std::function<bool (std::shared_ptr<CustomMember>)> 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<a8::XObject> raw_data_;
std::vector<std::shared_ptr<CustomTeam>> team_list_;
std::map<std::string, std::shared_ptr<CustomTeam>> uuid_hash_;
std::shared_ptr<CustomTeam> ob_team_;
std::map<std::string, std::shared_ptr<CustomTeam>> account_hash_;

View File

@ -1,6 +1,8 @@
#include "precompile.h"
#include "custom_team.h"
#include "custom_member.h"
#include "netdata.h"
std::shared_ptr<CustomMember> 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<CustomMember> 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();
}

View File

@ -10,6 +10,7 @@ class CustomTeam
bool IsView() { return is_view_; }
void TraverseMember(std::function<bool (std::shared_ptr<CustomMember>)> cb);
int GetMemberNum();
int GetAverageHeroLv();
private:
std::string team_uuid_;

View File

@ -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<cs::CMJoin> msg,
std::shared_ptr<CustomBattle> p)
{
std::vector<std::shared_ptr<Team>> room_teams;
std::vector<std::shared_ptr<CustomTeam>> net_teams;
p->TraverseTeamList
(
[this, &room_teams, &net_teams] (std::shared_ptr<CustomTeam> 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<CustomMember> 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<BornPoint> born_point = std::make_shared<BornPoint>();
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<CustomMember> 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()) {

View File

@ -3601,3 +3601,50 @@ void Room::DecAliveCount()
alive_count_chged_frameno_ = GetFrameNo();
--PerfMonitor::Instance()->alive_count;
}
bool Room::CanJoin(std::shared_ptr<CustomBattle> 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();
}

View File

@ -209,6 +209,7 @@ public:
int self_channel,
int init_map_id,
const cs::CMJoin& msg);
bool CanJoin(std::shared_ptr<CustomBattle> 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<cs::CMJoin> msg,
std::shared_ptr<CustomBattle> p);
int JoinWithCustomBattle(long ip_saddr, int socket_handle, std::shared_ptr<cs::CMJoin> msg,
std::shared_ptr<CustomBattle> p);
void CreateAndroid(int android_num, std::shared_ptr<Team> team = nullptr);
int GetFullLevelIdx() { return ++curr_full_level_idx_;}
std::shared_ptr<RoomOb> GetRoomOb();

View File

@ -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<cs::CMJoin> join_msg = std::make_shared<cs::CMJoin>();
*join_msg = msg;
std::vector<std::shared_ptr<cs::CMJoin>> join_msgs{join_msg};
@ -324,16 +324,60 @@ std::shared_ptr<Room> 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<Room> RoomMgr::GetJoinableRoom(std::shared_ptr<CustomBattle> p)
{
if (p->IsMoba()) {
return nullptr;
}
if (p->IsCustomMode()) {
return nullptr;
}
std::vector<std::vector<std::shared_ptr<Room>>> group_rooms;
for (int i = 0; i < RoomType_Max; ++i) {
group_rooms.push_back(std::vector<std::shared_ptr<Room>>());
}
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<Room> 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<Room> RoomMgr::CreateRoom(const cs::CMJoin& msg,
RoomType_e room_type,
std::shared_ptr<Room> 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<CustomBattle> custom_battle)
{
int room_idx = AllocRoomIdx();
@ -518,14 +562,16 @@ std::shared_ptr<Room> 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> 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<cs::CMJoin> 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<cs::CMJoin> 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();
}
}

View File

@ -96,18 +96,19 @@ class RoomMgr : public a8::Singleton<RoomMgr>
int creator_register_time,
int proto_version,
int channel);
std::shared_ptr<Room> GetJoinableRoom(std::shared_ptr<CustomBattle> 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<Room> CreateRoom(const cs::CMJoin& msg,
RoomType_e room_type,
std::shared_ptr<Room> 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<CustomBattle> custom_battle);
void JoinErrorHandle(const cs::CMJoin& msg, int error_code, int socket_handle);
std::string GenTeamHashData(const std::string& team_uuid, std::map<std::string, std::string>* team_hash);

View File

@ -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());