972 lines
34 KiB
C++
972 lines
34 KiB
C++
#include "precompile.h"
|
|
|
|
#include <a8/udplog.h>
|
|
#include <a8/timer.h>
|
|
#include <a8/openssl.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 = 8;
|
|
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();
|
|
}
|
|
|
|
static long long GetNameExt1(int channel)
|
|
{
|
|
switch (channel) {
|
|
case f8::Channel_e::DOUYIN:
|
|
case f8::Channel_e::QQ:
|
|
return channel;
|
|
default:
|
|
return 0;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
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;
|
|
}
|
|
long long name_ext1 = GetNameExt1(guild->_channel());
|
|
long long name_ext2 = 0;
|
|
if (GetGuildByName(
|
|
guild->_gameid(),
|
|
guild->_channel(),
|
|
name_ext1,
|
|
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);
|
|
std::string guild_name_base64;
|
|
a8::openssl::Base64Encode(guild->guild_name(), guild_name_base64);
|
|
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, guild_name_base64)"
|
|
"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, '%s');",
|
|
{
|
|
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,
|
|
guild_name_base64
|
|
},
|
|
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();
|
|
std::set<long long> applyed_guilds;
|
|
if (request->request.HasKey("applyed_guilds")) {
|
|
std::string applyed_guilds_str = request->request.At("applyed_guilds")->AsXValue().GetString();
|
|
std::vector<std::string> tmp_strings;
|
|
a8::Split(applyed_guilds_str, tmp_strings, ',');
|
|
for (auto& str : tmp_strings) {
|
|
if (!str.empty()) {
|
|
applyed_guilds.insert(a8::XValue(str));
|
|
}
|
|
}
|
|
}
|
|
if (curr_page < 0) {
|
|
curr_page = 0;
|
|
}
|
|
if (page_size < 1) {
|
|
page_size = 1;
|
|
}
|
|
#if 1
|
|
page_size = 10;
|
|
#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,
|
|
applyed_guilds,
|
|
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", "战队名字长度超过限制");
|
|
return;
|
|
}
|
|
if (a8::GetUtf8Length(guild_declaration.c_str()) > MAX_GUILD_DECLARATION_LEN) {
|
|
request->resp_xobj->SetVal("errcode", 3);
|
|
request->resp_xobj->SetVal("errmsg", "战队宣言长度超过限制");
|
|
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);
|
|
std::string guild_name_base64;
|
|
a8::openssl::Base64Encode(guild_name, guild_name_base64);
|
|
DBEngine::Instance()->ExecAsyncScript
|
|
(
|
|
conn,
|
|
"UPDATE `guild` SET guild_name='%s', guild_name_base64='%s', guild_declaration='%s' "
|
|
"WHERE guild_id=%d;",
|
|
{
|
|
guild_name,
|
|
guild_declaration,
|
|
guild_name_base64,
|
|
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::__GuildDirtyWordCheck(f8::JsonHttpRequest* request)
|
|
{
|
|
request->resp_xobj->SetVal("errcode", 0);
|
|
request->resp_xobj->SetVal("errmsg", "");
|
|
std::string text = request->request.At("text")->AsXValue();
|
|
if (MetaMgr::Instance()->HasDirtyWord(text)) {
|
|
request->resp_xobj->SetVal("errcode", 1);
|
|
request->resp_xobj->SetVal("errmsg", "含有屏蔽字符");
|
|
}
|
|
}
|
|
|
|
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,
|
|
std::set<long long>& applyed_guilds,
|
|
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);
|
|
int channel = f8::ExtractChannelIdFromAccountId(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;
|
|
}
|
|
if (guild->_channel() != channel) {
|
|
continue;
|
|
}
|
|
a8::MutableXObject* guild_xobj = a8::MutableXObject::NewObject();
|
|
TypeConvert::Convert(guild, guild_xobj);
|
|
if (applyed_guilds.find(guild->guild_id()) != applyed_guilds.end()) {
|
|
guild_xobj->SetVal("applyed", 1);
|
|
} else {
|
|
guild_xobj->SetVal("applyed", 0);
|
|
}
|
|
guild_list->Push(*guild_xobj);
|
|
delete guild_xobj;
|
|
cache_guilds.insert(guild->guild_id());
|
|
}
|
|
total_count = guild_list->Size();
|
|
}
|