diff --git a/server/imserver/guild.cc b/server/imserver/guild.cc index 7fb4cb0..e0bd70d 100644 --- a/server/imserver/guild.cc +++ b/server/imserver/guild.cc @@ -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, diff --git a/server/rankserver/guildmgr.cc b/server/rankserver/guildmgr.cc index 8f9f5a9..11f0862 100644 --- a/server/rankserver/guildmgr.cc +++ b/server/rankserver/guildmgr.cc @@ -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& row, cs::MFGuildBasic* guild) +void DbToGuildBasic(const std::vector& 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& 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& 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 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* GuildMgr::GetGuildRank(int gameid) return itr != rank_list_.end() ? &itr->second : nullptr; } +a8::CommonRank* 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& 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()); + 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* commonrank = GetGuildList(gameid); + if (!commonrank || commonrank->GetList().empty()) { + return; + } + std::vector 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& 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(); +} diff --git a/server/rankserver/guildmgr.h b/server/rankserver/guildmgr.h index 3e42a50..3437ccc 100644 --- a/server/rankserver/guildmgr.h +++ b/server/rankserver/guildmgr.h @@ -29,8 +29,13 @@ class GuildMgr : public a8::Singleton 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* GetGuildRank(int gameid); + a8::CommonRank* 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 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& 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 std::map> sorted_list_; std::function rank_cmp_func_; std::function sorted_cmp_func_; - std::map>> search_cache_; + std::map>> search_cache_; + + friend void DbToGuildBasic(const std::vector& row, cs::MFGuildBasic* guild); }; diff --git a/server/tools/protobuild/cs_proto.proto b/server/tools/protobuild/cs_proto.proto index 2ec6d9e..58e074e 100644 --- a/server/tools/protobuild/cs_proto.proto +++ b/server/tools/protobuild/cs_proto.proto @@ -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 } //登录好友服 diff --git a/sql/relationdb_n.sql b/sql/relationdb_n.sql index d14fcc9..36a3531 100644 --- a/sql/relationdb_n.sql +++ b/sql/relationdb_n.sql @@ -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`) diff --git a/third_party/a8engine b/third_party/a8engine index 3a005b9..6a750f1 160000 --- a/third_party/a8engine +++ b/third_party/a8engine @@ -1 +1 @@ -Subproject commit 3a005b95f4569756f525358f7fa9c116177d264c +Subproject commit 6a750f136e23393ff008e4b57982f1570c9eb3ec diff --git a/third_party/framework b/third_party/framework index bd30c66..a9481a2 160000 --- a/third_party/framework +++ b/third_party/framework @@ -1 +1 @@ -Subproject commit bd30c666bf2a5c909dafe6b458fce62d007d9a56 +Subproject commit a9481a26152bd030516b2e546702982f445e2494