diff --git a/server/imserver/asynctaskmgr.cc b/server/imserver/asynctaskmgr.cc index 5fbfbad..305cc77 100644 --- a/server/imserver/asynctaskmgr.cc +++ b/server/imserver/asynctaskmgr.cc @@ -6,6 +6,7 @@ #include "app.h" #include "player.h" #include "playermgr.h" +#include "dbhelper.h" #include "cs_proto.pb.h" #include "ss_proto.pb.h" @@ -110,13 +111,14 @@ void AsyncTaskMgr::CreateRecommandFriendTask(Player* hum) { ss::SS_IM_RandomUsersRequest msg; hum->FillIMMsgConext(msg.mutable_context()); - for (auto& account_id : hum->exclude_account_ids) { + for (auto& account_id : hum->GetExcludeAccountIds()) { msg.add_exclude_account_ids(account_id); } hum->SendSSMsg(hum->myself, msg); FillAsyncTaskContext(hum, &task->context, msg.context().seqid()); recommand_friend_tasks_[task->context.seqid] = task; } + DBHelper::Instance()->ShuaOfflineUsers(hum); a8::Timer::Instance()->AddDeadLineTimer ( 500, @@ -150,7 +152,9 @@ void AsyncTaskMgr::_SS_IM_PushUserOnlineState(f8::MsgHdr& hdr, const ss::SS_IM_P void AsyncTaskMgr::_SS_IM_RandomUsersResponse(f8::MsgHdr& hdr, const ss::SS_IM_RandomUsersResponse& msg) { - + RecommandFriendTask* task = GetRecommandFriendTask(msg.context().seqid()); + if (task) { + } } QueryUserStatusTask* AsyncTaskMgr::GetQueryUserStatusTask(long long seqid) diff --git a/server/imserver/dbhelper.cc b/server/imserver/dbhelper.cc index 03c6554..de086e6 100644 --- a/server/imserver/dbhelper.cc +++ b/server/imserver/dbhelper.cc @@ -10,6 +10,9 @@ #include "app.h" #include "synchelper.h" +#include "cs_proto.pb.h" +#include "ss_proto.pb.h" + void DBHelper::Init() { } @@ -191,3 +194,91 @@ void DBHelper::SetEventStatus(long long idx, crc32_code ); } + +void DBHelper::ShuaOfflineUsers(Player* hum) +{ + std::set& exclude_account_ids = hum->GetExcludeAccountIds(); + if (cache_users_hash.size() < 500 && !exclude_account_ids.empty()) { + std::string fmtstr; + std::vector sql_params; + for (auto& account_id : exclude_account_ids) { + fmtstr += "'%s',"; + sql_params.push_back(a8::XValue(account_id)); + } + if (!fmtstr.empty()) { + fmtstr = fmtstr.substr(0, fmtstr.size() - 1); + } + auto on_ok = + [] (a8::XParams& param, const f8::DataSet* data_set) + { + if (data_set) { + for (auto& row : *data_set) { + DBHelper::Instance()->AddCache + ( + row[1], //account_id + row[2], //nickname + row[3], //avatar_url + a8::XValue(row[4]), //sex + a8::XValue(row[5]), //data_version1 + a8::XValue(row[6]), //user_value1 + a8::XValue(row[7]), //user_value2 + a8::XValue(row[8]), //user_value3 + a8::XValue(row[9]) //last_logintime + ); + } + } + }; + auto on_error = + [] (a8::XParams& param, int error_code, const std::string& error_msg) + { + + }; + + a8::XObject conn_info = DBEngine::Instance()->GetConnInfo(hum->myself.crc32_code); + DBEngine::Instance()->ExecAsyncQuery + ( + conn_info, + ( + "SELECT idx, account_id, nickname, avatar_url, sex, data_version1, user_value1, " + " user_value2, user_value3, last_logintime " + "FROM `user` WHERE idx > (SELECT 9999 + FLOOR(RAND() * (MAX(idx) - 10000)) FROM `user`))" + " AND account_id not in(" + fmtstr + ") LIMIT 1, 10;" + ).c_str(), + sql_params, + a8::XParams() + .SetSender(hum->AccountId()), + on_ok, + on_error, + hum->myself.crc32_code + ); + } +} + +void DBHelper::AddCache( + const std::string& account_id, + const std::string& nickname, + const std::string& avatar_url, + int sex, + long long data_version1, + long long user_value1, + long long user_value2, + long long user_value3, + int last_logintime + ) +{ + if (cache_users_hash.find(account_id) == cache_users_hash.end()) { + cs::MFUserInfo* user_info = new cs::MFUserInfo(); + user_info->mutable_base_data()->set_account_id(account_id); + user_info->mutable_base_data()->set_nickname(nickname); + user_info->mutable_base_data()->set_avatar_url(avatar_url); + user_info->mutable_base_data()->set_sex(sex); + user_info->mutable_base_data()->set_base_data_version(data_version1); + user_info->mutable_base_data()->set_user_value1(user_value1); + user_info->mutable_base_data()->set_user_value2(user_value2); + user_info->mutable_base_data()->set_user_value3(user_value3); + user_info->mutable_base_data()->set_last_login_time(last_logintime); + user_info->mutable_base_data()->set__online(0); + cache_users_hash[account_id] = user_info; + cache_users_list.push_back(user_info); + } +} diff --git a/server/imserver/dbhelper.h b/server/imserver/dbhelper.h index b57b109..32c10c3 100644 --- a/server/imserver/dbhelper.h +++ b/server/imserver/dbhelper.h @@ -1,5 +1,10 @@ #pragma once +namespace cs +{ + class MFUserInfo; +} + class Player; class DBHelper : public a8::Singleton { @@ -30,5 +35,23 @@ class DBHelper : public a8::Singleton void SetEventStatus(long long idx, const std::string& target_id, int status); + void ShuaOfflineUsers(Player* hum); +public: + std::map cache_users_hash; + std::vector cache_users_list; + +private: + + void AddCache( + const std::string& account_id, + const std::string& nickname, + const std::string& avatar_url, + int sex, + long long data_version1, + long long user_value1, + long long user_value2, + long long user_value3, + int last_logintime + ); }; diff --git a/server/imserver/player.cc b/server/imserver/player.cc index 3ddbdc5..5e64e6d 100644 --- a/server/imserver/player.cc +++ b/server/imserver/player.cc @@ -737,6 +737,18 @@ void Player::FillMFUserInfo(cs::MFUserInfo* user_info) TypeConvert::Convert(myself.temp_custom_data, *(user_info->mutable_temp_custom_data())); } +std::set& Player::GetExcludeAccountIds() +{ + for (auto& pair : friend_hash_) { + exclude_account_ids_.insert(pair.first); + } + for (auto& pair : black_hash_) { + exclude_account_ids_.insert(pair.first); + } + exclude_account_ids_.insert(AccountId()); + return exclude_account_ids_; +} + void Player::MarkDirty() { if (!dirty_) { diff --git a/server/imserver/player.h b/server/imserver/player.h index 622dfb9..84e1429 100644 --- a/server/imserver/player.h +++ b/server/imserver/player.h @@ -20,7 +20,6 @@ class Player RoleData role_data; long ip_saddr = 0; int account_registertime = 0; - std::set exclude_account_ids; public: void Init(); @@ -105,6 +104,7 @@ class Player void FillIMMsgConext(ss::MFIMMsgConext* context); void Update(long long tick); void FillMFUserInfo(cs::MFUserInfo* user_info); + std::set& GetExcludeAccountIds(); const std::string AccountId(); const std::string SessionId(); @@ -161,6 +161,7 @@ private: long long last_run_tick_ = 0; std::map event_hash_; int red_point_flags_ = 0; + std::set exclude_account_ids_; std::map friend_hash_; std::map black_hash_; diff --git a/server/imserver/playermgr.cc b/server/imserver/playermgr.cc index e8c7de2..e846d6f 100644 --- a/server/imserver/playermgr.cc +++ b/server/imserver/playermgr.cc @@ -143,7 +143,28 @@ void PlayerMgr::_SS_IM_PushUserOnlineState(f8::MsgHdr& hdr, const ss::SS_IM_Push void PlayerMgr::_SS_IM_RandomUsersRequest(f8::MsgHdr& hdr, const ss::SS_IM_RandomUsersRequest& msg) { + std::set exclude_account_ids; + for (auto& account_id : msg.exclude_account_ids()) { + exclude_account_ids.insert(account_id); + } + std::vector human_list; + human_list.reserve(100); + for (auto& pair : accountid_hash_) { + if (pair.second->GetFriendNum() < MAX_FRIEND_NUM && + exclude_account_ids.find(pair.second->AccountId()) == exclude_account_ids.end()) { + human_list.push_back(pair.second); + } + } + std::random_shuffle(human_list.begin(), human_list.end()); + ss::SS_IM_RandomUsersResponse respmsg; + *respmsg.mutable_context() = msg.context(); + for (size_t i = 0; i < 4; ++i) { + if (i < human_list.size()) { + human_list[i]->FillMFUserInfo(respmsg.add_user_infos()); + } + } + IMListener::Instance()->SendMsg(hdr.socket_handle, respmsg); } void PlayerMgr::_SS_IM_RandomUsersResponse(f8::MsgHdr& hdr, const ss::SS_IM_RandomUsersResponse& msg)