2020-12-24 11:49:25 +08:00

1780 lines
65 KiB
C++

#include "precompile.h"
#include <a8/timer.h>
#include <a8/openssl.h>
#include <a8/mutable_xobject.h>
#include "guild.h"
#include "dbengine.h"
#include "app.h"
#include "guildmgr.h"
#include "typeconvert.h"
#include "utils.h"
#include "dbhelper.h"
#include "synchelper.h"
#include "player.h"
#include "gamelog.h"
#include "metamgr.h"
#include "framework/cpp/httpclientpool.h"
const int GUILD_MAX_ADMIN_NUM = 1;
enum GuildApplyStatus_e
{
kGuildApplyPending = 0,
kGuildApplyAgree = 1,
kGuildApplyReject = 2,
kGuildApplyIgnore = 3,
};
void Guild::Init()
{
last_active_time_ = App::Instance()->nowtime;
last_saveok_time_ = App::Instance()->nowtime;
logdb_ = new ss::MFGuildLogDB;
for (size_t i = 0; i < kGuildJobMax; ++i) {
job_hash_.push_back(std::set<std::string>());
}
RecalcRedPoint();
a8::Timer::Instance()->AddRepeatTimerAndAttach
(
1000 * 60,
a8::XParams()
.SetSender(this),
[] (const a8::XParams& param)
{
Guild* guild = (Guild*)param.sender.GetUserData();
if (App::Instance()->nowtime - guild->last_active_time_ < 300) {
guild->SaveToDB();
}
},
&timer_attacher_.timer_list_);
}
void Guild::UnInit()
{
for (auto& pair : member_hash_) {
delete pair.second;
}
member_hash_.clear();
for (auto& pair : apply_hash_) {
delete pair.second;
}
apply_hash_.clear();
A8_SAFE_DELETE(logdb_);
}
GuildMember* Guild::GetMember(const std::string& account_id)
{
auto itr = member_hash_.find(account_id);
return itr != member_hash_.end() ? itr->second : nullptr;
}
bool Guild::IsFull()
{
MetaData::Guild* meta = MetaMgr::Instance()->GetGuild(GuildLv());
if (meta) {
return member_hash_.size() >= meta->i->member();
} else {
return true;
}
}
void Guild::AddMember(GuildMember* member)
{
if (member_hash_.find(member->account_id) != member_hash_.end()) {
abort();
}
member_hash_[member->account_id] = member;
GenSortedMembers();
MarkDirty();
if (dirty_timer_) {
a8::Timer::Instance()->ModifyTimer(dirty_timer_, 100);
}
}
void Guild::RemoveMember(const std::string& sender_id,
const std::string& target_id,
int reason)
{
GuildMember* member = GetMember(target_id);
if (member) {
{
std::set<std::string>* members = GetJobMembers(GetMemberJob(member->account_id));
if (members) {
members->erase(member->account_id);
}
member_job_hash_.erase(member->account_id);
}
SyncHelper::Instance()->SyncGuildMemberQuit
(
this,
sender_id,
target_id,
reason
);
member_hash_.erase(target_id);
A8_SAFE_DELETE(member);
GenSortedMembers();
}
MarkDirty();
if (dirty_timer_) {
a8::Timer::Instance()->ModifyTimer(dirty_timer_, 100);
}
}
void Guild::MarkDirty()
{
if (!dirty_) {
dirty_ = true;
dirty_timer_ = a8::Timer::Instance()->AddDeadLineTimerAndAttach
(1000 * 60,
a8::XParams()
.SetSender((void*)this),
[] (const a8::XParams& param)
{
Guild* guild = (Guild*)param.sender.GetUserData();
guild->SaveToDB();
},
&timer_attacher_.timer_list_,
[] (const a8::XParams& param)
{
Guild* guild = (Guild*)param.sender.GetUserData();
guild->dirty_timer_ = nullptr;
}
);
}
SyncData();
}
void Guild::SyncData()
{
if (!sync_timer_) {
sync_timer_ = a8::Timer::Instance()->AddDeadLineTimerAndAttach
(1000 * 3,
a8::XParams()
.SetSender((void*)this),
[] (const a8::XParams& param)
{
Guild* guild = (Guild*)param.sender.GetUserData();
guild->SendUpdate();
},
&timer_attacher_.timer_list_,
[] (const a8::XParams& param)
{
Guild* guild = (Guild*)param.sender.GetUserData();
guild->sync_timer_ = nullptr;
}
);
}
}
void Guild::SendUpdate()
{
std::string ip;
int port = 0;
JsonDataMgr::Instance()->GetRankServerConf(ip, port);
a8::MutableXObject* params = a8::MutableXObject::NewObject();
params->SetVal("guild_id", guild_id_);
params->SetVal("guild_name", guild_name_);
params->SetVal("guild_badge", guild_badge_);
params->SetVal("guild_lv", guild_lv_);
params->SetVal("guild_exp", guild_exp_);
params->SetVal("guild_declaration", guild_declaration_);
params->SetVal("owner_id", owner_id_);
params->SetVal("owner_name", owner_name_);
params->SetVal("owner_avatar_url", owner_avatar_url_);
params->SetVal("owner_vip_lv", owner_vip_lv_);
params->SetVal("owner_head", owner_head_);
params->SetVal("owner_sex", owner_sex_);
params->SetVal("join_unlimited", join_unlimited_);
params->SetVal("join_cond1", join_cond1_);
params->SetVal("join_cond2", join_cond2_);
params->SetVal("member_num", GetMemberNum());
f8::HttpClientPool::Instance()->HttpGet
(
a8::XParams(),
[] (a8::XParams& param, a8::XObject& data)
{
},
[] (a8::XParams& param, const std::string& response)
{
},
a8::Format("http://%s:%d/webapp/index.php?c=Guild&a=update", {ip, port}).c_str(),
*params,
GuildId()
);
delete params;
}
void Guild::Deserialize(const std::string& guild_data,
const std::string& guild_members,
const std::string& guild_log)
{
{
logdb_->ParseFromString(guild_log);
}
{
ss::MFGuildDB guilddb;
guilddb.ParseFromString(guild_data);
for (auto& member_pb : guilddb.members()) {
GuildMember* member = new GuildMember;
TypeConvert::Convert(member_pb.base_data(), *member);
member_hash_[member->account_id] = member;
}
GenSortedMembers();
}
{
a8::XObject xobj;
xobj.ReadFromJsonString(guild_members);
if (xobj.GetType() == a8::XOT_ARRAY) {
for (int i = 0; i < xobj.Size(); ++i) {
std::shared_ptr<a8::XObject> item = xobj.At(i);
if (item && item->GetType() == a8::XOT_OBJECT) {
if (item->HasKey("account_id") && item->At("account_id")->GetType() == a8::XOT_SIMPLE &&
item->HasKey("guild_job") && item->At("guild_job")->GetType() == a8::XOT_SIMPLE
) {
std::string account_id = item->At("account_id")->AsXValue().GetString();
int job = item->At("guild_job")->AsXValue();
if (GetMember(account_id) && IsValidGuildJob(job)) {
if (job == kGuildOwner) {
continue;
}
if (job == kGuildAdmin && GetJobMemberNum(job) >= GUILD_MAX_ADMIN_NUM) {
continue;
}
member_job_hash_[account_id] = job;
std::set<std::string>* members = GetJobMembers(job);
members->insert(account_id);
}
}
}
}//end for
}
{
member_job_hash_[owner_id_] = kGuildOwner;
std::set<std::string>* members = GetJobMembers(kGuildOwner);
members->insert(owner_id_);
}
}
}
void Guild::_CMGuildInfo(f8::MsgHdr& hdr, const cs::CMGuildInfo& msg)
{
ss::SS_IM_ForwardGuildCMMsg *forward_msg = (ss::SS_IM_ForwardGuildCMMsg*)hdr.user_data;
cs::SMGuildInfo respmsg;
FillGuildBasic(respmsg.mutable_info());
GuildMgr::Instance()->ForwardGuildSMMsg(hdr.socket_handle,
forward_msg->context(),
respmsg);
}
void Guild::_CMGuildJoin(f8::MsgHdr& hdr, const cs::CMGuildJoin& msg)
{
ss::SS_IM_ForwardGuildCMMsg *forward_msg = (ss::SS_IM_ForwardGuildCMMsg*)hdr.user_data;
cs::SMGuildJoin respmsg;
GuildMgr::Instance()->ForwardGuildSMMsg(hdr.socket_handle,
forward_msg->context(),
respmsg);
GuildMember* member = GetMember(forward_msg->context().user_info().base_data().account_id());
if (member) {
SyncHelper::Instance()->SyncGuildMemberUpdateOnlyOnline(this, member, kGuildUpdateReasonJoin);
} else {
DBHelper::Instance()->AddGuildApply(this, forward_msg->context().user_info());
GameLog::Instance()->GuildApply(this, forward_msg->context().user_info().base_data());
SyncHelper::Instance()->SyncGuildApplyed(this,
forward_msg->context().user_info().base_data().account_id()
);
}
}
void Guild::_CMGuildAgree(f8::MsgHdr& hdr, const cs::CMGuildAgree& msg)
{
ss::SS_IM_ForwardGuildCMMsg *forward_msg = (ss::SS_IM_ForwardGuildCMMsg*)hdr.user_data;
cs::SMGuildAgree respmsg;
if (IsFull()) {
SendErrorMsg(hdr.socket_handle, forward_msg->context(), TEXT("guild_member_upper_limit", "战队人数已达上限"));
respmsg.set_errcode(1);
respmsg.set_errmsg(TEXT("guild_member_upper_limit", "战队人数已达上限"));
GuildMgr::Instance()->ForwardGuildSMMsg(hdr.socket_handle,
forward_msg->context(),
respmsg);
return;
}
GuildMember* sender = GetMember(forward_msg->context().user_info().base_data().account_id());
if (!sender) {
SendErrorMsg(hdr.socket_handle, forward_msg->context(), TEXT("server_internal_error", "服务器内部错误"));
respmsg.set_errcode(2);
respmsg.set_errmsg(TEXT("server_internal_error", "服务器内部错误"));
GuildMgr::Instance()->ForwardGuildSMMsg(hdr.socket_handle,
forward_msg->context(),
respmsg);
return;
}
if (!(
GetMemberJob(sender->account_id) == kGuildOwner ||
GetMemberJob(sender->account_id) == kGuildAdmin)
) {
SendErrorMsg(hdr.socket_handle, forward_msg->context(), TEXT("permission_denied", "权限不够"));
respmsg.set_errcode(3);
respmsg.set_errmsg(TEXT("permission_denied", "权限不够"));
GuildMgr::Instance()->ForwardGuildSMMsg(hdr.socket_handle,
forward_msg->context(),
respmsg);
return;
}
ss::SS_IM_ForwardGuildCMMsg *forward_msg_copy = new ss::SS_IM_ForwardGuildCMMsg;
*forward_msg_copy = *forward_msg;
cs::CMGuildAgree* msg_copy = new cs::CMGuildAgree;
*msg_copy = msg;
unsigned int crc32_code = a8::openssl::Crc32
(
(unsigned char*)msg.apply().base_data().account_id().data(),
msg.apply().base_data().account_id().size()
);
a8::XObject conn_info = DBEngine::Instance()->GetConnInfo(crc32_code);
DBEngine::Instance()->ExecAsyncQuery
(
conn_info,
"SELECT guild_id, guild_job FROM `user` WHERE account_id='%s' AND guild_id != 0;",
{
msg.apply().base_data().account_id()
},
a8::XParams()
.SetSender(guild_id_)
.SetParam1(forward_msg_copy)
.SetParam2(hdr.socket_handle)
.SetParam3(msg_copy),
[] (a8::XParams& param, const f8::DataSet* data_set)
{
ss::SS_IM_ForwardGuildCMMsg *forward_msg_copy = (ss::SS_IM_ForwardGuildCMMsg*)param.param1.GetUserData();
cs::CMGuildAgree* msg_copy = (cs::CMGuildAgree*)param.param3.GetUserData();
Guild* guild = GuildMgr::Instance()->GetGuild(param.sender);
if (guild) {
if (!data_set || data_set->empty()) {
guild->GuildAgreeCb(param.param2,
forward_msg_copy->context(),
*msg_copy);
} else if (data_set && !data_set->empty()) {
const auto& row = (*data_set)[0];
long long guild_id = a8::XValue(row[0]);
if (guild_id == guild->GuildId()) {
cs::SMGuildAgree respmsg;
GuildMgr::Instance()->ForwardGuildSMMsg(param.param2,
forward_msg_copy->context(),
respmsg);
DBHelper::Instance()->SetGuildApplyStatus
(
msg_copy->apply().base_data().account_id(),
guild->GuildId(),
kGuildApplyAgree
);
guild->ClearApplyBySenderId(msg_copy->apply().base_data().account_id());
} else {
guild->SendErrorMsg(param.param2, forward_msg_copy->context(), TEXT("target_already_has_guild", "对方已经有战队"));
}
}
}
delete msg_copy;
delete forward_msg_copy;
},
[] (a8::XParams& param, int error_code, const std::string& error_msg)
{
ss::SS_IM_ForwardGuildCMMsg *forward_msg_copy = (ss::SS_IM_ForwardGuildCMMsg*)param.param1.GetUserData();
cs::CMGuildAgree* msg_copy = (cs::CMGuildAgree*)param.param3.GetUserData();
Guild* guild = GuildMgr::Instance()->GetGuild(param.sender);
if (guild) {
guild->SendErrorMsg(param.param2, forward_msg_copy->context(), TEXT("server_internal_error", "服务器内部错误"));
}
delete msg_copy;
delete forward_msg_copy;
},
crc32_code
);
}
void Guild::_CMGuildGainExp(f8::MsgHdr& hdr, const cs::CMGuildGainExp& msg)
{
ss::SS_IM_ForwardGuildCMMsg *forward_msg = (ss::SS_IM_ForwardGuildCMMsg*)hdr.user_data;
int exp = msg.exp();
if (exp > 0) {
MetaData::Guild* next_guild_meta = nullptr;
do {
MetaData::Guild* curr_guild_meta = MetaMgr::Instance()->GetGuild(GuildLv());
next_guild_meta = MetaMgr::Instance()->GetGuild(GuildLv() + 1);
if (!next_guild_meta || !curr_guild_meta) {
break;
}
if (curr_guild_meta->i->experience() <= GuildExp()) {
++guild_lv_;
guild_exp_ = 0;
next_guild_meta = MetaMgr::Instance()->GetGuild(GuildLv() + 1);
} else {
int add_exp = curr_guild_meta->i->experience() - GuildExp();
if (exp < add_exp) {
guild_exp_ += std::min(add_exp, exp);
break;
} else {
exp -= add_exp;
++guild_lv_;
guild_exp_ = 0;
next_guild_meta = MetaMgr::Instance()->GetGuild(GuildLv() + 1);
}
}
} while (next_guild_meta && exp > 0);
SaveToDB();
}
cs::SMGuildGainExp respmsg;
GuildMgr::Instance()->ForwardGuildSMMsg(hdr.socket_handle,
forward_msg->context(),
respmsg);
}
void Guild::_CMGuildRefuse(f8::MsgHdr& hdr, const cs::CMGuildRefuse& msg)
{
ss::SS_IM_ForwardGuildCMMsg *forward_msg = (ss::SS_IM_ForwardGuildCMMsg*)hdr.user_data;
cs::SMGuildRefuse respmsg;
GuildMember* sender = GetMember(forward_msg->context().user_info().base_data().account_id());
if (!sender) {
SendErrorMsg(hdr.socket_handle, forward_msg->context(), TEXT("server_internal_error", "服务器内部错误"));
respmsg.set_errcode(2);
respmsg.set_errmsg(TEXT("server_internal_error", "服务器内部错误"));
GuildMgr::Instance()->ForwardGuildSMMsg(hdr.socket_handle,
forward_msg->context(),
respmsg);
return;
}
if (!(
GetMemberJob(sender->account_id) == kGuildOwner ||
GetMemberJob(sender->account_id) == kGuildAdmin)
) {
SendErrorMsg(hdr.socket_handle, forward_msg->context(), TEXT("permission_denied", "权限不够"));
respmsg.set_errcode(3);
respmsg.set_errmsg(TEXT("permission_denied", "权限不够"));
GuildMgr::Instance()->ForwardGuildSMMsg(hdr.socket_handle,
forward_msg->context(),
respmsg);
return;
}
GuildMgr::Instance()->ForwardGuildSMMsg(hdr.socket_handle,
forward_msg->context(),
respmsg);
DBHelper::Instance()->SetGuildApplyStatus
(
msg.apply().base_data().account_id(),
guild_id_,
kGuildApplyReject
);
ClearApplyByIdx(msg.apply().idx());
GameLog::Instance()->GuildRefuse(this,
sender,
msg.apply().idx(),
msg.apply().base_data().account_id());
SyncHelper::Instance()->SyncGuildRefuse(this,
msg.apply().base_data().account_id()
);
}
void Guild::_CMGuildKick(f8::MsgHdr& hdr, const cs::CMGuildKick& msg)
{
ss::SS_IM_ForwardGuildCMMsg *forward_msg = (ss::SS_IM_ForwardGuildCMMsg*)hdr.user_data;
cs::SMGuildKick respmsg;
GuildMember* sender = GetMember(forward_msg->context().user_info().base_data().account_id());
if (!sender) {
SendErrorMsg(hdr.socket_handle, forward_msg->context(), TEXT("server_internal_error", "服务器内部错误"));
respmsg.set_errcode(2);
respmsg.set_errmsg(TEXT("server_internal_error", "服务器内部错误"));
GuildMgr::Instance()->ForwardGuildSMMsg(hdr.socket_handle,
forward_msg->context(),
respmsg);
return;
}
if (!(
GetMemberJob(sender->account_id) == kGuildOwner ||
GetMemberJob(sender->account_id) == kGuildAdmin)
) {
SendErrorMsg(hdr.socket_handle, forward_msg->context(), TEXT("permission_denied", "权限不够"));
respmsg.set_errcode(3);
respmsg.set_errmsg(TEXT("permission_denied", "权限不够"));
GuildMgr::Instance()->ForwardGuildSMMsg(hdr.socket_handle,
forward_msg->context(),
respmsg);
return;
}
GuildMember* member = GetMember(msg.account_id());
if (!member) {
GuildMgr::Instance()->ForwardGuildSMMsg(hdr.socket_handle,
forward_msg->context(),
respmsg);
return;
}
if (sender == member) {
SendErrorMsg(hdr.socket_handle, forward_msg->context(), TEXT("cant_kickout_self", "不能踢自己"));
respmsg.set_errcode(3);
respmsg.set_errmsg(TEXT("cant_kickout_self", "不能踢自己"));
GuildMgr::Instance()->ForwardGuildSMMsg(hdr.socket_handle,
forward_msg->context(),
respmsg);
return;
}
if (GetMemberJob(sender->account_id) != kGuildOwner) {
if (GetMemberJob(member->account_id) == kGuildOwner ||
GetMemberJob(member->account_id) == kGuildAdmin) {
SendErrorMsg(hdr.socket_handle, forward_msg->context(), TEXT("permission_denied", "权限不够"));
respmsg.set_errcode(3);
respmsg.set_errmsg(TEXT("permission_denied", "权限不够"));
GuildMgr::Instance()->ForwardGuildSMMsg(hdr.socket_handle,
forward_msg->context(),
respmsg);
return;
}
}
GuildMgr::Instance()->ForwardGuildSMMsg(hdr.socket_handle,
forward_msg->context(),
respmsg);
RemoveMember(sender->account_id,
member->account_id,
kGuildKick);
GameLog::Instance()->GuildKick(
this,
sender,
msg.account_id()
);
SaveToDB();
}
void Guild::_CMGuildQuit(f8::MsgHdr& hdr, const cs::CMGuildQuit& msg)
{
ss::SS_IM_ForwardGuildCMMsg *forward_msg = (ss::SS_IM_ForwardGuildCMMsg*)hdr.user_data;
cs::SMGuildQuit respmsg;
GuildMgr::Instance()->ForwardGuildSMMsg(hdr.socket_handle,
forward_msg->context(),
respmsg);
GuildMember* sender = GetMember(forward_msg->context().user_info().base_data().account_id());
if (sender) {
GameLog::Instance()->GuildQuit(this, sender);
std::string src_account_id = sender->account_id;
int src_job = GetMemberJob(sender->account_id);
RemoveMember(sender->account_id,
sender->account_id,
kGuildQuit);
if (src_job == kGuildOwner && GetJobMemberNum(kGuildOwner) < 1) {
if (member_hash_.empty()) {
guild_status_ = kGuildDismissed;
} else {
std::vector<int> jobs = {kGuildAdmin, kGuildElite, kGuildMember};
for (int job : jobs) {
std::set<std::string>* members = GetJobMembers(job);
if (members && !members->empty()) {
GuildMember* new_leader = ChooseLeader(members);
if (new_leader) {
member_job_hash_[new_leader->account_id] = kGuildOwner;
job_hash_[job].erase(new_leader->account_id);
job_hash_[kGuildOwner].insert(new_leader->account_id);
SyncHelper::Instance()->SyncGuildMemberUpdate
(
this,
new_leader,
kGuildUpdateReasonInherit
);
SetNewLeader(new_leader);
break;
}
}
}
}
}
SaveToDB();
} else {
SyncHelper::Instance()->SyncGuildMemberQuitOnlyOnline
(
this,
forward_msg->context().user_info().base_data().account_id(),
forward_msg->context().user_info().base_data().account_id(),
kGuildUpdate
);
}
}
void Guild::_CMGuildChange(f8::MsgHdr& hdr, const cs::CMGuildChange& msg)
{
cs::SMGuildChange respmsg;
ss::SS_IM_ForwardGuildCMMsg *forward_msg = (ss::SS_IM_ForwardGuildCMMsg*)hdr.user_data;
GuildMember* sender = GetMember(forward_msg->context().user_info().base_data().account_id());
if (!sender) {
SendErrorMsg(hdr.socket_handle, forward_msg->context(), TEXT("server_internal_error", "服务器内部错误"));
respmsg.set_errcode(2);
respmsg.set_errmsg(TEXT("server_internal_error", "服务器内部错误"));
GuildMgr::Instance()->ForwardGuildSMMsg(hdr.socket_handle,
forward_msg->context(),
respmsg);
return;
}
if (!(
GetMemberJob(sender->account_id) == kGuildOwner ||
GetMemberJob(sender->account_id) == kGuildAdmin
)) {
SendErrorMsg(hdr.socket_handle, forward_msg->context(), TEXT("permission_denied", "权限不够"));
respmsg.set_errcode(3);
respmsg.set_errmsg(TEXT("permission_denied", "权限不够"));
GuildMgr::Instance()->ForwardGuildSMMsg(hdr.socket_handle,
forward_msg->context(),
respmsg);
return;
}
if ((!msg.has_guild_name() || msg.guild_name() == guild_name_) &&
(!msg.has_guild_declaration() || msg.guild_declaration() == guild_declaration_)) {
if (msg.has_guild_badge()) {
guild_badge_ = msg.guild_badge();
}
if (msg.has_join_unlimited()) {
join_unlimited_ = msg.join_unlimited();
}
if (msg.has_join_cond1()) {
join_cond1_ = msg.join_cond1();
}
if (msg.has_join_cond2()) {
join_cond2_ = msg.join_cond2();
}
FillGuildBasic(respmsg.mutable_info());
GuildMgr::Instance()->ForwardGuildSMMsg(hdr.socket_handle,
forward_msg->context(),
respmsg);
MarkDirty();
return;
}
ss::SS_IM_ForwardGuildCMMsg *forward_msg_copy = new ss::SS_IM_ForwardGuildCMMsg;
*forward_msg_copy = *forward_msg;
cs::CMGuildChange* msg_copy = new cs::CMGuildChange;
*msg_copy = msg;
std::string ip;
int port = 0;
JsonDataMgr::Instance()->GetRankServerConf(ip, port);
a8::MutableXObject* params = a8::MutableXObject::NewObject();
params->SetVal("account_id", forward_msg->context().user_info().base_data().account_id());
params->SetVal("guild_id", guild_id_);
if (msg.has_guild_name()) {
params->SetVal("guild_name", msg.guild_name());
} else {
params->SetVal("guild_name", guild_name_);
}
if (msg.has_guild_declaration()) {
params->SetVal("guild_declaration", msg.guild_declaration());
} else {
params->SetVal("guild_declaration", guild_declaration_);
}
f8::HttpClientPool::Instance()->HttpGet
(
a8::XParams()
.SetSender(guild_id_)
.SetParam1(forward_msg_copy)
.SetParam2(hdr.socket_handle)
.SetParam3(msg_copy),
[] (a8::XParams& param, a8::XObject& data)
{
ss::SS_IM_ForwardGuildCMMsg *forward_msg_copy = (ss::SS_IM_ForwardGuildCMMsg*)param.param1.GetUserData();
cs::CMGuildChange* msg_copy = (cs::CMGuildChange*)param.param3.GetUserData();
Guild* guild = GuildMgr::Instance()->GetGuild(param.sender);
if (guild && data.GetType() == a8::XOT_OBJECT) {
if (data.HasKey("errcode") && data.At("errcode")->AsXValue().GetInt() == 0) {
guild->GuildRenameCb(param.param2, forward_msg_copy->context(), *msg_copy);
} else {
guild->SendErrorMsg(param.param2,
forward_msg_copy->context(),
data.Get("errmsg", TEXT("server_internal_error", "服务器内部错误")));
}
}
delete msg_copy;
delete forward_msg_copy;
},
[] (a8::XParams& param, const std::string& response)
{
ss::SS_IM_ForwardGuildCMMsg *forward_msg_copy = (ss::SS_IM_ForwardGuildCMMsg*)param.param1.GetUserData();
cs::CMGuildChange* msg_copy = (cs::CMGuildChange*)param.param3.GetUserData();
Guild* guild = GuildMgr::Instance()->GetGuild(param.sender);
if (guild) {
guild->SendErrorMsg(param.param2, forward_msg_copy->context(), TEXT("server_internal_error", "服务器内部错误"));
}
delete msg_copy;
delete forward_msg_copy;
},
a8::Format("http://%s:%d/webapp/index.php?c=Guild&a=rename", {ip, port}).c_str(),
*params,
GuildId()
);
delete params;
}
void Guild::_CMGuildMemberList(f8::MsgHdr& hdr, const cs::CMGuildMemberList& msg)
{
ss::SS_IM_ForwardGuildCMMsg *forward_msg = (ss::SS_IM_ForwardGuildCMMsg*)hdr.user_data;
cs::SMGuildMemberList respmsg;
respmsg.set_guild_lv(guild_lv_);
*respmsg.mutable_paging() = msg.paging();
if (respmsg.paging().page_size() <= 0) {
respmsg.mutable_paging()->set_page_size(100);
}
int total_count = 0;
{
for (size_t i = respmsg.paging().curr_page() * respmsg.paging().page_size();
i < sorted_members_.size();
++i) {
GuildMember* member = sorted_members_[i];
if (!msg.member_name().empty() &&
member->nickname.find(msg.member_name()) == std::string::npos) {
continue;
}
++total_count;
}
}
AdjustPaging(respmsg.mutable_paging(), total_count);
for (size_t i = respmsg.paging().curr_page() * respmsg.paging().page_size();
i < sorted_members_.size();
++i) {
GuildMember* member = sorted_members_[i];
if (!msg.member_name().empty() &&
member->nickname.find(msg.member_name()) == std::string::npos) {
continue;
}
if (respmsg.member_list().size() >= respmsg.paging().page_size()) {
break;
}
auto p = respmsg.add_member_list();
TypeConvert::Convert(guild_id_,
GetMemberJob(member->account_id),
*member,
*(p->mutable_base_data()));
TypeConvert::Convert(member->temp_custom_data, *p->mutable_temp_custom_data());
if (member->account_id == forward_msg->context().user_info().base_data().account_id()) {
member->online = 1;
member->last_update_time = App::Instance()->nowtime;
}
}
GuildMgr::Instance()->ForwardGuildSMMsg(hdr.socket_handle,
forward_msg->context(),
respmsg);
}
void Guild::_CMGuildApplyList(f8::MsgHdr& hdr, const cs::CMGuildApplyList& msg)
{
auto on_ok =
[] (a8::XParams& param, const f8::DataSet* data_set)
{
cs::MFPaging* paging = (cs::MFPaging*)param.param2.GetUserData();
ss::SS_IM_ForwardGuildCMMsg* forward_msg = (ss::SS_IM_ForwardGuildCMMsg*)
param.param3.GetUserData();
Guild* guild = GuildMgr::Instance()->GetGuild(param.sender);
if (guild) {
for (auto& row : *data_set) {
GuildApply* apply = new GuildApply;
apply->idx = a8::XValue(row[0]);
apply->applyid = a8::XValue(row[1]);
apply->guild_id = a8::XValue(row[2]);
apply->base_data.account_id = row[3];
apply->base_data.nickname = row[4];
apply->base_data.avatar_url = row[5];
apply->base_data.sex = a8::XValue(row[6]);
apply->base_data.base_data_version = a8::XValue(row[7]);
apply->base_data.user_value1 = a8::XValue(row[8]);
apply->base_data.user_value2 = a8::XValue(row[9]);
apply->base_data.user_value3 = a8::XValue(row[10]);
apply->base_data.last_login_time = a8::XValue(row[12]);
apply->base_data.vip_lv = a8::XValue(row[13]);
apply->base_data.head = a8::XValue(row[14]);
guild->apply_hash_[apply->idx] = apply;
if (apply->idx > guild->last_apply_idx_) {
guild->last_apply_idx_ = apply->idx;
}
}
cs::SMGuildApplyList respmsg;
respmsg.set_guild_lv(guild->GuildLv());
guild->FillApplyList(forward_msg->context().user_info().base_data().account_id(),
*paging,
respmsg);
GuildMgr::Instance()->ForwardGuildSMMsg(param.param1,
forward_msg->context(),
respmsg);
}
delete forward_msg;
delete paging;
};
auto on_error =
[] (a8::XParams& param, int error_code, const std::string& error_msg)
{
cs::MFPaging* paging = (cs::MFPaging*)param.param2.GetUserData();
ss::SS_IM_ForwardGuildCMMsg* forward_msg = (ss::SS_IM_ForwardGuildCMMsg*)
param.param3.GetUserData();
cs::SMGuildApplyList respmsg;
GuildMgr::Instance()->ForwardGuildSMMsg(param.param1,
forward_msg->context(),
respmsg);
delete forward_msg;
delete paging;
};
ss::SS_IM_ForwardGuildCMMsg* forward_msg = (ss::SS_IM_ForwardGuildCMMsg*)hdr.user_data;
ss::SS_IM_ForwardGuildCMMsg* forward_msg_copy = new ss::SS_IM_ForwardGuildCMMsg();
*forward_msg_copy = *forward_msg;
cs::MFPaging* paging_copy = new cs::MFPaging;
*paging_copy = msg.paging();
paging_copy->set_curr_page(0);
paging_copy->set_page_size(20);
a8::XObject conn_info = DBEngine::Instance()->GetConnInfo(guild_id_);
std::string fmtstr = "SELECT '' AS account_id";
std::vector<a8::XValue> sql_params;
{
sql_params.push_back(a8::XValue(last_apply_idx_));
sql_params.push_back(a8::XValue(guild_id_));
}
DBEngine::Instance()->ExecAsyncQuery
(
conn_info,
(
"SELECT A.idx, A.applyid, A.guild_id, A.sender_id, A.sender_nickname, "
" A.sender_avatar_url, A.sender_sex, A.sender_data_version1, "
" A.sender_user_value1, A.sender_user_value2, A.sender_user_value3, A.status, A.createtime, "
" A.sender_vip_lv, A.sender_head "
"FROM guild_apply A "
" LEFT JOIN (" + fmtstr + ") AS B ON B.account_id = A.sender_id "
"WHERE A.idx > %d AND A.guild_id='%s' AND A.status=0 AND "
" B.account_id IS NULL;"
).c_str(),
sql_params,
a8::XParams()
.SetSender(guild_id_)
.SetParam1(hdr.socket_handle)
.SetParam2(paging_copy)
.SetParam3(forward_msg_copy),
on_ok,
on_error,
guild_id_
);
}
void Guild::_CMGuildLog(f8::MsgHdr& hdr, const cs::CMGuildLog& msg)
{
cs::SMGuildLog respmsg;
*respmsg.mutable_paging() = msg.paging();
if (respmsg.paging().page_size() <= 0) {
respmsg.mutable_paging()->set_page_size(10);
}
AdjustPaging(respmsg.mutable_paging(), logdb_->logs().size());
for (int i = respmsg.paging().curr_page() * respmsg.paging().page_size();
i < logdb_->logs().size();
++i) {
#if 0
if (respmsg.member_list().size() >= respmsg.paging().page_size()) {
break;
}
auto p = respmsg.add_member_list();
TypeConvert::Convert(*sorted_members_[i], *p);
#endif
}
}
void Guild::_CMGuildMemberSetJob(f8::MsgHdr& hdr, const cs::CMGuildMemberSetJob& msg)
{
ss::SS_IM_ForwardGuildCMMsg *forward_msg = (ss::SS_IM_ForwardGuildCMMsg*)hdr.user_data;
cs::SMGuildMemberSetJob respmsg;
if (!IsValidGuildJob(msg.job())) {
SendErrorMsg(hdr.socket_handle, forward_msg->context(), TEXT("parameter_error", "参数错误"));
respmsg.set_errcode(2);
respmsg.set_errmsg(TEXT("parameter_error", "参数错误"));
GuildMgr::Instance()->ForwardGuildSMMsg(hdr.socket_handle,
forward_msg->context(),
respmsg);
return;
}
GuildMember* sender = GetMember(forward_msg->context().user_info().base_data().account_id());
if (!sender) {
SendErrorMsg(hdr.socket_handle, forward_msg->context(), TEXT("server_internal_error", "服务器内部错误"));
respmsg.set_errcode(3);
respmsg.set_errmsg(TEXT("permission_denied", "权限不够"));
GuildMgr::Instance()->ForwardGuildSMMsg(hdr.socket_handle,
forward_msg->context(),
respmsg);
return;
}
if (GetMemberJob(sender->account_id) != kGuildOwner) {
SendErrorMsg(hdr.socket_handle, forward_msg->context(), TEXT("permission_denied", "权限不够"));
respmsg.set_errcode(3);
respmsg.set_errmsg(TEXT("permission_denied", "权限不够"));
GuildMgr::Instance()->ForwardGuildSMMsg(hdr.socket_handle,
forward_msg->context(),
respmsg);
return;
}
GuildMember* member = GetMember(msg.member_id());
if (!member) {
SendErrorMsg(hdr.socket_handle, forward_msg->context(), TEXT("parameter_error", "参数错误"));
respmsg.set_errcode(3);
respmsg.set_errmsg(TEXT("parameter_error", "参数错误"));
GuildMgr::Instance()->ForwardGuildSMMsg(hdr.socket_handle,
forward_msg->context(),
respmsg);
return;
}
if (sender == member) {
SendErrorMsg(hdr.socket_handle, forward_msg->context(), TEXT("cant_setjob_self", "不能给自己任职"));
respmsg.set_errcode(3);
respmsg.set_errmsg(TEXT("cant_setjob_self", "不能给自己任职"));
GuildMgr::Instance()->ForwardGuildSMMsg(hdr.socket_handle,
forward_msg->context(),
respmsg);
return;
}
if (GetMemberJob(member->account_id) == msg.job()) {
GuildMgr::Instance()->ForwardGuildSMMsg(hdr.socket_handle,
forward_msg->context(),
respmsg);
return;
}
if (msg.job() == kGuildAdmin) {
if (GetJobMemberNum(msg.job()) >= GUILD_MAX_ADMIN_NUM) {
SendErrorMsg(hdr.socket_handle, forward_msg->context(), TEXT("guild_admin_upper_limit", "副队长数量已达上限"));
respmsg.set_errcode(3);
respmsg.set_errmsg(TEXT("guild_admin_upper_limit", "副队长数量已达上限"));
GuildMgr::Instance()->ForwardGuildSMMsg(hdr.socket_handle,
forward_msg->context(),
respmsg);
return;
}
}
ForceSetJob(member, msg.job());
GuildMgr::Instance()->ForwardGuildSMMsg(hdr.socket_handle,
forward_msg->context(),
respmsg);
SaveToDB();
}
void Guild::_CMGuildAgreeInvite(f8::MsgHdr& hdr, const cs::CMGuildAgreeInvite& msg)
{
ss::SS_IM_ForwardGuildCMMsg *forward_msg = (ss::SS_IM_ForwardGuildCMMsg*)hdr.user_data;
cs::SMGuildAgreeInvite respmsg;
GuildMember* member = GetMember(forward_msg->context().user_info().base_data().account_id());
if (member) {
GuildMgr::Instance()->ForwardGuildSMMsg(hdr.socket_handle,
forward_msg->context(),
respmsg);
return;
}
if (IsFull()) {
SendErrorMsg(hdr.socket_handle, forward_msg->context(), TEXT("guild_member_upper_limit", "战队人数已达上限"));
respmsg.set_errcode(1);
respmsg.set_errmsg(TEXT("guild_member_upper_limit", "战队人数已达上限"));
GuildMgr::Instance()->ForwardGuildSMMsg(hdr.socket_handle,
forward_msg->context(),
respmsg);
return;
}
GuildMgr::Instance()->ForwardGuildSMMsg(hdr.socket_handle,
forward_msg->context(),
respmsg);
member = new GuildMember();
TypeConvert::Convert(forward_msg->context().user_info().base_data(), *member);
AddMember(member);
member_job_hash_[member->account_id] = kGuildMember;
std::set<std::string>* members = GetJobMembers(kGuildMember);
members->insert(member->account_id);
SyncHelper::Instance()->SyncGuildMemberUpdate(this, member, kGuildUpdateReasonAgree);
DBHelper::Instance()->SetGuildApplyStatus
(
forward_msg->context().user_info().base_data().account_id(),
guild_id_,
kGuildApplyAgree
);
ClearApplyBySenderId(forward_msg->context().user_info().base_data().account_id());
GameLog::Instance()->GuildAgreeInvite(this, member);
SaveToDB();
}
int Guild::GetMemberJob(const std::string& account_id)
{
auto itr = member_job_hash_.find(account_id);
int job = itr != member_job_hash_.end() ? itr->second : kGuildMember;
if (job < kGuildMember ||
job > kGuildJobMax) {
return kGuildMember;
} else {
return job;
}
}
std::set<std::string>* Guild::GetJobMembers(int job)
{
if (!IsValidGuildJob(job)) {
return nullptr;
}
return &job_hash_[job];
}
void Guild::UpdateMemberInfo(const cs::MFUserInfo& user_info)
{
GuildMember* member = GetMember(user_info.base_data().account_id());
if (member) {
member->nickname = user_info.base_data().nickname();
member->avatar_url = user_info.base_data().avatar_url();
member->sex = user_info.base_data().sex();
member->vip_lv = user_info.base_data().vip_lv();
member->head = user_info.base_data().head();
member->last_login_time = user_info.base_data().last_login_time();
member->user_value1 = user_info.base_data().user_value1();
member->user_value2 = user_info.base_data().user_value2();
member->user_value3 = user_info.base_data().user_value3();
member->data_version1 = user_info.base_data().base_data_version();
member->online = user_info.base_data()._online();
TypeConvert::Convert(user_info.temp_custom_data(), member->temp_custom_data);
member->last_update_time = App::Instance()->nowtime;
if (GetMemberJob(member->account_id) != user_info.base_data().guild_job()) {
SyncHelper::Instance()->SyncGuildMemberUpdateOnlyOnline(this, member, kGuildUpdateReasonUpdate);
}
if (member->account_id == owner_id_) {
owner_name_ = member->nickname;
owner_avatar_url_ = member->avatar_url;
owner_vip_lv_ = member->vip_lv;
owner_head_ = member->head;
owner_sex_ = member->sex;
}
} else {
SyncHelper::Instance()->SyncGuildMemberQuitOnlyOnline
(
this,
user_info.base_data().account_id(),
user_info.base_data().account_id(),
kGuildUpdate
);
}
}
void Guild::UpdateMemberOnline(const std::string& account_id)
{
GuildMember* member = GetMember(account_id);
if (member) {
member->online = 1;
member->last_update_time = App::Instance()->nowtime;
}
}
void Guild::UpdateMemberOffline(const std::string& account_id)
{
GuildMember* member = GetMember(account_id);
if (member) {
member->online = 0;
member->last_update_time = App::Instance()->nowtime;
}
}
void Guild::Active()
{
last_active_time_ = App::Instance()->nowtime;
if (App::Instance()->nowtime - last_query_member_time_ > 15) {
QueryMemberOnlineState();
last_query_member_time_ = App::Instance()->nowtime;
}
}
bool Guild::CheckRedPoint()
{
if (has_red_point_) {
return true;
}
if (App::Instance()->nowtime - last_check_red_point_time_ < 15) {
return true;
}
RecalcRedPoint();
return false;
}
bool Guild::HasApply()
{
return has_red_point_;
}
void Guild::SyncNewApply()
{
std::vector<int> jobs = {kGuildOwner, kGuildAdmin};
for (int job : jobs) {
std::set<std::string>* members = GetJobMembers(job);
if (members) {
for (const std::string& member_id : *members) {
ss::SS_GS_PushGuildRedPoint respmsg;
respmsg.set_account_id(member_id);
respmsg.set_has_apply(1);
GuildMgr::Instance()->SendMsg(0, respmsg);
}
}
}
}
void Guild::TraverseMember(std::function<void (GuildMember*)> callback)
{
for (auto& pair : member_hash_) {
callback(pair.second);
}
}
int Guild::GetJobMemberNum(int job)
{
std::set<std::string>* members = GetJobMembers(job);
return members ? members->size() : 0;
}
void Guild::FillGuildBasic(cs::MFGuildBasic* guild_basic)
{
guild_basic->set__gameid(gameid_);
guild_basic->set__channel(channel_);
guild_basic->set_guild_id(guild_id_);
guild_basic->set_guild_name(guild_name_);
guild_basic->set_guild_lv(guild_lv_);
guild_basic->set_guild_exp(guild_exp_);
guild_basic->set_guild_badge(guild_badge_);
guild_basic->set_member_num(member_hash_.size());
guild_basic->set_guild_declaration(guild_declaration_);
guild_basic->set_owner_id(owner_id_);
guild_basic->set_owner_name(owner_name_);
guild_basic->set_owner_avatar_url(owner_avatar_url_);
guild_basic->set_owner_vip_lv(owner_vip_lv_);
guild_basic->set_owner_head(owner_head_);
guild_basic->set_owner_sex(owner_sex_);
guild_basic->set_join_unlimited(join_unlimited_);
guild_basic->set_join_cond1(join_cond1_);
guild_basic->set_join_cond2(join_cond2_);
}
void Guild::FillGuildDB(ss::MFGuildDB& guild_pb)
{
for (auto& pair : member_hash_) {
auto p = guild_pb.add_members();
TypeConvert::Convert(guild_id_,
GetMemberJob(pair.second->account_id),
*pair.second,
*p->mutable_base_data());
}
}
void Guild::SerializeMembers(std::string& guild_members)
{
a8::MutableXObject* members_xobj = a8::MutableXObject::NewArray();
for (auto& pair : member_hash_) {
a8::MutableXObject* member_xobj = a8::MutableXObject::NewObject();
member_xobj->SetVal("account_id", pair.second->account_id);
member_xobj->SetVal("guild_job", GetMemberJob(pair.second->account_id));
members_xobj->Push(*member_xobj);
delete member_xobj;
}
members_xobj->ToJsonStr(guild_members);
delete members_xobj;
}
void Guild::SaveToDB()
{
std::string guild_data;
std::string guild_log;
std::string guild_members;
{
ss::MFGuildDB guild_db;
FillGuildDB(guild_db);
guild_db.SerializeToString(&guild_data);
}
{
logdb_->SerializeToString(&guild_log);
SerializeMembers(guild_members);
}
auto on_ok =
[] (a8::XParams& param, const f8::DataSet* data_set)
{
Guild* guild = GuildMgr::Instance()->GetGuild(param.sender);
if (guild) {
guild->last_saveok_time_ = App::Instance()->nowtime;
}
};
auto on_error =
[] (a8::XParams& param, int error_code, const std::string& error_msg)
{
};
a8::XObject conn_info = DBEngine::Instance()->GetConnInfo(guild_id_);
DBEngine::Instance()->ExecAsyncScript
(
conn_info,
"UPDATE `guild` SET guild_lv=%d, guild_exp=%d, guild_badge=%d, "
" guild_apply_num=%d, guild_members='%s', guild_notice='%s', guild_declaration='%s', "
" guild_log='%s', owner_id='%s', owner_name='%s', owner_avatar_url='%s', "
" creator_id='%s', creator_name='%s', creator_avatar_url='%s', guild_data='%s', "
" guild_status='%d', join_unlimited=%d, join_cond1=%d, join_cond2=%d, guild_member_num=%d, "
" modifytime=%d, name_ext2=%d, "
" owner_vip_lv=%d, owner_head=%d, "
" owner_sex=%d, creator_sex=%d "
"WHERE guild_id=%d;",
{
guild_lv_,
guild_exp_,
guild_badge_,
guild_apply_num_,
guild_members,
guild_notice_,
guild_declaration_,
guild_log,
owner_id_,
owner_name_,
owner_avatar_url_,
creator_id_,
creator_name_,
creator_avatar_url_,
guild_data,
guild_status_,
join_unlimited_,
join_cond1_,
join_cond2_,
member_hash_.size(),
App::Instance()->nowtime,
owner_vip_lv_,
owner_head_,
guild_status_ == kGuildDismissed ? GuildId() : 0,
owner_sex_,
creator_sex_,
guild_id_
},
a8::XParams()
.SetSender(GuildId()),
on_ok,
on_error,
guild_id_
);
}
void Guild::GenSortedMembers()
{
sorted_members_.clear();
for (auto& pair : member_hash_) {
sorted_members_.push_back(pair.second);
}
}
int Guild::GetMemberNum()
{
return member_hash_.size();
}
void Guild::FillApplyList(const std::string& account_id, cs::MFPaging& paging, cs::SMGuildApplyList& respmsg)
{
RemoveHandledApply();
int i = 0;
int start = paging.curr_page() * paging.page_size();
for (auto& pair : apply_hash_) {
if (i >= start && i < start + paging.page_size()) {
if (pair.second->flag == 1) {
continue;
}
auto apply_pb = respmsg.add_apply_list();
TypeConvert::Convert(*pair.second, *apply_pb);
{
int target_channel = f8::ExtractChannelIdFromAccountId
(apply_pb->base_data().account_id());
int channel = f8::ExtractChannelIdFromAccountId(account_id);
App::Instance()->PreProcAvatarUrl
(channel,
target_channel,
*apply_pb->mutable_base_data()->mutable_avatar_url());
}
}
++i;
}
*respmsg.mutable_paging() = paging;
if (paging.page_size() > 0) {
respmsg.mutable_paging()->set__total_page(ceil(i / paging.page_size()));
} else {
respmsg.mutable_paging()->set__total_page(1);
}
}
void Guild::ClearApplyBySenderId(const std::string& sender_id)
{
std::vector<long long> deleted_applys;
for (auto& pair : apply_hash_) {
if (pair.second->base_data.account_id == sender_id) {
deleted_applys.push_back(pair.first);
}
}
for (auto idx : deleted_applys) {
ClearApplyByIdx(idx);
}
}
void Guild::ClearApplyByIdx(long long idx)
{
auto itr = apply_hash_.find(idx);
if (itr != apply_hash_.end()) {
delete itr->second;
apply_hash_.erase(itr);
}
}
Guild* Guild::CreateGuild(int gameid,
long long guild_id,
const std::string& guild_name,
int guild_lv,
int guild_exp,
int guild_badge,
int guild_apply_num,
const std::string& guild_members,
const std::string& guild_notice,
const std::string& guild_declaration,
const std::string& guild_log,
const std::string& owner_id,
const std::string& owner_name,
const std::string& owner_avatar_url,
const std::string& creator_id,
const std::string& creator_name,
const std::string& creator_avatar_url,
const std::string& guild_data,
int guild_status,
int join_unlimited,
int join_cond1,
int join_cond2,
int createtime,
int channel,
int owner_vip_lv,
int owner_head,
int creator_vip_lv,
int creator_head,
int owner_sex,
int creator_sex
)
{
if (GuildMgr::Instance()->GetGuild(guild_id)) {
abort();
}
Guild* guild = new Guild;
guild->Init();
guild->gameid_ = gameid;
guild->channel_ = channel;
guild->guild_id_ = guild_id;
guild->guild_name_ = guild_name;
guild->guild_lv_ = guild_lv;
guild->guild_exp_ = guild_exp;
guild->guild_badge_ = guild_badge;
guild->guild_apply_num_ = guild_apply_num;
guild->guild_notice_ = guild_notice;
guild->guild_declaration_ = guild_declaration;
guild->owner_id_ = owner_id;
guild->owner_name_ = owner_name;
guild->owner_avatar_url_ = owner_avatar_url;
guild->owner_vip_lv_ = owner_vip_lv;
guild->owner_head_ = owner_head;
guild->owner_sex_ = owner_sex;
guild->creator_id_ = creator_id;
guild->creator_name_ = creator_name;
guild->creator_avatar_url_ = creator_avatar_url;
guild->creator_vip_lv_ = creator_vip_lv;
guild->creator_head_ = creator_head;
guild->creator_sex_ = creator_sex;
guild->guild_status_ = guild_status;
guild->join_unlimited_ = join_unlimited;
guild->join_cond1_ = join_cond1;
guild->join_cond2_ = join_cond2;
guild->createtime_ = createtime;
guild->Deserialize(guild_data, guild_members, guild_log);
return guild;
}
void Guild::SendErrorMsg(int socket_handle, const ss::MFIMMsgConext& context, const std::string& errmsg)
{
cs::SMShowErrorMsg notifymsg;
notifymsg.set_msg(errmsg);
GuildMgr::Instance()->ForwardGuildSMMsg(socket_handle,
context,
notifymsg);
}
void Guild::QueryMemberOnlineState()
{
ss::SS_GS_QueryGuildUserOnlineState msg;
msg.set_seqid(App::Instance()->NewUUID());
msg.set_guild_id(GuildId());
for (auto& pair : member_hash_) {
GuildMember* member = pair.second;
if (App::Instance()->nowtime - member->last_update_time > 30) {
msg.add_account_ids(member->account_id);
}
}
GuildMgr::Instance()->SendMsg(0, msg);
}
void Guild::GenGuildData(Player* hum, long long guild_id, std::string& guild_data)
{
ss::MFGuildDB guild_db;
{
auto member = guild_db.add_members();
cs::MFUserInfo user_info;
hum->FillMFUserInfo(&user_info);
BaseUserData base_data;
TypeConvert::Convert(user_info.base_data(), base_data);
TypeConvert::Convert(base_data, *member->mutable_base_data());
member->mutable_base_data()->set_guild_job(kGuildOwner);
}
guild_db.SerializeToString(&guild_data);
}
GuildMember* Guild::ChooseLeader(std::set<std::string>* members)
{
GuildMember* leader = nullptr;
if (members && !members->empty()) {
for (const std::string& member_id : *members) {
leader = GetMember(member_id);
if (leader) {
break;
}
}
}
return leader;
}
void Guild::GuildRenameCb(int socket_handle, const ss::MFIMMsgConext& context, const cs::CMGuildChange& msg)
{
if (msg.has_guild_name()) {
guild_name_ = msg.guild_name();
}
if (msg.has_guild_badge()) {
guild_badge_ = msg.guild_badge();
}
if (msg.has_guild_declaration()) {
guild_declaration_ = msg.guild_declaration();
}
if (msg.has_join_unlimited()) {
join_unlimited_ = msg.join_unlimited();
}
if (msg.has_join_cond1()) {
join_cond1_ = msg.join_cond1();
}
if (msg.has_join_cond2()) {
join_cond2_ = msg.join_cond2();
}
cs::SMGuildChange respmsg;
FillGuildBasic(respmsg.mutable_info());
GuildMgr::Instance()->ForwardGuildSMMsg(socket_handle,
context,
respmsg);
MarkDirty();
}
void Guild::RemoveHandledApply()
{
std::vector<long long> handled_idxs;
for (auto& pair : apply_hash_) {
if (GetMember(pair.second->base_data.account_id)) {
handled_idxs.push_back(pair.first);
}
}
for (long long idx : handled_idxs) {
auto itr = apply_hash_.find(idx);
if (itr != apply_hash_.end()) {
auto& apply = itr->second;
DBHelper::Instance()->SetGuildApplyStatus
(
apply->base_data.account_id,
guild_id_,
kGuildApplyIgnore
);
delete itr->second;
apply_hash_.erase(itr);
}
}
CombineRepeatApply();
}
void Guild::CombineRepeatApply()
{
std::map<std::string, std::vector<GuildApply*>> num_hash;
for (auto& pair : apply_hash_) {
auto itr = num_hash.find(pair.second->base_data.account_id);
if (itr != num_hash.end()) {
itr->second.push_back(pair.second);
} else {
num_hash[pair.second->base_data.account_id] = std::vector<GuildApply*>({pair.second});
}
}
for (auto& pair : num_hash) {
for (size_t i = 0; i + 1 < pair.second.size(); ++i) {
pair.second[i]->flag = 1;
}
}
}
void Guild::GuildAgreeCb(int socket_handle, const ss::MFIMMsgConext& context, const cs::CMGuildAgree& msg)
{
cs::SMGuildAgree respmsg;
GuildMember* member = GetMember(msg.apply().base_data().account_id());
if (member) {
SyncHelper::Instance()->SyncGuildMemberUpdateOnlyOnline(this, member, kGuildUpdateReasonAgree);
GuildMgr::Instance()->ForwardGuildSMMsg(socket_handle,
context,
respmsg);
DBHelper::Instance()->SetGuildApplyStatus
(
msg.apply().base_data().account_id(),
guild_id_,
kGuildApplyAgree
);
ClearApplyBySenderId(msg.apply().base_data().account_id());
return;
}
if (IsFull()) {
SendErrorMsg(socket_handle, context, TEXT("guild_member_upper_limit", "战队人数已达上限"));
respmsg.set_errcode(1);
respmsg.set_errmsg(TEXT("guild_member_upper_limit", "战队人数已达上限"));
GuildMgr::Instance()->ForwardGuildSMMsg(socket_handle,
context,
respmsg);
return;
}
GuildMember* sender = GetMember(context.user_info().base_data().account_id());
if (!sender) {
SendErrorMsg(socket_handle, context, TEXT("server_internal_error", "服务器内部错误"));
respmsg.set_errcode(2);
respmsg.set_errmsg(TEXT("server_internal_error", "服务器内部错误"));
GuildMgr::Instance()->ForwardGuildSMMsg(socket_handle,
context,
respmsg);
return;
}
if (!(
GetMemberJob(sender->account_id) == kGuildOwner ||
GetMemberJob(sender->account_id) == kGuildAdmin)
) {
SendErrorMsg(socket_handle, context, TEXT("permission_denied", "权限不够"));
respmsg.set_errcode(3);
respmsg.set_errmsg(TEXT("permission_denied", "权限不够"));
GuildMgr::Instance()->ForwardGuildSMMsg(socket_handle,
context,
respmsg);
return;
}
GuildMgr::Instance()->ForwardGuildSMMsg(socket_handle,
context,
respmsg);
member = new GuildMember();
TypeConvert::Convert(msg.apply().base_data(), *member);
AddMember(member);
member_job_hash_[member->account_id] = kGuildMember;
std::set<std::string>* members = GetJobMembers(kGuildMember);
members->insert(member->account_id);
DBHelper::Instance()->SetGuildApplyStatus
(
msg.apply().base_data().account_id(),
guild_id_,
kGuildApplyAgree
);
ClearApplyBySenderId(msg.apply().base_data().account_id());
SaveToDB();
DBHelper::Instance()->UpdateUserGuild(member->account_id,
GuildId(),
GetMemberJob(member->account_id)
);
for (int i = 0; i < 3; ++i) {
a8::Timer::Instance()->AddDeadLineTimerAndAttach
(
1000 * i,
a8::XParams()
.SetSender(this)
.SetParam1(member->account_id),
[] (const a8::XParams& param)
{
Guild* guild = (Guild*)param.sender.GetUserData();
std::string member_id = param.param1.GetString();
GuildMember* member = guild->GetMember(member_id);
if (member) {
SyncHelper::Instance()->SyncGuildMemberUpdateOnlyOnline
(guild,
member,
kGuildUpdateReasonAgree);
}
},
&timer_attacher_.timer_list_,
[] (const a8::XParams& param)
{
});
}
GameLog::Instance()->GuildAgree(
this,
sender,
msg.apply().idx(),
msg.apply().base_data().account_id()
);
}
void Guild::RecalcRedPoint()
{
last_check_red_point_time_ = App::Instance()->nowtime;
{
auto on_ok =
[] (a8::XParams& param, const f8::DataSet* data_set)
{
if (data_set && !data_set->empty()) {
Guild* guild = GuildMgr::Instance()->GetGuild(param.sender);
if (guild) {
guild->has_red_point_ = 1;
}
}
};
auto on_error =
[] (a8::XParams& param, int error_code, const std::string& error_msg)
{
};
a8::XObject conn_info = DBEngine::Instance()->GetConnInfo(GuildId());
DBEngine::Instance()->ExecAsyncQuery
(
conn_info,
"SELECT idx, applyid "
"FROM guild_apply "
"WHERE guild_id=%d AND idx > %d AND status=0 LIMIT 1;",
{
GuildId(),
0
},
a8::XParams()
.SetSender(GuildId()),
on_ok,
on_error,
GuildId()
);
}
{
a8::Timer::Instance()->AddDeadLineTimerAndAttach
(
1000 * 10,
a8::XParams()
.SetSender(this),
[] (const a8::XParams& param)
{
Guild* guild = (Guild*)param.sender.GetUserData();
guild->has_red_point_ = 0;
},
&timer_attacher_.timer_list_,
[] (const a8::XParams& param)
{
});
}
}
void Guild::SetNewLeader(GuildMember* member)
{
owner_id_ = member->account_id;
owner_name_ = member->nickname;
owner_avatar_url_ = member->avatar_url;
}
void Guild::ForceSetJob(GuildMember* member, int new_job)
{
if (!IsValidGuildJob(new_job)) {
return;
}
GuildMember* old_owner = GetMember(owner_id_);
if (!old_owner || GetMemberJob(owner_id_) != kGuildOwner) {
return;
}
if (old_owner == member) {
return;
}
int old_job = GetMemberJob(member->account_id);
switch (new_job) {
case kGuildOwner:
{
{
std::set<std::string>* members = GetJobMembers(kGuildOwner);
members->clear();
members->insert(member->account_id);
}
{
std::set<std::string>* members = GetJobMembers(kGuildMember);
members->insert(old_owner->account_id);
}
member_job_hash_[old_owner->account_id] = kGuildMember;
member_job_hash_[member->account_id] = kGuildOwner;
SyncHelper::Instance()->SyncGuildMemberUpdate(this, old_owner, kGuildUpdateReasonSetJob);
SetNewLeader(member);
}
break;
case kGuildAdmin:
{
if (GetJobMemberNum(new_job) >= GUILD_MAX_ADMIN_NUM) {
return;
}
std::set<std::string>* members = GetJobMembers(new_job);
members->insert(member->account_id);
member_job_hash_[member->account_id] = new_job;
}
break;
case kGuildElite:
case kGuildMember:
{
std::set<std::string>* members = GetJobMembers(new_job);
members->insert(member->account_id);
member_job_hash_[member->account_id] = new_job;
}
break;
default:
{
return;
}
break;
}
{
std::set<std::string>* members = GetJobMembers(old_job);
members->erase(member->account_id);
}
GameLog::Instance()->GuildSetJob(this, member, old_job);
SyncHelper::Instance()->SyncGuildMemberUpdate(this, member, kGuildUpdateReasonSetJob);
}