This commit is contained in:
aozhiwei 2020-10-13 15:21:28 +08:00
parent 8387f9b140
commit 5a6a622ac0
7 changed files with 225 additions and 59 deletions

View File

@ -1145,7 +1145,7 @@ void Guild::SaveToDB()
" 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 "
" modifytime=%d, name_ext2=%d "
"WHERE guild_id=%d;",
{
guild_lv_,
@ -1169,7 +1169,8 @@ void Guild::SaveToDB()
join_cond2_,
member_hash_.size(),
App::Instance()->nowtime,
guild_id_
guild_id_,
guild_status_ == kGuildDismissed ? GuildId() : 0
},
a8::XParams(),
on_ok,

View File

@ -13,6 +13,9 @@
#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 = "@";
@ -63,7 +66,7 @@ static bool SortedCmpFunc(const cs::MFGuildBasic* a, const cs::MFGuildBasic* b)
return a->guild_id() > b->guild_id();
}
static void DbToGuildBasic(const std::vector<std::string>& row, cs::MFGuildBasic* guild)
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]);
@ -74,6 +77,7 @@ static void DbToGuildBasic(const std::vector<std::string>& row, cs::MFGuildBasic
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]));
@ -82,15 +86,23 @@ static void DbToGuildBasic(const std::vector<std::string>& row, cs::MFGuildBasic
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 "
" join_unlimited, join_cond1, join_cond2, createtime, modifytime, channel, guild_member_num, "
" name_ext1, name_ext2 "
"FROM `guild` ";
sql += where;
return sql;
@ -142,6 +154,8 @@ void GuildMgr::__GuildCreate(f8::JsonHttpRequest* request)
if (GetGuildByName(
guild->_gameid(),
guild->_channel(),
guild->_name_ext1(),
guild->_name_ext2(),
guild->guild_name()
)) {
request->resp_xobj->SetVal("errcode", 3);
@ -169,16 +183,22 @@ void GuildMgr::__GuildCreate(f8::JsonHttpRequest* request)
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)"
" 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', 1, "
" '%s', %d, %d, %d, %d, %d, %d);",
" '%s', '%s', '%s', '%s', '%s', 0, "
" '%s', %d, %d, %d, %d, %d, %d, %d, %d);",
{
guild->_gameid(),
guild->_channel(),
@ -203,7 +223,9 @@ void GuildMgr::__GuildCreate(f8::JsonHttpRequest* request)
guild->join_cond1(),
guild->join_cond2(),
App::Instance()->nowtime,
App::Instance()->nowtime
App::Instance()->nowtime,
name_ext1,
name_ext2
},
a8::XParams()
.SetSender(request)
@ -249,6 +271,7 @@ void GuildMgr::__GuildSearch(f8::JsonHttpRequest* request)
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();
@ -261,43 +284,23 @@ void GuildMgr::__GuildSearch(f8::JsonHttpRequest* request)
#if 1
page_size = 20;
#endif
int total_page = 0;
int total_count = 0;
std::vector<cs::MFGuildBasic*> last_page_data;
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();
for (auto& pair : id_hash_) {
cs::MFGuildBasic* guild = pair.second;
if (guild->member_num() <= 0) {
continue;
}
if (guild->guild_name().find(search_name) != std::string::npos) {
++total_count;
last_page_data.push_back(guild);
if (last_page_data.size() % page_size == 0) {
last_page_data.clear();
}
if (total_count >= curr_page * page_size && guild_list->Size() < page_size) {
a8::MutableXObject* guild_xobj = a8::MutableXObject::NewObject();
TypeConvert::Convert(guild, guild_xobj);
guild_list->Push(*guild_xobj);
delete guild_xobj;
}
}
}
total_page = std::ceil((double)total_count / page_size);
if (curr_page >= total_page) {
for (auto& guild : last_page_data) {
a8::MutableXObject* guild_xobj = a8::MutableXObject::NewObject();
TypeConvert::Convert(guild, guild_xobj);
delete guild_xobj;
}
curr_page = total_page - 1;
}
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);
@ -366,7 +369,11 @@ void GuildMgr::__GuildRename(f8::JsonHttpRequest* request)
request->resp_xobj->SetVal("errmsg", "公会名不能为空");
return;
}
if (GetGuildByName(guild->_gameid(), guild->_channel(), guild_name)) {
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;
@ -529,9 +536,13 @@ cs::MFGuildBasic* GuildMgr::GetGuildById(long long guild_id)
return itr != id_hash_.end() ? itr->second : nullptr;
}
cs::MFGuildBasic* GuildMgr::GetGuildByName(int gameid, int channel, const std::string& guild_name)
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, guild_name));
auto itr = name_hash_.find(GenGuildName(gameid, channel, name_ext1, name_ext2, guild_name));
return itr != name_hash_.end() ? itr->second : nullptr;
}
@ -541,10 +552,21 @@ a8::CommonRank<cs::MFGuildBasic>* GuildMgr::GetGuildRank(int 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;
name_hash_[GenGuildName(guild->_gameid(), guild->_channel(), guild->guild_name())] = 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)
@ -696,6 +718,29 @@ void GuildMgr::UpdateGuild(cs::MFGuildBasic* new_guild)
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);
}
}
@ -709,7 +754,12 @@ void GuildMgr::UpdateRank(cs::MFGuildBasic* guild)
guild->_gameid(),
rank_cmp_func_,
MAX_RANK_LIST_NUM);
rank_list.Update(guild);
if (guild->_guild_status() == 2 ||
guild->member_num() <= 0) {
rank_list.Remove(guild);
} else {
rank_list.Update(guild);
}
}
{
auto rank_list = a8::ForceCreateCommonRankList
@ -718,7 +768,12 @@ void GuildMgr::UpdateRank(cs::MFGuildBasic* guild)
guild->_gameid(),
sorted_cmp_func_,
MAX_SORTED_LIST_NUM);
rank_list.Update(guild);
if (guild->_guild_status() == 2 ||
guild->member_num() <= 0) {
rank_list.Remove(guild);
} else {
rank_list.Update(guild);
}
}
}
@ -739,18 +794,104 @@ void GuildMgr::InstallSyncGuildTimer()
}
}
std::string GuildMgr::GenGuildName(int gameid, int channel, const std::string& raw_name)
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 + 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_name)
void GuildMgr::GuildRename(cs::MFGuildBasic* guild, const std::string& new_raw_name)
{
if (guild->guild_name() != new_name) {
std::string old_name = GenGuildName(guild->_gameid(), guild->_channel(), guild->guild_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_name);
name_hash_[GenGuildName(guild->_gameid(), guild->_channel(), new_name)] = guild;
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();
}

View File

@ -29,8 +29,13 @@ class GuildMgr : public a8::Singleton<GuildMgr>
private:
cs::MFGuildBasic* GetGuildById(long long guild_id);
cs::MFGuildBasic* GetGuildByName(int gameid, int channel, const std::string& guild_name);
cs::MFGuildBasic* GetGuildByName(int gameid,
int channel,
long long name_ext1,
long long name_ext2,
const std::string& guild_name);
a8::CommonRank<cs::MFGuildBasic>* GetGuildRank(int gameid);
a8::CommonRank<cs::MFGuildBasic>* GetGuildList(int gameid);
void AddGuild(cs::MFGuildBasic* guild);
void LoadGuild(int instance_id, long long last_idx);
void SyncGuild(int instance_id);
@ -40,8 +45,20 @@ class GuildMgr : public a8::Singleton<GuildMgr>
void UpdateGuild(cs::MFGuildBasic* new_guild);
void UpdateRank(cs::MFGuildBasic* guild);
void InstallSyncGuildTimer();
std::string GenGuildName(int gameid, int channel, const std::string& raw_name);
void GuildRename(cs::MFGuildBasic* guild, const std::string& new_name);
std::string GenGuildName(int gameid,
int channel,
long long name_ext1,
long long name_ext2,
const std::string& raw_name);
void GuildRename(cs::MFGuildBasic* guild, const std::string& new_raw_name);
void 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);
std::set<long long>& ForceSearchCache(const std::string& account_id, const std::string& search_name);
private:
a8::TimerAttacher timer_attacher_;
@ -54,5 +71,7 @@ class GuildMgr : public a8::Singleton<GuildMgr>
std::map<long long, a8::CommonRank<cs::MFGuildBasic>> sorted_list_;
std::function<bool(const cs::MFGuildBasic*, const cs::MFGuildBasic*)> rank_cmp_func_;
std::function<bool(const cs::MFGuildBasic*, const cs::MFGuildBasic*)> sorted_cmp_func_;
std::map<std::string, std::tuple<timer_list*, std::set<long long>>> search_cache_;
std::map<std::string, std::tuple<timer_list*, std::string, std::set<long long>>> search_cache_;
friend void DbToGuildBasic(const std::vector<std::string>& row, cs::MFGuildBasic* guild);
};

