game2005/server/gameserver/matchteam.cc
aozhiwei cde210548c 1
2021-09-28 02:59:57 +00:00

352 lines
8.5 KiB
C++

#include "precompile.h"
#include <a8/timer.h>
#include "matchteam.h"
#include "matchmgr.h"
#include "GGListener.h"
#include "metamgr.h"
void RawTeamMember::FillMFMatchTeamMember(cs::MFMatchTeamMember* p)
{
p->set_account_id(msg.account_id());
p->set_name(msg.name());
p->set_avatar_url(msg.avatar_url());
p->set_hero_id(msg.hero_id());
*p->mutable_weapons() = msg.weapons();
*p->mutable_skins() = msg.skins();
*p->mutable_skill_list() = msg.skill_list();
p->set_is_leader(is_leader);
p->set_state(state);
}
void RawTeamMember::InitRobot()
{
static long long robot_idx = 1000;
msg.set_account_id(a8::Format("6000_2005_%d", {++robot_idx}));
{
std::set<int> refreshed_robot_set;
MetaData::Robot* robot_meta = MetaMgr::Instance()->RandRobot(refreshed_robot_set);
if (robot_meta) {
msg.set_hero_id(robot_meta->i->hero_id());
msg.set_name(robot_meta->i->name());
auto skin = msg.add_skins();
if (!robot_meta->skin_id.empty()) {
skin->set_skin_id(robot_meta->skin_id[0]);
skin->set_skin_lv(1);
}
}
}
}
void MatchTeam::Init(f8::MsgHdr& hdr, const cs::CMJoin& msg)
{
master_team_ = this;
create_tick_ = a8::XGetTickCount();
a8::Timer::Instance()->AddRepeatTimerAndAttach
(1000,
a8::XParams()
.SetSender(this),
[] (const a8::XParams& param)
{
MatchTeam* team = (MatchTeam*)param.sender.GetUserData();
team->Update();
},
&timer_attacher.timer_list_);
phase_= kMatchCombining;
phase_start_tick_ = a8::XGetTickCount();
countdown_ = MetaMgr::Instance()->match_team_time;
AddRawMember(hdr, msg);
}
void MatchTeam::_CMMatchCancel(f8::MsgHdr& hdr, const cs::CMMatchCancel& msg)
{
auto member = GetMemberBySocket(hdr.socket_handle);
if (member) {
}
}
void MatchTeam::_CMMatchChoose(f8::MsgHdr& hdr, const cs::CMMatchChoose& msg)
{
auto member = GetMemberBySocket(hdr.socket_handle);
if (member) {
member->msg.set_hero_id(msg.hero_id());
*member->msg.mutable_weapons() = msg.weapons();
*member->msg.mutable_skins() = msg.skins();
*member->msg.mutable_skill_list() = msg.skill_list();
}
}
void MatchTeam::_CMMatchStartGame(f8::MsgHdr& hdr, const cs::CMMatchStartGame& msg)
{
if (phase_ == kMatchChoose) {
auto member = GetMemberBySocket(hdr.socket_handle);
if (member) {
}
}
}
void MatchTeam::AddRawMember(f8::MsgHdr& hdr, const cs::CMJoin& msg)
{
std::shared_ptr<RawTeamMember> member = std::make_shared<RawTeamMember>();
member->team = this;
member->add_tick = a8::XGetTickCount();
member->socket_handle = hdr.socket_handle;
member->msg = msg;
raw_member_hash_[msg.account_id()] = member;
curr_member_hash_.push_back(member);
if (!first_member_) {
first_member_ = member;
}
}
bool MatchTeam::IsRawMember(const std::string &account_id)
{
auto itr = raw_member_hash_.find(account_id);
return itr != raw_member_hash_.end();
}
bool MatchTeam::IsValidMember(const cs::CMJoin& msg)
{
return false;
}
void MatchTeam::Update()
{
if (IsMasterTeam()) {
UpdateMaster();
} else {
UpdateSlave();
}
master_team_->SyncMatchInfo();
}
void MatchTeam::SyncMatchInfo()
{
cs::SMUpdateMatchInfo notifymsg;
for (auto member : curr_member_hash_) {
member->FillMFMatchTeamMember(notifymsg.mutable_info()->add_members());
}
notifymsg.mutable_info()->set_phase(phase_);
notifymsg.mutable_info()->set_countdown(phase_left_time_);
for (auto& member : curr_member_hash_) {
if (member->socket_handle != 0) {
GGListener::Instance()->SendToClient(member->socket_handle, 0, notifymsg);
}
}
}
void MatchTeam::TryCombineTeam()
{
if (GetPredictMemberNum() < MAX_TEAM_NUM) {
MatchTeam* matched_team = nullptr;
MatchMgr::Instance()->TraverseTeam
(
[this, &matched_team] (MatchTeam* team, bool& stop)
{
if (team == this) {
return;
}
if (CanCombine(team)) {
matched_team = team;
stop = true;
}
});
if (matched_team) {
Combine(matched_team);
}
}
}
void MatchTeam::UpdateMaster()
{
phase_left_time_ = GetPhaseLeftTime();
switch (phase_) {
case kMatchCombining:
{
if (IsShuaRobotTime()) {
if (curr_member_hash_.size() < MAX_TEAM_NUM) {
ShuaRobot();
}
} else {
if (GetPredictMemberNum() < MAX_TEAM_NUM) {
TryCombineTeam();
}
}
if (phase_left_time_ <= 0) {
phase_ = kMatchChoose;
phase_start_tick_ = a8::XGetTickCount();
}
}
break;
case kMatchChoose:
{
if (phase_left_time_ <= 0) {
phase_ = kMatchLock;
phase_start_tick_ = a8::XGetTickCount();
}
}
break;
case kMatchLock:
{
}
break;
default:
{
}
break;
}
}
void MatchTeam::UpdateSlave()
{
switch (phase_) {
case kMatchCombining:
{
}
break;
case kMatchChoose:
{
}
break;
case kMatchLock:
{
}
break;
default:
{
}
break;
}
}
int MatchTeam::GetPredictMemberNum()
{
int num = GetRawMemberNum();
for (auto& pair : combined_team_hash_) {
num += pair.second->GetRawMemberNum();
}
return num;
}
bool MatchTeam::HasSameCurrMember(MatchTeam* b)
{
bool has = false;
for (auto& a_member : curr_member_hash_) {
for (auto& b_member : b->curr_member_hash_) {
if (a_member->msg.account_id() == b_member->msg.account_id()) {
has = true;
break;
}
}
}
return has;
}
bool MatchTeam::CanCombine(MatchTeam* b)
{
if (this == b) {
return false;
}
//已合并
if (master_team_ != this){
return false;
}
//已合并
if (b->master_team_ != b) {
return false;
}
if (phase_ != kMatchCombining) {
return false;
}
if (b->phase_ != kMatchCombining) {
return false;
}
if (IsShuaRobotTime()) {
return false;
}
if (b->IsShuaRobotTime()) {
return false;
}
if (!b->combined_team_hash_.empty()) {
return false;
}
if (GetPredictMemberNum() + b->GetPredictMemberNum() > MAX_TEAM_NUM) {
return false;
}
if (combined_team_hash_.find(b->GetTeamUUid()) != combined_team_hash_.end()) {
return false;
}
if (HasSameCurrMember(b)) {
return false;
}
return true;
}
void MatchTeam::Combine(MatchTeam* b)
{
combined_team_hash_[b->GetTeamUUid()] = b;
b->master_team_ = this;
for (auto& member : b->curr_member_hash_) {
curr_member_hash_.push_back(member);
}
}
std::string MatchTeam::GetTeamUUid()
{
return first_member_->msg.team_uuid();
}
bool MatchTeam::IsShuaRobotTime()
{
return phase_ == kMatchCombining &&
phase_left_time_ <= MetaMgr::Instance()->match_robot_time;
}
int MatchTeam::GetPhaseLeftTime()
{
int passtime = (a8::XGetTickCount() - phase_start_tick_) / 1000;
return std::max(0, countdown_ - passtime);
}
std::shared_ptr<RawTeamMember> MatchTeam::GetMemberBySocket(int socket_handle)
{
for (auto& pair : raw_member_hash_) {
if (pair.second->socket_handle == socket_handle) {
return pair.second;
}
}
return std::shared_ptr<RawTeamMember>();
}
void MatchTeam::ShuaRobot()
{
for (int i = curr_member_hash_.size(); i < MAX_TEAM_NUM; ++i) {
std::shared_ptr<RawTeamMember> member = std::make_shared<RawTeamMember>();
member->team = this;
member->add_tick = a8::XGetTickCount();
member->is_robot = true;
member->InitRobot();
curr_member_hash_.push_back(member);
}
}
void MatchTeam::StartGame()
{
for (auto& member : curr_member_hash_) {
if (member->socket_handle != 0) {
MatchMgr::Instance()->RemoveSocket(member->socket_handle);
}
}
for (auto& pair : combined_team_hash_) {
MatchMgr::Instance()->RemoveTeam(pair.first);
}
MatchMgr::Instance()->RemoveTeam(GetTeamUUid());
}