259 lines
11 KiB
C++
259 lines
11 KiB
C++
#include "precompile.h"
|
|
|
|
#include <a8/timer.h>
|
|
#include <a8/mutable_xobject.h>
|
|
|
|
#include "roommgr.h"
|
|
#include "room.h"
|
|
#include "cs_proto.pb.h"
|
|
#include "GGListener.h"
|
|
#include "player.h"
|
|
#include "playermgr.h"
|
|
#include "app.h"
|
|
#include "metamgr.h"
|
|
#include "jsondatamgr.h"
|
|
#include "playermgr.h"
|
|
|
|
#include "framework/cpp/httpclientpool.h"
|
|
|
|
void RoomMgr::Init()
|
|
{
|
|
InstallReportStateTimer();
|
|
}
|
|
|
|
void RoomMgr::UnInit()
|
|
{
|
|
for (auto& pair : room_hash_) {
|
|
pair.second->UnInit();
|
|
delete pair.second;
|
|
}
|
|
for (auto& pair : over_room_hash_) {
|
|
pair.second->UnInit();
|
|
delete pair.second;
|
|
}
|
|
}
|
|
|
|
void RoomMgr::Update(int delta_time)
|
|
{
|
|
for (auto& pair : room_hash_) {
|
|
pair.second->Update(delta_time);
|
|
}
|
|
}
|
|
|
|
void RoomMgr::_CMJoin(f8::MsgHdr& hdr, const cs::CMJoin& msg)
|
|
{
|
|
MetaData::Player* hum_meta = MetaMgr::Instance()->GetPlayer(40001);
|
|
if (!hum_meta) {
|
|
abort();
|
|
}
|
|
Room* room = GetJoinableRoom(msg);
|
|
if (!room) {
|
|
room = new Room();
|
|
room->room_uuid = App::Instance()->NewUuid();
|
|
if (GetRoomByUuid(room->room_uuid)) {
|
|
abort();
|
|
}
|
|
if (App::Instance()->HasFlag(5)) {
|
|
room->map_meta = MetaMgr::Instance()->GetMap(1);
|
|
} else {
|
|
room->map_meta = MetaMgr::Instance()->RandMap();
|
|
}
|
|
room->map_tpl_name = room->map_meta->i->template_name();
|
|
assert(MetaMgr::Instance()->GetMapTplSize(room->map_tpl_name, room->map_width, room->map_height));
|
|
room->Init(msg);
|
|
room_unionid_hash_[msg.team_uuid()] = room;
|
|
inactive_room_hash_[room->room_uuid] = room;
|
|
room_hash_[room->room_uuid] = room;
|
|
}
|
|
Player* hum = PlayerMgr::Instance()->CreatePlayerByCMJoin(hdr.ip_saddr, hdr.socket_handle, msg);
|
|
hum->SetMeta(hum_meta);
|
|
room->AddPlayer(hum);
|
|
hum->ProcPrepareItems(msg.prepare_items());
|
|
for (int buff_id : msg.buff_list()) {
|
|
MetaData::Buff* buff_meta = MetaMgr::Instance()->GetBuff(buff_id);
|
|
if (buff_meta) {
|
|
hum->AddBuff(buff_meta, 1);
|
|
}
|
|
}
|
|
{
|
|
cs::SMJoinedNotify notifymsg;
|
|
notifymsg.set_error_code(0);
|
|
room->FillSMJoinedNotify(hum, notifymsg);
|
|
GGListener::Instance()->SendToClient(hdr.socket_handle, hdr.seqid, notifymsg);
|
|
}
|
|
{
|
|
cs::SMMapInfo notifymsg;
|
|
notifymsg.set_map_id(room->map_meta->i->map_id());
|
|
notifymsg.set_map_width(room->map_width);
|
|
notifymsg.set_map_height(room->map_height);
|
|
GGListener::Instance()->SendToClient(hdr.socket_handle, hdr.seqid, notifymsg);
|
|
}
|
|
}
|
|
|
|
int RoomMgr::RoomNum()
|
|
{
|
|
return room_hash_.size();
|
|
}
|
|
|
|
int RoomMgr::OverRoomNum()
|
|
{
|
|
return over_room_hash_.size();
|
|
}
|
|
|
|
Room* RoomMgr::GetJoinableRoom(const cs::CMJoin& msg)
|
|
{
|
|
auto itr = room_unionid_hash_.find(msg.team_uuid());
|
|
if (itr != room_unionid_hash_.end()) {
|
|
if (itr->second->CanJoin(msg)) {
|
|
return itr->second;
|
|
} else {
|
|
return nullptr;
|
|
}
|
|
} else {
|
|
return nullptr;
|
|
}
|
|
}
|
|
|
|
Room* RoomMgr::GetRoomByUuid(long long room_uuid)
|
|
{
|
|
auto itr = room_hash_.find(room_uuid);
|
|
return itr != room_hash_.end() ? itr->second : nullptr;
|
|
}
|
|
|
|
void RoomMgr::AddOverRoom(long long room_uuid)
|
|
{
|
|
auto callback = [] (const a8::XParams& param)
|
|
{
|
|
Room* room = RoomMgr::Instance()->GetRoomByUuid(param.sender);
|
|
if (room) {
|
|
if ((room->pending_request <= 0) ||
|
|
(a8::XGetTickCount() - room->game_over_tick > 1000 * 8)) {
|
|
RoomMgr::Instance()->room_unionid_hash_.erase(room->room_unionid);
|
|
RoomMgr::Instance()->room_hash_.erase(room->room_uuid);
|
|
RoomMgr::Instance()->over_room_hash_[room->room_uuid] = room;
|
|
RoomMgr::Instance()->FreeOverRoom(param.sender);
|
|
}
|
|
}
|
|
};
|
|
|
|
inactive_room_hash_.erase(room_uuid);
|
|
Room* room = GetRoomByUuid(room_uuid);
|
|
if (room) {
|
|
room->game_over_tick = a8::XGetTickCount();
|
|
room->game_over_timer = a8::Timer::Instance()->AddRepeatTimer(500,
|
|
a8::XParams()
|
|
.SetSender(room_uuid),
|
|
callback);
|
|
}
|
|
}
|
|
|
|
void RoomMgr::ActiveRoom(long long room_uuid)
|
|
{
|
|
{
|
|
auto itr = inactive_room_hash_.find(room_uuid);
|
|
if (itr != inactive_room_hash_.end()) {
|
|
room_unionid_hash_.erase(itr->second->room_unionid);
|
|
}
|
|
}
|
|
inactive_room_hash_.erase(room_uuid);
|
|
}
|
|
|
|
void RoomMgr::ReportServerState(int instance_id, const std::string& host, int port)
|
|
{
|
|
auto on_ok = [] (a8::XParams& param, a8::XObject& data)
|
|
{
|
|
a8::Timer::Instance()->AddDeadLineTimerAndAttach(1000,
|
|
a8::XParams()
|
|
.SetSender(param.sender)
|
|
.SetParam1(param.param1)
|
|
.SetParam2(param.param2),
|
|
[] (const a8::XParams& param)
|
|
{
|
|
RoomMgr::Instance()->ReportServerState(
|
|
param.sender,
|
|
param.param1,
|
|
param.param2
|
|
);
|
|
},
|
|
&RoomMgr::Instance()->reportstate_timer_attacher_.timer_list_);
|
|
};
|
|
auto on_error = [] (a8::XParams& param, const std::string& response)
|
|
{
|
|
a8::Timer::Instance()->AddDeadLineTimerAndAttach(1000,
|
|
a8::XParams()
|
|
.SetSender(param.sender)
|
|
.SetParam1(param.param1)
|
|
.SetParam2(param.param2),
|
|
[] (const a8::XParams& param)
|
|
{
|
|
RoomMgr::Instance()->ReportServerState(
|
|
param.sender,
|
|
param.param1,
|
|
param.param2
|
|
);
|
|
},
|
|
&RoomMgr::Instance()->reportstate_timer_attacher_.timer_list_);
|
|
};
|
|
std::string url = a8::Format("http://%s:%d/webapp/index.php?c=GS&a=report&",
|
|
{
|
|
host,
|
|
port
|
|
});
|
|
a8::MutableXObject* url_params = a8::MutableXObject::NewObject();
|
|
url_params->SetVal("node_id", App::Instance()->node_id);
|
|
url_params->SetVal("instance_id", App::Instance()->instance_id);
|
|
url_params->SetVal("ip", JsonDataMgr::Instance()->ip);
|
|
url_params->SetVal("port", JsonDataMgr::Instance()->listen_port);
|
|
url_params->SetVal("online_num", PlayerMgr::Instance()->OnlineNum());
|
|
url_params->SetVal("room_num", RoomNum());
|
|
url_params->SetVal("servicing", App::Instance()->servicing ? 1 : 0);
|
|
f8::HttpClientPool::Instance()->HttpGet(a8::XParams()
|
|
.SetSender(instance_id)
|
|
.SetParam1(host)
|
|
.SetParam2(port),
|
|
on_ok,
|
|
on_error,
|
|
url.c_str(),
|
|
*url_params,
|
|
rand() % kMAX_SYS_HTTP_NUM
|
|
);
|
|
delete url_params;
|
|
}
|
|
|
|
void RoomMgr::FreeOverRoom(long long room_uuid)
|
|
{
|
|
auto itr = over_room_hash_.find(room_uuid);
|
|
if (itr != over_room_hash_.end()) {
|
|
itr->second->UnInit();
|
|
delete itr->second;
|
|
over_room_hash_.erase(itr);
|
|
}
|
|
}
|
|
|
|
void RoomMgr::InstallReportStateTimer()
|
|
{
|
|
reportstate_timer_attacher_.ClearTimerList();
|
|
auto master_svr_cluster_conf = JsonDataMgr::Instance()->GetMasterServerClusterConf();
|
|
for (int i = 0; i < master_svr_cluster_conf->Size(); ++i) {
|
|
auto master_svr_conf = master_svr_cluster_conf->At(i);
|
|
int instance_id = master_svr_conf->At("instance_id")->AsXValue();
|
|
std::string remote_ip = master_svr_conf->At("ip")->AsXValue();
|
|
int remote_port = master_svr_conf->At("listen_port")->AsXValue();
|
|
|
|
a8::Timer::Instance()->AddDeadLineTimerAndAttach(1000 + (i + 1),
|
|
a8::XParams()
|
|
.SetSender(instance_id)
|
|
.SetParam1(remote_ip)
|
|
.SetParam2(remote_port),
|
|
[] (const a8::XParams& param)
|
|
{
|
|
RoomMgr::Instance()->ReportServerState(
|
|
param.sender,
|
|
param.param1,
|
|
param.param2
|
|
);
|
|
},
|
|
&reportstate_timer_attacher_.timer_list_);
|
|
}
|
|
}
|