relation/server/rankserver/guildmgr.cc
aozhiwei dea0773c25 1
2020-10-13 19:40:31 +08:00

925 lines
32 KiB
C++

#include "precompile.h"
#include <a8/udplog.h>
#include <a8/timer.h>
#include "guildmgr.h"
#include "typeconvert.h"
#include "ss_proto.pb.h"
#include "cs_proto.pb.h"
#include "dbengine.h"
#include "app.h"
#include "jsondatamgr.h"
#include "IMListener.h"
#include "metamgr.h"
#include "framework/cpp/utils.h"
#include "framework/cpp/channel.h"
const size_t MAX_RANK_LIST_NUM = 50;
const size_t MAX_SORTED_LIST_NUM = 5000;
const char* const NAME_MAGIC_SYMBOL = "@";
const size_t MAX_GUILD_NAME_LEN = 10;
const size_t MAX_GUILD_DECLARATION_LEN = 30;
static bool RankCmpFunc(const cs::MFGuildBasic* a, const cs::MFGuildBasic* b)
{
if (a->guild_lv() > b->guild_lv()) {
return true;
}
if (a->guild_lv() < b->guild_lv()) {
return false;
}
if (a->guild_exp() > b->guild_exp()) {
return true;
}
if (a->guild_exp() < b->guild_exp()) {
return false;
}
if (a->member_num() > b->member_num()) {
return true;
}
if (a->member_num() < b->member_num()) {
return false;
}
return a->guild_id() > b->guild_id();
}
static bool SortedCmpFunc(const cs::MFGuildBasic* a, const cs::MFGuildBasic* b)
{
if (a->guild_lv() > b->guild_lv()) {
return true;
}
if (a->guild_lv() < b->guild_lv()) {
return false;
}
if (a->guild_exp() > b->guild_exp()) {
return true;
}
if (a->guild_exp() < b->guild_exp()) {
return false;
}
if (a->member_num() > b->member_num()) {
return true;
}
if (a->member_num() < b->member_num()) {
return false;
}
return a->guild_id() > b->guild_id();
}
void DbToGuildBasic(const std::vector<std::string>& row, cs::MFGuildBasic* guild)
{
guild->set_guild_id(a8::XValue(row[2]));
guild->set_guild_name(row[3]);
guild->set_guild_lv(a8::XValue(row[4]));
guild->set_guild_exp(a8::XValue(row[5]));
guild->set_guild_badge(a8::XValue(row[6]));
guild->set_guild_declaration(row[8]);
guild->set_owner_id(row[9]);
guild->set_owner_name(row[10]);
guild->set_owner_avatar_url(row[11]);
guild->set__guild_status(a8::XValue(row[12]));
guild->set_join_unlimited(a8::XValue(row[16]));
guild->set_join_cond1(a8::XValue(row[17]));
guild->set_join_cond2(a8::XValue(row[18]));
guild->set__gameid(a8::XValue(row[1]));
guild->set__channel(a8::XValue(row[21]));
guild->set__createtime(a8::XValue(row[19]));
guild->set__modifytime(a8::XValue(row[20]));
guild->set_member_num(a8::XValue(row[22]));
guild->set__name_ext1(a8::XValue(row[23]));
guild->set__name_ext2(a8::XValue(row[24]));
}
/*
LoadGuild
SyncGuild
RefreshGuild
*/
static std::string GenSelectGuildSql(const std::string& where)
{
std::string sql =
"SELECT idx, gameid, guild_id, guild_name, guild_lv, guild_exp, guild_badge, guild_notice, "
" guild_declaration, owner_id, owner_name, owner_avatar_url, "
" creator_id, creator_name, creator_avatar_url, guild_status, "
" join_unlimited, join_cond1, join_cond2, createtime, modifytime, channel, guild_member_num, "
" name_ext1, name_ext2 "
"FROM `guild` ";
sql += where;
return sql;
}
void GuildMgr::Init()
{
rank_cmp_func_ = RankCmpFunc;
sorted_cmp_func_ = SortedCmpFunc;
auto mysql_cluster_conf = JsonDataMgr::Instance()->GetMysqlClusterConf();
for (int i = 0; i < mysql_cluster_conf->Size(); ++i) {
int instance_id = mysql_cluster_conf->At(i)->At("instance_id")->AsXValue();
pending_db_hash_[instance_id] = 0;
sync_db_hash_[instance_id] = App::Instance()->nowtime;
LoadGuild(instance_id, 0);
}
}
void GuildMgr::UnInit()
{
}
void GuildMgr::__GuildCreate(f8::JsonHttpRequest* request)
{
if (!load_done_) {
request->resp_xobj->SetVal("errcode", 2);
request->resp_xobj->SetVal("errmsg", "");
return;
}
long long guild_id = request->request.At("guild_id")->AsXValue();
if (GetGuildById(guild_id)) {
request->resp_xobj->SetVal("errcode", 1);
request->resp_xobj->SetVal("errmsg", "guild_id已经存在");
return;
}
std::string guild_data;
cs::MFGuildBasic* guild = new cs::MFGuildBasic;
TypeConvert::Convert(request, guild);
if (guild->guild_name().empty()) {
request->resp_xobj->SetVal("errcode", 2);
request->resp_xobj->SetVal("errmsg", "战队名字不能为空");
delete guild;
return;
}
if (GetGuildByName(
guild->_gameid(),
guild->_channel(),
guild->_name_ext1(),
guild->_name_ext2(),
guild->guild_name()
)) {
request->resp_xobj->SetVal("errcode", 3);
request->resp_xobj->SetVal("errmsg", "战队名已经存在");
delete guild;
return;
}
if (a8::GetUtf8Length(guild->guild_name().c_str()) > MAX_GUILD_NAME_LEN) {
request->resp_xobj->SetVal("errcode", 3);
request->resp_xobj->SetVal("errmsg", "战队名字长度超过限制");
delete guild;
return;
}
if (a8::GetUtf8Length(guild->guild_declaration().c_str()) > MAX_GUILD_DECLARATION_LEN) {
request->resp_xobj->SetVal("errcode", 3);
request->resp_xobj->SetVal("errmsg", "战队宣言长度超过限制");
delete guild;
return;
}
if (MetaMgr::Instance()->HasDirtyWord(guild->guild_name())) {
request->resp_xobj->SetVal("errcode", 4);
request->resp_xobj->SetVal("errmsg", "战队名含有违禁字符");
delete guild;
return;
}
if (MetaMgr::Instance()->HasDirtyWord(guild->guild_declaration())) {
request->resp_xobj->SetVal("errcode", 5);
request->resp_xobj->SetVal("errmsg", "战队宣言含有违禁字符");
delete guild;
return;
}
request->pending = true;
request->resp_xobj->SetVal("errcode", 0);
request->resp_xobj->SetVal("errmsg", "");
a8::XObject conn = DBEngine::Instance()->GetConnInfo(guild_id);
guild->set_member_num(1);
guild->set__createtime(App::Instance()->nowtime);
guild->set__modifytime(App::Instance()->nowtime);
long long name_ext1 = 0;
long long name_ext2 = 0;
if (f8::Channel_e::DOUYIN == guild->_channel()) {
name_ext1 = f8::Channel_e::DOUYIN;
}
DBEngine::Instance()->ExecAsyncScript
(
conn,
"INSERT INTO `guild`(gameid, channel, guild_id, guild_name, guild_lv, guild_exp, guild_badge, "
" guild_apply_num, guild_notice, guild_declaration, guild_log, owner_id, "
" owner_name, owner_avatar_url, creator_id, creator_name, creator_avatar_url, guild_member_num, "
" guild_data, guild_status, join_unlimited, join_cond1, join_cond2, createtime, modifytime, "
" name_ext1, name_ext2)"
"VALUES(%d, %d, %d, '%s', %d, %d, %d, %d, '%s', '%s', '%s', '%s', "
" '%s', '%s', '%s', '%s', '%s', %d, "
" '%s', %d, %d, %d, %d, %d, %d, %d, %d);",
{
guild->_gameid(),
guild->_channel(),
guild->guild_id(),
guild->guild_name(),
guild->guild_lv(),
guild->guild_exp(),
guild->guild_badge(),
0,
"",
guild->guild_declaration(),
"",
guild->owner_id(),
guild->owner_name(),
guild->owner_avatar_url(),
guild->owner_id(),
guild->owner_name(),
guild->owner_avatar_url(),
guild->member_num(),
guild_data,
0,
guild->join_unlimited(),
guild->join_cond1(),
guild->join_cond2(),
App::Instance()->nowtime,
App::Instance()->nowtime,
name_ext1,
name_ext2
},
a8::XParams()
.SetSender(request)
.SetParam1(guild),
[] (a8::XParams& param, const f8::DataSet* data_set)
{
f8::JsonHttpRequest* request = (f8::JsonHttpRequest*)param.sender.GetUserData();
cs::MFGuildBasic* guild = (cs::MFGuildBasic*)param.param1.GetUserData();
GuildMgr::Instance()->AddGuild(guild);
{
std::string response;
request->resp_xobj->ToJsonStr(response);
IMListener::Instance()->SendText(request->socket_handle, a8::HttpResponse(response));
}
delete request;
},
[] (a8::XParams& param, int error_code, const std::string& error_msg)
{
f8::JsonHttpRequest* request = (f8::JsonHttpRequest*)param.sender.GetUserData();
cs::MFGuildBasic* guild = (cs::MFGuildBasic*)param.param1.GetUserData();
{
std::string response;
request->resp_xobj->SetVal("errcode", 2);
request->resp_xobj->SetVal("errmsg", "服务器内部错误");
request->resp_xobj->ToJsonStr(response);
IMListener::Instance()->SendText(request->socket_handle, a8::HttpResponse(response));
}
delete guild;
delete request;
},
0);
}
void GuildMgr::__GuildSearch(f8::JsonHttpRequest* request)
{
if (!load_done_) {
request->resp_xobj->SetVal("errcode", 2);
request->resp_xobj->SetVal("errmsg", "");
return;
}
std::string account_id = request->request.At("account_id")->AsXValue();
int curr_page = request->request.At("curr_page")->AsXValue();
int page_size = request->request.At("page_size")->AsXValue();
std::string search_name = request->request.At("guild_name")->AsXValue().GetString();
if (curr_page < 0) {
curr_page = 0;
}
if (page_size < 1) {
page_size = 1;
}
#if 1
page_size = 20;
#endif
request->resp_xobj->SetVal("errcode", 0);
request->resp_xobj->SetVal("errmsg", "");
request->resp_xobj->SetVal("curr_page", curr_page);
request->resp_xobj->SetVal("page_size", page_size);
a8::MutableXObject* guild_list = a8::MutableXObject::NewArray();
int total_count = 0;
int total_page = 0;
InternalSearch(account_id,
guild_list,
search_name,
curr_page,
page_size,
total_count,
total_page);
request->resp_xobj->SetVal("_total_page", total_page);
request->resp_xobj->SetVal("_total_count", total_count);
request->resp_xobj->SetVal("guild_list", *guild_list);
delete guild_list;
}
void GuildMgr::__GuildUpdate(f8::JsonHttpRequest* request)
{
if (!load_done_) {
request->resp_xobj->SetVal("errcode", 2);
request->resp_xobj->SetVal("errmsg", "");
return;
}
long long guild_id = request->request.At("guild_id")->AsXValue();
cs::MFGuildBasic* guild = GetGuildById(guild_id);
if (guild) {
guild->set_guild_badge(request->request.At("guild_badge")->AsXValue());
guild->set_guild_lv(request->request.At("guild_lv")->AsXValue());
guild->set_guild_exp(request->request.At("guild_exp")->AsXValue());
guild->set_guild_declaration(request->request.At("guild_declaration")->AsXValue().GetString());
guild->set_owner_id(request->request.At("owner_id")->AsXValue());
guild->set_owner_name(request->request.At("owner_name")->AsXValue().GetString());
guild->set_owner_avatar_url(request->request.At("owner_avatar_url")->AsXValue().GetString());
guild->set_join_unlimited(request->request.At("join_unlimited")->AsXValue());
guild->set_join_cond1(request->request.At("join_cond1")->AsXValue());
guild->set_join_cond2(request->request.At("join_cond2")->AsXValue());
guild->set_member_num(request->request.At("member_num")->AsXValue());
}
request->resp_xobj->SetVal("errcode", 0);
request->resp_xobj->SetVal("errmsg", "");
}
void GuildMgr::__GuildRename(f8::JsonHttpRequest* request)
{
if (!load_done_) {
request->resp_xobj->SetVal("errcode", 2);
request->resp_xobj->SetVal("errmsg", "服务器内部错误");
return;
}
request->resp_xobj->SetVal("errcode", 0);
request->resp_xobj->SetVal("errmsg", "");
long long guild_id = request->request.At("guild_id")->AsXValue();
std::string guild_name = request->request.At("guild_name")->AsXValue().GetString();
std::string guild_declaration = request->request.At("guild_declaration")->AsXValue().GetString();
cs::MFGuildBasic* guild = GetGuildById(guild_id);
if (!guild) {
request->resp_xobj->SetVal("errcode", 1);
request->resp_xobj->SetVal("errmsg", "服务器内部错误");
return;
}
if (guild->guild_declaration() != guild_declaration) {
if (MetaMgr::Instance()->HasDirtyWord(guild_declaration)) {
request->resp_xobj->SetVal("errcode", 1);
request->resp_xobj->SetVal("errmsg", "战队宣言含有违禁字符");
return;
}
}
if (guild->guild_name() == guild_name) {
guild->set_guild_declaration(guild_declaration);
return;
}
if (guild_name.empty()) {
request->resp_xobj->SetVal("errcode", 1);
request->resp_xobj->SetVal("errmsg", "战队名不能为空");
return;
}
if (GetGuildByName(guild->_gameid(),
guild->_channel(),
guild->_name_ext1(),
guild->_name_ext2(),
guild_name)) {
request->resp_xobj->SetVal("errcode", 1);
request->resp_xobj->SetVal("errmsg", "战队名已经存在");
return;
}
if (a8::GetUtf8Length(guild_name.c_str()) > MAX_GUILD_NAME_LEN) {
request->resp_xobj->SetVal("errcode", 3);
request->resp_xobj->SetVal("errmsg", "战队名字长度超过限制");
delete guild;
return;
}
if (a8::GetUtf8Length(guild_declaration.c_str()) > MAX_GUILD_DECLARATION_LEN) {
request->resp_xobj->SetVal("errcode", 3);
request->resp_xobj->SetVal("errmsg", "战队宣言长度超过限制");
delete guild;
return;
}
if (MetaMgr::Instance()->HasDirtyWord(guild_name)) {
request->resp_xobj->SetVal("errcode", 1);
request->resp_xobj->SetVal("errmsg", "战队名含有违禁字符");
return;
}
request->pending = true;
request->resp_xobj->SetVal("errcode", 0);
request->resp_xobj->SetVal("errmsg", "");
a8::XObject conn = DBEngine::Instance()->GetConnInfo(guild_id);
DBEngine::Instance()->ExecAsyncScript
(
conn,
"UPDATE `guild` SET guild_name='%s', guild_declaration='%s' "
"WHERE guild_id=%d;",
{
guild_name,
guild_declaration,
guild->guild_id()
},
a8::XParams()
.SetSender(request)
.SetParam1(guild),
[] (a8::XParams& param, const f8::DataSet* data_set)
{
f8::JsonHttpRequest* request = (f8::JsonHttpRequest*)param.sender.GetUserData();
cs::MFGuildBasic* guild = (cs::MFGuildBasic*)param.param1.GetUserData();
std::string guild_name = request->request.At("guild_name")->AsXValue().GetString();
std::string guild_declaration = request->request.At("guild_declaration")->AsXValue().GetString();
GuildMgr::Instance()->GuildRename(guild, guild_name);
guild->set_guild_declaration(guild_declaration);
{
std::string response;
request->resp_xobj->ToJsonStr(response);
IMListener::Instance()->SendText(request->socket_handle, a8::HttpResponse(response));
}
delete request;
},
[] (a8::XParams& param, int error_code, const std::string& error_msg)
{
f8::JsonHttpRequest* request = (f8::JsonHttpRequest*)param.sender.GetUserData();
{
std::string response;
request->resp_xobj->SetVal("errcode", 2);
request->resp_xobj->SetVal("errmsg", "服务器内部错误");
request->resp_xobj->ToJsonStr(response);
IMListener::Instance()->SendText(request->socket_handle, a8::HttpResponse(response));
}
delete request;
},
0);
}
void GuildMgr::__GuildRank(f8::JsonHttpRequest* request)
{
if (!load_done_) {
request->resp_xobj->SetVal("errcode", 2);
request->resp_xobj->SetVal("errmsg", "");
return;
}
int gameid = request->request.At("gameid")->AsXValue();
a8::CommonRank<cs::MFGuildBasic>* sorted_guild_list = GetGuildRank(gameid);
request->resp_xobj->SetVal("errcode", 0);
request->resp_xobj->SetVal("errmsg", "");
request->resp_xobj->SetVal("curr_page", 0);
request->resp_xobj->SetVal("page_size", 50);
request->resp_xobj->SetVal("_total_page", 1);
request->resp_xobj->SetVal("_total_count", 0);
a8::MutableXObject* guild_list = a8::MutableXObject::NewArray();
if (sorted_guild_list) {
request->resp_xobj->SetVal("_total_count", sorted_guild_list->Size());
for (auto& guild : sorted_guild_list->GetList()) {
a8::MutableXObject* guild_xobj = a8::MutableXObject::NewObject();
TypeConvert::Convert(guild, guild_xobj);
guild_list->Push(*guild_xobj);
delete guild_xobj;
}
}
request->resp_xobj->SetVal("guild_list", *guild_list);
delete guild_list;
}
void GuildMgr::__GuildConfirmed(f8::JsonHttpRequest* request)
{
}
void GuildMgr::__GenTestData(f8::JsonHttpRequest* request)
{
if (!load_done_) {
request->resp_xobj->SetVal("errcode", 2);
request->resp_xobj->SetVal("errmsg", "");
return;
}
request->resp_xobj->SetVal("errcode", 0);
request->resp_xobj->SetVal("errmsg", "");
int num = request->request.At("num")->AsXValue();
int gameid = request->request.At("gameid")->AsXValue();
for (int i = 0; i < num; ++i) {
long long guild_id = App::Instance()->NewUuid();
a8::XObject conn = DBEngine::Instance()->GetConnInfo(guild_id);
DBEngine::Instance()->ExecAsyncScript
(
conn,
"INSERT INTO `guild`(gameid, guild_id, guild_name, guild_lv, guild_exp, guild_badge, "
" guild_apply_num, guild_notice, guild_declaration, guild_log, owner_id, "
" owner_name, owner_avatar_url, creator_id, creator_name, creator_avatar_url, "
" guild_data, guild_status, createtime, modifytime)"
"VALUES(%d, %d, '%s', %d, %d, %d, %d, '%s', '%s', '%s', '%s', "
" '%s', '%s', '%s', '%s', '%s', "
" '%s', %d, %d, %d)",
{
gameid,
guild_id,
a8::Format("测试战队%d", { i + 1}),
1,
1,
1,
0,
"",
"战队宣言",
"",
1,
"1",
"",
"",
"",
"",
"",
0,
App::Instance()->nowtime,
App::Instance()->nowtime
},
a8::XParams(),
[] (a8::XParams& param, const f8::DataSet* data_set)
{
},
[] (a8::XParams& param, int error_code, const std::string& error_msg)
{
abort();
},
guild_id);
}
}
cs::MFGuildBasic* GuildMgr::GetGuildById(long long guild_id)
{
auto itr = id_hash_.find(guild_id);
return itr != id_hash_.end() ? itr->second : nullptr;
}
cs::MFGuildBasic* GuildMgr::GetGuildByName(int gameid,
int channel,
long long name_ext1,
long long name_ext2,
const std::string& guild_name)
{
auto itr = name_hash_.find(GenGuildName(gameid, channel, name_ext1, name_ext2, guild_name));
return itr != name_hash_.end() ? itr->second : nullptr;
}
a8::CommonRank<cs::MFGuildBasic>* GuildMgr::GetGuildRank(int gameid)
{
auto itr = rank_list_.find(gameid);
return itr != rank_list_.end() ? &itr->second : nullptr;
}
a8::CommonRank<cs::MFGuildBasic>* GuildMgr::GetGuildList(int gameid)
{
auto itr = sorted_list_.find(gameid);
return itr != sorted_list_.end() ? &itr->second : nullptr;
}
void GuildMgr::AddGuild(cs::MFGuildBasic* guild)
{
id_hash_[guild->guild_id()] = guild;
std::string key = GenGuildName(guild->_gameid(),
guild->_channel(),
guild->_name_ext1(),
guild->_name_ext2(),
guild->guild_name());
name_hash_[key] = guild;
}
void GuildMgr::LoadGuild(int instance_id, long long last_idx)
{
DBEngine::Instance()->ExecAsyncQuery
(
*JsonDataMgr::Instance()->GetMysqlConf(instance_id),
GenSelectGuildSql("WHERE idx > %d;").c_str(),
{
last_idx
},
a8::XParams()
.SetSender(instance_id)
.SetParam1(last_idx),
[] (a8::XParams& param, const f8::DataSet* data_set)
{
int instance_id = param.sender;
long long last_idx = param.param1;
if (data_set && !data_set->empty()) {
for (auto& row : *data_set) {
cs::MFGuildBasic* guild = new cs::MFGuildBasic;
DbToGuildBasic(row, guild);
GuildMgr::Instance()->AddGuild(guild);
if (a8::XValue(row[0]).GetInt64() > last_idx) {
last_idx = a8::XValue(row[0]);
}
}
GuildMgr::Instance()->LoadGuild(instance_id, last_idx);
} else {
GuildMgr::Instance()->OnOneDBDone(instance_id);
}
},
[] (a8::XParams& param, int error_code, const std::string& error_msg)
{
abort();
},
instance_id);
}
void GuildMgr::SyncGuild(int instance_id)
{
DBEngine::Instance()->ExecAsyncQuery
(
*JsonDataMgr::Instance()->GetMysqlConf(instance_id),
GenSelectGuildSql("WHERE modifytime > %d;").c_str(),
{
sync_db_hash_[instance_id]
},
a8::XParams()
.SetSender(instance_id),
[] (a8::XParams& param, const f8::DataSet* data_set)
{
int instance_id = param.sender;
if (data_set && !data_set->empty()) {
int last_sync_time = GuildMgr::Instance()->sync_db_hash_[instance_id];
for (auto& row : *data_set) {
cs::MFGuildBasic* guild = new cs::MFGuildBasic;
DbToGuildBasic(row, guild);
GuildMgr::Instance()->UpdateGuild(guild);
if (guild->_modifytime() > last_sync_time) {
last_sync_time = guild->_modifytime();
}
delete guild;
}
if (last_sync_time > GuildMgr::Instance()->sync_db_hash_[instance_id]) {
GuildMgr::Instance()->sync_db_hash_[instance_id] = last_sync_time;
}
}
},
[] (a8::XParams& param, int error_code, const std::string& error_msg)
{
abort();
},
instance_id);
}
void GuildMgr::OnOneDBDone(int instance_id)
{
if (pending_db_hash_.find(instance_id) == pending_db_hash_.end() ||
pending_db_hash_[instance_id] == 1) {
abort();
}
pending_db_hash_[instance_id] = 1;
load_done_ = true;
for (auto& pair : pending_db_hash_) {
if (!pair.second) {
load_done_ = false;
break;
}
}
a8::UdpLog::Instance()->Debug("%d db done", {instance_id});
if (load_done_) {
a8::UdpLog::Instance()->Debug("all db done guild_num:%d", {id_hash_.size()});
GenGuildRank();
InstallSyncGuildTimer();
}
}
void GuildMgr::RefreshGuild(long long guild_id)
{
a8::XObject conn = DBEngine::Instance()->GetConnInfo(guild_id);
DBEngine::Instance()->ExecAsyncQuery
(
conn,
GenSelectGuildSql("WHERE guild_id = %d;").c_str(),
{
guild_id
},
a8::XParams()
.SetSender(guild_id),
[] (a8::XParams& param, const f8::DataSet* data_set)
{
if (data_set && !data_set->empty()) {
for (auto& row : *data_set) {
cs::MFGuildBasic* guild = new cs::MFGuildBasic;
DbToGuildBasic(row, guild);
GuildMgr::Instance()->UpdateGuild(guild);
delete guild;
}
}
},
[] (a8::XParams& param, int error_code, const std::string& error_msg)
{
abort();
},
guild_id);
}
void GuildMgr::GenGuildRank()
{
rank_list_.clear();
for (auto& pair : id_hash_) {
UpdateRank(pair.second);
}
}
void GuildMgr::UpdateGuild(cs::MFGuildBasic* new_guild)
{
auto guild = GetGuildById(new_guild->guild_id());
if (guild) {
guild->set_guild_lv(new_guild->guild_lv());
guild->set_guild_exp(new_guild->guild_exp());
guild->set_guild_badge(new_guild->guild_badge());
guild->set_member_num((new_guild->member_num()));
guild->set_guild_declaration((new_guild->guild_declaration()));
guild->set_owner_id((new_guild->owner_id()));
guild->set_owner_name((new_guild->owner_name()));
guild->set_owner_avatar_url((new_guild->owner_avatar_url()));
guild->set_join_unlimited((new_guild->join_unlimited()));
guild->set_join_cond1((new_guild->join_cond1()));
guild->set_join_cond2((new_guild->join_cond2()));
guild->set__modifytime(new_guild->_modifytime());
guild->set__guild_status(new_guild->_guild_status());
if (guild->_name_ext1() != new_guild->_name_ext1() ||
guild->_name_ext2() != new_guild->_name_ext2()) {
{
std::string old_key = GenGuildName(guild->_gameid(),
guild->_channel(),
guild->_name_ext1(),
guild->_name_ext2(),
guild->guild_name());
name_hash_.erase(old_key);
}
{
std::string new_key = GenGuildName(guild->_gameid(),
guild->_channel(),
new_guild->_name_ext1(),
new_guild->_name_ext2(),
guild->guild_name());
name_hash_[new_key] = guild;
}
}
guild->set__name_ext1(new_guild->_name_ext1());
guild->set__name_ext2(new_guild->_name_ext2());
UpdateRank(guild);
}
}
void GuildMgr::UpdateRank(cs::MFGuildBasic* guild)
{
{
auto rank_list = a8::ForceCreateCommonRankList
(
rank_list_,
guild->_gameid(),
rank_cmp_func_,
MAX_RANK_LIST_NUM);
if (guild->_guild_status() == 2 ||
guild->member_num() <= 0) {
rank_list->Remove(guild);
} else {
rank_list->Update(guild);
}
}
{
auto rank_list = a8::ForceCreateCommonRankList
(
sorted_list_,
guild->_gameid(),
sorted_cmp_func_,
MAX_SORTED_LIST_NUM);
if (guild->_guild_status() == 2 ||
guild->member_num() <= 0) {
rank_list->Remove(guild);
} else {
rank_list->Update(guild);
}
}
}
void GuildMgr::InstallSyncGuildTimer()
{
auto mysql_cluster_conf = JsonDataMgr::Instance()->GetMysqlClusterConf();
for (int i = 0; i < mysql_cluster_conf->Size(); ++i) {
int instance_id = mysql_cluster_conf->At(i)->At("instance_id")->AsXValue();
a8::Timer::Instance()->AddRepeatTimerAndAttach
(1000 * 60,
a8::XParams()
.SetSender(instance_id),
[] (const a8::XParams& param)
{
GuildMgr::Instance()->SyncGuild(param.sender);
},
&timer_attacher_.timer_list_);
}
}
std::string GuildMgr::GenGuildName(int gameid,
int channel,
long long name_ext1,
long long name_ext2,
const std::string& raw_name)
{
std::string guild_name = a8::XValue(gameid).GetString() +
NAME_MAGIC_SYMBOL + a8::XValue(name_ext1).GetString() +
NAME_MAGIC_SYMBOL + a8::XValue(name_ext2).GetString() +
NAME_MAGIC_SYMBOL + raw_name;
return guild_name;
}
void GuildMgr::GuildRename(cs::MFGuildBasic* guild, const std::string& new_raw_name)
{
if (guild->guild_name() != new_raw_name) {
std::string old_name = GenGuildName(guild->_gameid(),
guild->_channel(),
guild->_name_ext1(),
guild->_name_ext2(),
guild->guild_name());
name_hash_.erase(old_name);
guild->set_guild_name(new_raw_name);
std::string new_name = GenGuildName(guild->_gameid(),
guild->_channel(),
guild->_name_ext1(),
guild->_name_ext2(),
new_raw_name);
name_hash_[new_name] = guild;
}
}
std::set<long long>& GuildMgr::ForceSearchCache(const std::string& account_id, const std::string& search_name)
{
auto itr = search_cache_.find(account_id);
if (itr == search_cache_.end()) {
timer_list* timer = a8::Timer::Instance()->AddDeadLineTimerAndAttach
(
1000 * 20,
a8::XParams()
.SetSender(account_id)
.SetParam1(App::Instance()->nowtime),
[] (const a8::XParams& param)
{
GuildMgr::Instance()->search_cache_.erase(param.sender);
},
&timer_attacher_.timer_list_
);
search_cache_[account_id] = std::make_tuple(timer, account_id, std::set<long long>());
itr = search_cache_.find(account_id);
} else {
a8::Timer::Instance()->ModifyTimer(std::get<0>(itr->second), 1000 * 20);
}
int addtime = a8::Timer::Instance()->MutableParams(std::get<0>(itr->second))->param1;
if (App::Instance()->nowtime - addtime > 60) {
std::get<2>(itr->second).clear();
}
if (std::get<1>(itr->second) != search_name) {
std::get<1>(itr->second) = search_name;
std::get<2>(itr->second).clear();
}
return std::get<2>(itr->second);
}
void GuildMgr::InternalSearch(const std::string& account_id,
a8::MutableXObject* guild_list,
const std::string& search_name,
int curr_page,
int page_size,
int& total_count,
int& total_page)
{
total_page = 0;
total_count = 0;
int gameid = f8::ExtractGameIdFromAccountId(account_id);
a8::CommonRank<cs::MFGuildBasic>* commonrank = GetGuildList(gameid);
if (!commonrank || commonrank->GetList().empty()) {
return;
}
std::vector<cs::MFGuildBasic*> matched_list;
for (auto guild : commonrank->GetList()) {
if (search_name.empty() ||
guild->guild_name().find(search_name) != std::string::npos) {
matched_list.push_back(guild);
}
}
std::shuffle(matched_list.begin(), matched_list.end(), std::default_random_engine(rand()));
std::set<long long>& cache_guilds = ForceSearchCache(account_id, search_name);
for (auto& guild : matched_list) {
if (guild_list->Size() >= page_size) {
break;
}
a8::MutableXObject* guild_xobj = a8::MutableXObject::NewObject();
TypeConvert::Convert(guild, guild_xobj);
guild_list->Push(*guild_xobj);
delete guild_xobj;
cache_guilds.insert(guild->guild_id());
}
total_count = guild_list->Size();
}