View File

@ -117,6 +117,9 @@ message MFGuildBasic
optional int32 _channel = 101; //channel
optional int32 _createtime = 102; //createtime
optional int32 _modifytime = 103; //modifytime
optional int64 _name_ext1 = 104; //name_ext1
optional int64 _name_ext2 = 105; //name_ext2
optional int64 _guild_status = 106; //guild_status
}
//

View File

@ -113,11 +113,13 @@ CREATE TABLE `guild` (
`join_unlimited` int(11) NOT NULL DEFAULT '0' COMMENT '不限制加入',
`join_cond1` int(11) NOT NULL DEFAULT '0' COMMENT '加入条件1',
`join_cond2` int(11) NOT NULL DEFAULT '0' COMMENT '加入条件2',
`name_ext1` bigint NOT NULL DEFAULT '0' COMMENT 'name_ext1',
`name_ext2` bigint NOT NULL DEFAULT '0' COMMENT 'name_ext2',
`createtime` int(11) NOT NULL DEFAULT '0' COMMENT '创建时间',
`modifytime` int(11) NOT NULL DEFAULT '0' COMMENT '修改时间',
PRIMARY KEY (`idx`),
UNIQUE KEY `guild_id` (`guild_id`),
UNIQUE KEY `guild_name` (`guild_name`),
UNIQUE KEY `guild_name` (`gameid`, `name_ext1`, `name_ext2`, `guild_name`),
KEY `owner_id` (`owner_id`),
KEY `creator_id` (`creator_id`),
KEY `modifytime` (`modifytime`)

@ -1 +1 @@
Subproject commit 3a005b95f4569756f525358f7fa9c116177d264c
Subproject commit 6a750f136e23393ff008e4b57982f1570c9eb3ec

@ -1 +1 @@
Subproject commit bd30c666bf2a5c909dafe6b458fce62d007d9a56
Subproject commit a9481a26152bd030516b2e546702982f445e2494