relation/server/imserver/asynctaskmgr.cc
aozhiwei c3982fb82f 1
2022-04-15 10:33:32 +08:00

289 lines
9.2 KiB
C++

#include "precompile.h"
#include<random>
#include <a8/timer.h>
#include <a8/openssl.h>
#include "asynctaskmgr.h"
#include "app.h"
#include "player.h"
#include "playermgr.h"
#include "dbhelper.h"
#include "dbengine.h"
#include "cs_proto.pb.h"
#include "ss_proto.pb.h"
struct AsyncTaskContext
{
long long seqid = 0;
std::string account_id;
int socket_handle = 0;
Player* hum = nullptr;
bool IsValid()
{
if (PlayerMgr::Instance()->GetPlayerByAccountId(account_id) != hum) {
return false;
}
if (hum->socket_handle != socket_handle) {
return false;
}
return true;
}
};
struct QueryUserStatusTask
{
AsyncTaskContext context;
std::map<std::string, cs::MFUserStatus> users;
void Done()
{
if (context.IsValid()) {
cs::SMQueryUserStatus msg;
for (auto& pair : users) {
cs::MFUserStatus* user = msg.add_status_list();
#if 1
*user = pair.second;
#else
user->set_account_id(pair.first);
user->set__online(pair.second ? 1 : 0);
#endif
}
context.hum->SendMsg(msg);
}
}
};
struct RecommandFriendTask
{
AsyncTaskContext context;
std::map<std::string, cs::MFUserInfo> recommand_friends;
void Done()
{
if (context.IsValid()) {
std::set<std::string>& exclude_account_ids = context.hum->GetExcludeAccountIds();
std::set<std::string> batch_account_ids;
int my_gameid = f8::ExtractGameIdFromAccountId
(context.account_id);
int my_channel = f8::ExtractChannelIdFromAccountId
(context.account_id);
cs::SMRecommandFriend msg;
for (auto& pair : recommand_friends) {
if (msg.friend_list_size() < 4) {
int target_gameid = f8::ExtractGameIdFromAccountId
(pair.second.base_data().account_id());
int target_channel = f8::ExtractChannelIdFromAccountId
(pair.second.base_data().account_id());
if (target_gameid != my_gameid || target_channel != my_channel) {
continue;
}
auto p = msg.add_friend_list() ;
*p = pair.second;
{
App::Instance()->PreProcAvatarUrl
(my_channel,
target_channel,
*p->mutable_base_data()->mutable_avatar_url());
}
exclude_account_ids.insert(pair.first);
batch_account_ids.insert(pair.first);
}
}
std::shuffle(DBHelper::Instance()->cache_users_list.begin(),
DBHelper::Instance()->cache_users_list.end(),
std::default_random_engine(rand()));
for (auto& user_info : DBHelper::Instance()->cache_users_list) {
if (msg.friend_list_size() >= 4) {
break;
}
if (exclude_account_ids.find(user_info->base_data().account_id()) ==
exclude_account_ids.end()) {
int target_gameid = f8::ExtractGameIdFromAccountId
(user_info->base_data().account_id());
int target_channel = f8::ExtractChannelIdFromAccountId
(user_info->base_data().account_id());
if (target_gameid != my_gameid || target_channel != my_channel) {
continue;
}
auto p = msg.add_friend_list();
*p = *user_info;
{
App::Instance()->PreProcAvatarUrl
(my_channel,
target_channel,
*p->mutable_base_data()->mutable_avatar_url());
}
exclude_account_ids.insert(user_info->base_data().account_id());
batch_account_ids.insert(user_info->base_data().account_id());
}
}
if (exclude_account_ids.size() > 50) {
std::vector<std::string> deleted_account_ids;
for (auto& account_id : exclude_account_ids) {
if (batch_account_ids.find(account_id) == batch_account_ids.end()) {
deleted_account_ids.push_back(account_id);
}
}
}
context.hum->SendMsg(msg);
}
}
};
struct CreateGuildTask
{
long long seqid = 0;
ss::MFIMMsgConext context;
cs::CMGuildCreate msg;
};
void AsyncTaskMgr::Init()
{
}
void AsyncTaskMgr::UnInit()
{
}
void AsyncTaskMgr::CreateQueryUserStatusTask(Player* hum, std::vector<std::string>& account_ids)
{
QueryUserStatusTask* task = new QueryUserStatusTask();
{
ss::SS_IM_QueryUserOnlineState msg;
hum->FillIMMsgConext(msg.mutable_context());
for (auto& account_id : account_ids) {
msg.add_account_ids(account_id);
}
hum->SendSSMsg(hum->myself, msg);
for (auto& account_id : account_ids) {
cs::MFUserStatus status;
status.set_account_id(account_id);
status.set__online(0);
task->users[account_id] = status;
}
FillAsyncTaskContext(hum, &task->context, msg.context().seqid());
query_user_status_tasks_[task->context.seqid] = task;
}
a8::Timer::Instance()->AddDeadLineTimer
(
200,
a8::XParams()
.SetSender(task),
[] (const a8::XParams& param)
{
QueryUserStatusTask* task = (QueryUserStatusTask*)param.sender.GetUserData();
task->Done();
},
[] (const a8::XParams& param)
{
QueryUserStatusTask* task = (QueryUserStatusTask*)param.sender.GetUserData();
AsyncTaskMgr::Instance()->RemoveQueryUserStatusTask(task->context.seqid);
}
);
}
void AsyncTaskMgr::CreateRecommandFriendTask(Player* hum)
{
RecommandFriendTask* task = new RecommandFriendTask();
{
ss::SS_IM_RandomUsersRequest msg;
hum->FillIMMsgConext(msg.mutable_context());
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,
a8::XParams()
.SetSender(task),
[] (const a8::XParams& param)
{
RecommandFriendTask* task = (RecommandFriendTask*)param.sender.GetUserData();
task->Done();
},
[] (const a8::XParams& param)
{
RecommandFriendTask* task = (RecommandFriendTask*)param.sender.GetUserData();
AsyncTaskMgr::Instance()->RemoveRecommandFriendTask(task->context.seqid);
}
);
}
void AsyncTaskMgr::_SS_IM_PushUserOnlineState(f8::MsgHdr& hdr, const ss::SS_IM_PushUserOnlineState& msg)
{
QueryUserStatusTask* task = GetQueryUserStatusTask(msg.context().seqid());
if (task) {
for (auto& user : msg.user_infos()) {
auto itr = task->users.find(user.base_data().account_id());
if (itr != task->users.end()) {
itr->second.set__online(1);
*itr->second.mutable_temp_custom_data() = user.temp_custom_data();
}
}
}
}
void AsyncTaskMgr::_SS_IM_RandomUsersResponse(f8::MsgHdr& hdr, const ss::SS_IM_RandomUsersResponse& msg)
{
RecommandFriendTask* task = GetRecommandFriendTask(msg.context().seqid());
if (task) {
for (auto& user_info : msg.user_infos()) {
task->recommand_friends[user_info.base_data().account_id()] = user_info;
}
}
}
QueryUserStatusTask* AsyncTaskMgr::GetQueryUserStatusTask(long long seqid)
{
auto itr = query_user_status_tasks_.find(seqid);
return itr != query_user_status_tasks_.end() ? itr->second : nullptr;
}
void AsyncTaskMgr::RemoveQueryUserStatusTask(long long seqid)
{
auto itr = query_user_status_tasks_.find(seqid);
if (itr != query_user_status_tasks_.end()) {
delete itr->second;
query_user_status_tasks_.erase(itr);
}
}
RecommandFriendTask* AsyncTaskMgr::GetRecommandFriendTask(long long seqid)
{
auto itr = recommand_friend_tasks_.find(seqid);
return itr != recommand_friend_tasks_.end() ? itr->second : nullptr;
}
void AsyncTaskMgr::RemoveRecommandFriendTask(long long seqid)
{
auto itr = recommand_friend_tasks_.find(seqid);
if (itr != recommand_friend_tasks_.end()) {
delete itr->second;
recommand_friend_tasks_.erase(itr);
}
}
void AsyncTaskMgr::FillAsyncTaskContext(Player* hum, AsyncTaskContext* context, long long seqid)
{
context->seqid = seqid;
context->account_id = hum->AccountId();
context->socket_handle = hum->socket_handle;
context->hum = hum;
}