316 lines
7.2 KiB
C++
316 lines
7.2 KiB
C++
#include "precompile.h"
|
|
|
|
#include <a8/timer.h>
|
|
|
|
#include "cs_proto.pb.h"
|
|
#include "matchteam.h"
|
|
#include "matchmgr.h"
|
|
#include "GGListener.h"
|
|
#include "metamgr.h"
|
|
|
|
struct RawTeamMember
|
|
{
|
|
MatchTeam* team = nullptr;
|
|
long long add_tick = 0;
|
|
int socket_handle = 0;
|
|
cs::CMJoin msg;
|
|
|
|
void FillMFMatchTeamMember(cs::MFMatchTeamMember* msg)
|
|
{
|
|
|
|
}
|
|
|
|
};
|
|
|
|
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 (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::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());
|
|
}
|