327 lines
10 KiB
C++
327 lines
10 KiB
C++
#include "precompile.h"
|
|
|
|
#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, bool> users;
|
|
|
|
void Done()
|
|
{
|
|
if (context.IsValid()) {
|
|
cs::SMQueryUserStatus msg;
|
|
for (auto& pair : users) {
|
|
cs::MFUserStatus* user = msg.add_status_list();
|
|
user->set_account_id(pair.first);
|
|
user->set__online(pair.second ? 1 : 0);
|
|
}
|
|
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) {
|
|
task->users[account_id] = false;
|
|
}
|
|
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::CreateNewGuildTask(const ss::MFIMMsgConext& context, const cs::CMGuildCreate& msg)
|
|
{
|
|
auto on_ok =
|
|
[] (a8::XParams& param, const f8::DataSet* data_set)
|
|
{
|
|
};
|
|
auto on_error =
|
|
[] (a8::XParams& param, int error_code, const std::string& error_msg)
|
|
{
|
|
};
|
|
|
|
CreateGuildTask* task = new CreateGuildTask();
|
|
{
|
|
task->seqid = App::Instance()->NewSeqId();
|
|
task->context = context;
|
|
task->msg = msg;
|
|
}
|
|
std::string guild_id = a8::XValue(context.user_info().base_data().guild_id()).GetString();
|
|
long long crc32_code = a8::openssl::Crc32(
|
|
(unsigned char*)guild_id.data(),
|
|
guild_id.size()
|
|
);
|
|
a8::XObject conn_info = DBEngine::Instance()->GetConnInfo(crc32_code);
|
|
DBEngine::Instance()->ExecAsyncScript
|
|
(
|
|
conn_info,
|
|
"INSERT INTO `guild`(guild_id, guild_name, guild_lv, guild_exp, guild_badge, guild_declaration, "
|
|
" guild_status, owner_id, creator_id, guild_data, createtime, modifytime)"
|
|
"VALUES(%d, '%s', 1, 0, %d, '%s', '%s', %d, '%s', '%s', %d, %d);",
|
|
{
|
|
guild_id,
|
|
msg.guild_name(),
|
|
msg.guild_badge(),
|
|
msg.guild_declaration(),
|
|
kGuildCreatePending,
|
|
context.user_info().base_data().account_id(),
|
|
context.user_info().base_data().account_id(),
|
|
"",
|
|
App::Instance()->nowtime,
|
|
App::Instance()->nowtime
|
|
},
|
|
a8::XParams(),
|
|
on_ok,
|
|
on_error,
|
|
crc32_code
|
|
);
|
|
}
|
|
|
|
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()) {
|
|
if (task->users.find(user.base_data().account_id()) !=
|
|
task->users.end()) {
|
|
task->users[user.base_data().account_id()] = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
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;
|
|
}
|