#include "precompile.h" #include #include #include #include "player.h" #include "playermgr.h" #include "dbengine.h" #include "MSConnMgr.h" #include "dbengine.h" #include "dbhelper.h" #include "synchelper.h" #include "app.h" #include "typeconvert.h" #include "playermgr.h" #include "IMConn.h" #include "IMConnMgr.h" #include "IMListener.h" #include "MSConn.h" #include "MSConnMgr.h" #include "handlermgr.h" void Player::Init() { myself.hum = this; myself.crc32_code = a8::openssl::Crc32 ( (unsigned char*)myself.base_data.account_id.data(), myself.base_data.account_id.size() ); NotifyOnline(); a8::Timer::Instance()->AddRepeatTimerAndAttach ( 1000 * 3 + (rand() % 3000), a8::XParams() .SetSender(this), [] (const a8::XParams& param) { Player* hum = (Player*)param.sender.GetUserData(); hum->ProcessEventTimerFunc(); }, &timer_attacher.timer_list_ ); if (App::Instance()->IsTimeToReset(role_data.last_save_time)) { OnDailyReset(); } RecalcRedPoint(); } void Player::UnInit() { SaveToDB(a8::XParams(), nullptr, nullptr); timer_attacher.ClearTimerList(); for (auto& pair : friend_hash_) { if (!list_empty(&pair.second->watch_node)) { PlayerMgr::Instance()->UnWatchPlayer(pair.second); delete pair.second; } } for (auto& pair : apply_hash_) { delete pair.second; } friend_hash_.clear(); NotifyOffline(); } void Player::Deserialize(const ss::MFUserDB& user_db) { for (auto& friend_db : user_db.friends()) { Friend* friendobj = new Friend; TypeConvert::Convert(friend_db.base_data(), friendobj->base_data); AddFriend(friendobj); } role_data.today_apply_times = user_db.role_data().today_apply_times(); role_data.save_count = user_db.role_data().save_count(); role_data.last_save_time = user_db.role_data().last_save_time(); } void Player::Serialize(ss::MFUserDB& user_db) { for (auto& pair : friend_hash_) { auto p = user_db.add_friends(); TypeConvert::Convert(pair.second->base_data, *(p->mutable_base_data())); } user_db.mutable_role_data()->set_today_apply_times(role_data.today_apply_times); user_db.mutable_role_data()->set_save_count(role_data.save_count); user_db.mutable_role_data()->set_last_save_time(role_data.last_save_time); } void Player::_CMPing(f8::MsgHdr& hdr, const cs::CMPing& msg) { cs::SMPing respmsg; SendMsg(respmsg); } void Player::_CMUpdateUserInfo(f8::MsgHdr& hdr, const cs::CMUpdateUserInfo& msg) { if (msg.has_nickname()) { myself.base_data.nickname = msg.nickname(); } if (msg.has_avatar_url()) { myself.base_data.avatar_url = msg.avatar_url(); } if (msg.has_sex()) { myself.base_data.sex = msg.sex(); } if (msg.has_user_value1()) { myself.base_data.user_value1 = msg.user_value1(); } if (msg.has_user_value2()) { myself.base_data.user_value2 = msg.user_value2(); } if (msg.has_user_value3()) { myself.base_data.user_value3 = msg.user_value3(); } OnDataVersion1Change(); } void Player::_CMUpdateTempCustomData(f8::MsgHdr& hdr, const cs::CMUpdateTempCustomData& msg) { if (msg.temp_custom_data().has_value1()) { myself.temp_custom_data.value1 = msg.temp_custom_data().value1(); } if (msg.temp_custom_data().has_value2()) { myself.temp_custom_data.value2 = msg.temp_custom_data().value2(); } if (msg.temp_custom_data().has_value3()) { myself.temp_custom_data.value2 = msg.temp_custom_data().value3(); } OnTempCustomDataChange(); } void Player::_CMFriendList(f8::MsgHdr& hdr, const cs::CMFriendList& msg) { PushFriendList(); } void Player::_CMFriendApply(f8::MsgHdr& hdr, const cs::CMFriendApply& msg) { cs::SMFriendApply respmsg; if (GetFriendById(msg.friend_id())) { respmsg.set_errcode(1); respmsg.set_errmsg("已经是好友"); SendMsg(respmsg); return; } if (msg.friend_id() == AccountId()) { respmsg.set_errcode(2); respmsg.set_errmsg("不能邀请自己"); SendMsg(respmsg); return; } if (f8::ExtractGameIdFromAccountId(AccountId()) != f8::ExtractGameIdFromAccountId(msg.friend_id())) { respmsg.set_errcode(3); respmsg.set_errmsg("不能邀请其他游戏玩家"); SendMsg(respmsg); return; } if (role_data.today_apply_times > DAILY_APPLY_FRIEND_TIMES) { respmsg.set_errcode(4); respmsg.set_errmsg("今天邀请次数已经用完不能再邀请"); SendMsg(respmsg); return; } ++role_data.today_apply_times; SendMsg(respmsg); DBHelper::Instance()->AddFriendApply(this, msg.friend_id()); } void Player::_CMFriendApplyList(f8::MsgHdr& hdr, const cs::CMFriendApplyList& msg) { #if 0 if (last_apply_idx_ > 0 && last_apply_idx_ >= DBEngine::Instance()->GetFriendApplyCurrIdx(myself.crc32_code)) { cs::SMFriendApplyList respmsg; FillApplyList(msg.paging(), respmsg); SendMsg(respmsg); return; } #endif auto on_ok = [] (a8::XParams& param, const f8::DataSet* data_set) { cs::MFPaging* paging = (cs::MFPaging*)param.param2.GetUserData(); Player* hum = PlayerMgr::Instance()->GetPlayerByAccountId(param.sender.GetString()); if (hum && hum->socket_handle == param.param1.GetInt()) { for (auto& row : *data_set) { FriendApply apply; apply.idx = a8::XValue(row[0]); apply.applyid = a8::XValue(row[1]); apply.target_id = row[2]; apply.base_data.account_id = row[3]; apply.base_data.nickname = row[4]; apply.base_data.avatar_url = row[5]; apply.base_data.sex = a8::XValue(row[6]); apply.base_data.base_data_version = a8::XValue(row[7]); apply.base_data.user_value1 = a8::XValue(row[8]); apply.base_data.user_value2 = a8::XValue(row[9]); apply.base_data.user_value3 = a8::XValue(row[10]); hum->apply_list_.push_back(apply); if (apply.idx > hum->last_apply_idx_) { hum->last_apply_idx_ = apply.idx; } } cs::SMFriendApplyList respmsg; hum->FillApplyList(*paging, respmsg); hum->SendMsg(respmsg); a8::UnSetBitFlag(hum->red_point_flags_, RPF_Apply); hum->SyncRedPoint(); } delete paging; }; auto on_error = [] (a8::XParams& param, int error_code, const std::string& error_msg) { cs::MFPaging* paging = (cs::MFPaging*)param.param2.GetUserData(); Player* hum = PlayerMgr::Instance()->GetPlayerByAccountId(param.sender.GetString()); if (hum && hum->socket_handle == param.param1.GetInt()) { cs::SMFriendApplyList respmsg; hum->FillApplyList(*paging, respmsg); hum->SendMsg(respmsg); } delete paging; }; cs::MFPaging* paging_copy = new cs::MFPaging; *paging_copy = msg.paging(); #if 1 paging_copy->set_curr_page(0); paging_copy->set_page_size(100); #endif a8::XObject conn_info = DBEngine::Instance()->GetConnInfo(myself.crc32_code); DBEngine::Instance()->ExecAsyncQuery ( conn_info, "SELECT idx, applyid, target_id, sender_id, sender_nickname, " " sender_avatar_url, sender_sex, sender_data_version1, " " sender_user_value1, sender_user_value2, sender_user_value3, status " "FROM friend_apply WHERE idx > %d AND target_id='%s' AND status=0;", { last_apply_idx_, myself.base_data.account_id }, a8::XParams() .SetSender(myself.base_data.account_id) .SetParam1(hdr.socket_handle) .SetParam2(paging_copy), on_ok, on_error, myself.crc32_code ); } void Player::_CMFriendAgree(f8::MsgHdr& hdr, const cs::CMFriendAgree& msg) { cs::SMFriendAgree respmsg; if (GetFriendById(msg.apply().base_data().account_id())) { respmsg.set_errcode(0); respmsg.set_errmsg(""); SendMsg(respmsg); DBHelper::Instance()->SetFriendApplyStatus( myself.crc32_code, msg.apply().target_id(), AccountId(), 1 ); return; } if (msg.apply().base_data().account_id() == AccountId()) { respmsg.set_errcode(2); respmsg.set_errmsg("不能添加自己"); SendMsg(respmsg); return; } if (!CanAddFriend(msg.apply().base_data().account_id())) { respmsg.set_errcode(3); respmsg.set_errmsg("您的好友数已达到上限"); SendMsg(respmsg); return; } Friend* friendobj = new Friend; TypeConvert::Convert(msg.apply().base_data(), friendobj->base_data); if (AddFriend(friendobj) == 0) { NotifyUserInfoUpdate(friendobj); SyncHelper::Instance()->SyncNewFriend(this, friendobj->base_data.account_id); MarkDirty(); } else { A8_SAFE_DELETE(friendobj); } SendMsg(respmsg); DBHelper::Instance()->SetFriendApplyStatus ( myself.crc32_code, msg.apply().target_id(), AccountId(), 1 ); ClearApplyByTarget(msg.apply().target_id()); } void Player::_CMFriendRefuse(f8::MsgHdr& hdr, const cs::CMFriendRefuse& msg) { cs::SMFriendRefuse respmsg; SendMsg(respmsg); DBHelper::Instance()->SetFriendApplyStatus ( myself.crc32_code, msg.apply().idx(), msg.apply().target_id(), AccountId(), 2 ); ClearApplyByIdx(msg.apply().idx()); } void Player::_CMFriendDelete(f8::MsgHdr& hdr, const cs::CMFriendDelete& msg) { cs::SMFriendDelete respmsg; Friend* p = GetFriendById(msg.friend_id()); if (p) { RemoveFriend(p->base_data.account_id); } respmsg.set_friend_id(msg.friend_id()); SendMsg(respmsg); { cs::SMDeleteFriendNotify notifymsg; notifymsg.add_user_list(msg.friend_id()); SendMsg(notifymsg); } } void Player::_CMFriendBlackList(f8::MsgHdr& hdr, const cs::CMFriendBlackList& msg) { } void Player::_CMFriendAddBlack(f8::MsgHdr& hdr, const cs::CMFriendAddBlack& msg) { } void Player::_CMFriendDeleteBlack(f8::MsgHdr& hdr, const cs::CMFriendDeleteBlack& msg) { } void Player::_CMSendChatMsg(f8::MsgHdr& hdr, const cs::CMSendChatMsg& msg) { ss::SS_IM_SendChatMsg ss_msg; FillIMMsgConext(ss_msg.mutable_context()); ss_msg.set_chat_channel(msg.chat_channel()); ss_msg.set_msg(msg.msg()); Friend* friend_data = GetFriendById(msg.target()); if (friend_data) { SendSSMsg(*friend_data, ss_msg); } } void Player::_CMSendCustomMsg(f8::MsgHdr& hdr, const cs::CMSendCustomMsg& msg) { ss::SS_IM_SendCustomMsg ss_msg; FillIMMsgConext(ss_msg.mutable_context()); ss_msg.set_msg(msg.msg()); ss_msg.set_param1(msg.param1()); ss_msg.set_param2(msg.param2()); ss_msg.set_param3(msg.param3()); for (auto& target_id : msg.target_list()) { Friend* friend_data = GetFriendById(target_id); if (friend_data) { ss_msg.set_target(target_id); SendSSMsg(*friend_data, ss_msg); } } } void Player::_CMGroupCreate(f8::MsgHdr& hdr, const cs::CMGroupCreate& msg) { #if 0 if (myself.base_data.group_id != 0) { cs::SMGroupCreate respmsg; respmsg.set_errcode(1); respmsg.set_errmsg("你已经有群"); SendMsg(respmsg); return; } ForwardGroupCMMsg(hdr, App::Instance()->NewUUID()); #endif } void Player::_CMGroupJoin(f8::MsgHdr& hdr, const cs::CMGroupJoin& msg) { #if 0 if (myself.base_data.group_id != 0) { cs::SMGroupJoin respmsg; respmsg.set_errcode(1); respmsg.set_errmsg("你已经有群"); SendMsg(respmsg); return; } ForwardGroupCMMsg(hdr, myself.base_data.group_id); #endif } void Player::_CMGroupAgree(f8::MsgHdr& hdr, const cs::CMGroupAgree& msg) { #if 0 if (myself.base_data.group_id == 0) { cs::SMGroupAgree respmsg; respmsg.set_errcode(2); respmsg.set_errmsg("你还没有群"); SendMsg(respmsg); return; } ForwardGroupCMMsg(hdr, myself.base_data.group_id); #endif } void Player::_CMGroupKick(f8::MsgHdr& hdr, const cs::CMGroupKick& msg) { #if 0 if (myself.base_data.group_id == 0) { cs::SMGroupKick respmsg; respmsg.set_errcode(2); respmsg.set_errmsg("你还没有群"); SendMsg(respmsg); return; } ForwardGroupCMMsg(hdr, myself.base_data.group_id); #endif } void Player::_CMGroupQuit(f8::MsgHdr& hdr, const cs::CMGroupQuit& msg) { #if 0 if (myself.base_data.group_id == 0) { cs::SMGroupQuit respmsg; respmsg.set_errcode(2); respmsg.set_errmsg("你还没有群"); SendMsg(respmsg); return; } ForwardGroupCMMsg(hdr, myself.base_data.group_id); #endif } void Player::_CMGroupDismiss(f8::MsgHdr& hdr, const cs::CMGroupDismiss& msg) { #if 0 if (myself.base_data.group_id == 0) { cs::SMGroupQuit respmsg; respmsg.set_errcode(2); respmsg.set_errmsg("你还没有群"); SendMsg(respmsg); return; } ForwardGroupCMMsg(hdr, myself.base_data.group_id); #endif } void Player::_CMGroupRename(f8::MsgHdr& hdr, const cs::CMGroupRename& msg) { #if 0 if (myself.base_data.group_id == 0) { cs::SMGroupRename respmsg; respmsg.set_errcode(2); respmsg.set_errmsg("你还没有群"); SendMsg(respmsg); return; } ForwardGroupCMMsg(hdr, myself.base_data.group_id); #endif } void Player::_SS_IM_FriendAgreeRequest(f8::MsgHdr& hdr, const ss::SS_IM_FriendAgreeRequest& msg) { if (!GetFriendById(msg.context().user_info().base_data().account_id())) { Friend* friendobj = new Friend; TypeConvert::Convert(msg.context().user_info().base_data(), friendobj->base_data); TypeConvert::Convert(msg.context().user_info().temp_custom_data(), friendobj->temp_custom_data); if (!AddFriend(friendobj)) { delete friendobj; } } f8::MsgHdr* hdr_copy = hdr.Clone(); ss::SS_IM_FriendAgreeRequest* msg_copy = new ss::SS_IM_FriendAgreeRequest; *msg_copy = msg; SaveToDB ( a8::XParams() .SetSender(hdr_copy) .SetParam1(msg_copy), [] (a8::XParams& param, const f8::DataSet* data_set) { f8::MsgHdr* hdr_copy = (f8::MsgHdr*)param.sender.GetUserData(); ss::SS_IM_FriendAgreeRequest* msg_copy = (ss::SS_IM_FriendAgreeRequest*)param.param1.GetUserData(); ss::SS_IM_FriendAgreeResponse respmsg; *respmsg.mutable_context() = msg_copy->context(); respmsg.set_target_id(msg_copy->target_id()); IMListener::Instance()->SendMsg(hdr_copy->socket_handle, respmsg); f8::MsgHdr::Destroy(hdr_copy); delete msg_copy; }, [] (a8::XParams& param, int error_code, const std::string& error_msg) { f8::MsgHdr* hdr_copy = (f8::MsgHdr*)param.sender.GetUserData(); ss::SS_IM_FriendAgreeRequest* msg_copy = (ss::SS_IM_FriendAgreeRequest*)param.param1.GetUserData(); f8::MsgHdr::Destroy(hdr_copy); delete msg_copy; } ); } void Player::_SS_IM_FriendDeleteRequest(f8::MsgHdr& hdr, const ss::SS_IM_FriendDeleteRequest& msg) { f8::MsgHdr* hdr_copy = hdr.Clone(); ss::SS_IM_FriendDeleteRequest* msg_copy = new ss::SS_IM_FriendDeleteRequest; *msg_copy = msg; SaveToDB ( a8::XParams() .SetSender(hdr_copy) .SetParam1(msg_copy), [] (a8::XParams& param, const f8::DataSet* data_set) { f8::MsgHdr* hdr_copy = (f8::MsgHdr*)param.sender.GetUserData(); ss::SS_IM_FriendDeleteRequest* msg_copy = (ss::SS_IM_FriendDeleteRequest*)param.param1.GetUserData(); f8::MsgHdr::Destroy(hdr_copy); delete msg_copy; }, [] (a8::XParams& param, int error_code, const std::string& error_msg) { f8::MsgHdr* hdr_copy = (f8::MsgHdr*)param.sender.GetUserData(); ss::SS_IM_FriendDeleteRequest* msg_copy = (ss::SS_IM_FriendDeleteRequest*)param.param1.GetUserData(); f8::MsgHdr::Destroy(hdr_copy); delete msg_copy; } ); } void Player::_SS_IM_FriendApply(f8::MsgHdr& hdr, const ss::SS_IM_FriendApply& msg) { a8::SetBitFlag(red_point_flags_, RPF_Apply); SyncRedPoint(); } void Player::ReLogin(f8::MsgHdr& hdr, const cs::CMLogin& msg) { cs::SMLogin respmsg; WSListener::Instance()->SendToClient(hdr.socket_handle, 0, respmsg); PlayerMgr::Instance()->ReBindSocket(hdr.socket_handle, this); } void Player::FillFriendList(::google::protobuf::RepeatedPtrField< ::cs::MFUserInfo >* friend_list) { { auto p = friend_list->Add(); TypeConvert::Convert(myself.base_data, *(p->mutable_base_data())); TypeConvert::Convert(myself.temp_custom_data, *(p->mutable_temp_custom_data())); } for (auto& pair : friend_hash_) { auto p = friend_list->Add(); TypeConvert::Convert(pair.second->base_data, *(p->mutable_base_data())); TypeConvert::Convert(pair.second->temp_custom_data, *(p->mutable_temp_custom_data())); } } void Player::FillIMMsgConext(ss::MFIMMsgConext* context) { FillMFUserInfo(context->mutable_user_info()); context->set_seqid(App::Instance()->NewSeqId()); } void Player::ForwardGroupCMMsg(f8::MsgHdr& hdr, long long hash_code) { ss::SS_MS_ForwardGroupCMMsg msg; FillIMMsgConext(msg.mutable_context()); if (hdr.buflen > 0) { msg.mutable_payload()->assign(hdr.buf, hdr.buflen); } MSConnMgr::Instance()->SendMsg(msg, hash_code); } void Player::FillMFUserInfo(cs::MFUserInfo* user_info) { } void Player::MarkDirty() { if (!dirty_) { dirty_ = true; dirty_timer_ = a8::Timer::Instance()->AddDeadLineTimerAndAttach (1000 * 60, a8::XParams() .SetSender((void*)this), [] (const a8::XParams& param) { Player* hum = (Player*)param.sender.GetUserData(); hum->SaveToDB(a8::XParams(), nullptr, nullptr); }, &timer_attacher.timer_list_, [] (const a8::XParams& param) { Player* hum = (Player*)param.sender.GetUserData(); hum->dirty_timer_ = nullptr; } ); } } void Player::SaveToDB(a8::XParams param, f8::AsyncDBOnOkFunc on_ok, f8::AsyncDBOnErrorFunc on_error) { ss::MFUserDB user_db; Serialize(user_db); std::string friend_data; user_db.SerializeToString(&friend_data); a8::XObject conn_info = DBEngine::Instance()->GetConnInfo(myself.crc32_code); DBEngine::Instance()->ExecAsyncScript ( conn_info, "UPDATE `user` SET friend_data='%s', modifytime=%d, " " nickname='%s', avatar_url='%s', sex=%d, data_version1=%d " "WHERE account_id='%s';", { friend_data, App::Instance()->nowtime, myself.base_data.nickname, myself.base_data.avatar_url, myself.base_data.sex, myself.base_data.base_data_version, myself.base_data.account_id }, a8::XParams(), on_ok, on_error, myself.crc32_code ); ++role_data.save_count; role_data.last_save_time = App::Instance()->nowtime; } Friend* Player::GetFriendById(const std::string& friend_id) { auto itr = friend_hash_.find(friend_id); return itr != friend_hash_.end() ? itr->second : nullptr; } void Player::FillApplyList(const cs::MFPaging& paging, cs::SMFriendApplyList& respmsg) { int i = 0; int start = paging.curr_page() * paging.page_size(); for (const FriendApply& apply : apply_list_) { if (i >= start && i < start + paging.page_size()) { TypeConvert::Convert(apply, *respmsg.add_apply_list()); } ++i; } *respmsg.mutable_paging() = paging; if (paging.page_size() > 0) { respmsg.mutable_paging()->set_total_page(ceil(i / paging.page_size())); } else { respmsg.mutable_paging()->set_total_page(1); } } void Player::NotifyOnline() { } void Player::NotifyOffline() { } void Player::OnDataVersion1Change() { ++myself.base_data.base_data_version; if (!update_user_info_timer_) { update_user_info_timer_ = a8::Timer::Instance()->AddDeadLineTimerAndAttach ( 1000 * 3, a8::XParams() .SetSender(this), [] (const a8::XParams& param) { Player* hum = (Player*)param.sender.GetUserData(); hum->InternalUpdateUserInfo(); hum->SyncOtherFriend(); }, &timer_attacher.timer_list_, [] (const a8::XParams& param) { Player* hum = (Player*)param.sender.GetUserData(); hum->update_user_info_timer_ = nullptr; } ); } } void Player::OnTempCustomDataChange() { if (!update_user_info_timer_) { update_user_info_timer_ = a8::Timer::Instance()->AddDeadLineTimerAndAttach ( 1000 * 3, a8::XParams() .SetSender(this), [] (const a8::XParams& param) { Player* hum = (Player*)param.sender.GetUserData(); hum->InternalUpdateUserInfo(); hum->SyncOtherFriend(); }, &timer_attacher.timer_list_, [] (const a8::XParams& param) { Player* hum = (Player*)param.sender.GetUserData(); hum->update_user_info_timer_ = nullptr; } ); } } void Player::InternalSendSSMsg(const Friend& friend_data, int msgid, ::google::protobuf::Message& msg) { #if 0 if (friend_data.server_key.empty()) { return; } IMConn* conn = IMConnMgr::Instance()->GetConnByKey(friend_data.server_key); if (conn) { conn->SendMsg(msgid, msg); } #endif #if 1 { Player* hum = PlayerMgr::Instance()->GetPlayerByAccountId(friend_data.base_data.account_id); if (hum) { f8::NetMsgHandler* handler = f8::GetNetMsgHandler(&HandlerMgr::Instance()->imcmsghandler, msgid); if (!handler || handler->handlerid != HID_PlayerMgr) { return; } f8::MsgHdr hdr; hdr.msgid = msgid; hdr.seqid = 0; hdr.socket_handle = 0; int packlen = msg.ByteSize(); char* buff = nullptr; if (packlen) { buff = (char*)malloc(packlen); msg.SerializeToArray(buff, packlen); } hdr.buf = buff; hdr.buflen = packlen; hdr.offset = 0; hdr.ip_saddr = 0; ProcessNetMsg(handler, PlayerMgr::Instance(), hdr); if (buff) { free(buff); } } } #endif } int Player::AddFriend(Friend* friendobj) { if (friendobj->base_data.account_id == AccountId()) { return -2; } if (!GetFriendById(friendobj->base_data.account_id)) { INIT_LIST_HEAD(&friendobj->watch_node); friendobj->crc32_code = a8::openssl::Crc32 ( (unsigned char*)friendobj->base_data.account_id.data(), friendobj->base_data.account_id.size() ); friendobj->hum = this; friend_hash_[friendobj->base_data.account_id] = friendobj; NotifyUserInfoUpdate(friendobj); PlayerMgr::Instance()->WatchPlayer(friendobj); return 0; } return -1; } void Player::RemoveFriend(const std::string& account_id) { Friend* friendobj = GetFriendById(account_id); if (friendobj) { { cs::SMDeleteFriendNotify notifymsg; notifymsg.add_user_list(account_id); SendMsg(notifymsg); } SyncHelper::Instance()->SyncDeleteFriend(this, friendobj->base_data.account_id); PlayerMgr::Instance()->UnWatchPlayer(friendobj); friend_hash_.erase(account_id); delete friendobj; MarkDirty(); } } void Player::Update(long long tick) { last_run_tick_ = tick; ProcessEvent(); if (App::Instance()->nowtime - role_data.last_save_time > 1000 * 60) { role_data.last_save_time = App::Instance()->nowtime; SaveToDB(a8::XParams(), nullptr, nullptr); } } const std::string Player::AccountId() { return myself.base_data.account_id; } const std::string Player::SessionId() { return role_data.session_id; } int Player::GetFriendNum() { return friend_hash_.size(); } void Player::InternalUpdateUserInfo() { ss::SS_IM_UpdateUserInfo ss_msg; FillMFUserInfo(ss_msg.mutable_user_info()); MSConnMgr::Instance()->TraverseMSConn ( [&ss_msg] (MSConn* conn) { conn->SendMsg(ss_msg); return true; } ); IMConnMgr::Instance()->TraverseIMConn ( [&ss_msg] (IMConn* conn) { conn->SendMsg(ss_msg); return true; } ); NotifyUserInfoUpdate(&myself); MarkDirty(); } void Player::NotifyUserInfoUpdate(Friend* friend_data) { cs::SMUserInfoUpdate msg; auto p = msg.add_user_infos(); TypeConvert::Convert(friend_data->base_data, *p->mutable_base_data()); TypeConvert::Convert(friend_data->temp_custom_data, *p->mutable_temp_custom_data()); SendMsg(msg); } void Player::PushFriendList() { cs::SMFriendList respmsg; FillFriendList(respmsg.mutable_friend_list()); SendMsg(respmsg); } void Player::SyncOtherFriend() { cs::SMUserInfoUpdate msg; auto p = msg.add_user_infos(); TypeConvert::Convert(myself.base_data, *p->mutable_base_data()); TypeConvert::Convert(myself.temp_custom_data, *p->mutable_temp_custom_data()); for (auto& pair : friend_hash_) { Player* hum = PlayerMgr::Instance()->GetPlayerByAccountId(pair.second->base_data.account_id); if (hum) { Friend* friend_data = hum->GetFriendById(AccountId()); if (friend_data) { *friend_data = myself; } hum->SendMsg(msg); } } } void Player::ProcessEventTimerFunc() { if (curr_max_event_idx_ >= DBEngine::Instance()->GetEventCurrIdx(myself.crc32_code)) { return; } if (last_event_idx_ >= curr_max_event_idx_) { curr_max_event_idx_ = DBEngine::Instance()->GetEventCurrIdx(myself.crc32_code); } if (last_event_idx_ >= curr_max_event_idx_) { return; } auto on_ok = [] (a8::XParams& param, const f8::DataSet* data_set) { std::string account_id = param.sender.GetString(); long long curr_max_event_idx = param.param1; #if 0 long long last_event_idx = param.param2; #endif Player* hum = PlayerMgr::Instance()->GetPlayerByAccountId(account_id); if (hum) { hum->OnFetchEvent(curr_max_event_idx, data_set); } }; auto on_error = [] (a8::XParams& param, int error_code, const std::string& error_msg) { }; a8::XObject conn_info = DBEngine::Instance()->GetConnInfo(myself.crc32_code); DBEngine::Instance()->ExecAsyncQuery ( conn_info, "SELECT idx, sender_id, target_id, event_name, param1, param2, " " param3, event_data, status, createtime " "FROM `event' WHERE idx > %d AND target_id='%s' AND status=0;", { last_event_idx_, myself.base_data.account_id }, a8::XParams() .SetSender(myself.base_data.account_id) .SetParam1(curr_max_event_idx_) .SetParam1(last_event_idx_), on_ok, on_error, myself.crc32_code ); } void Player::OnFetchEvent(long long max_event_idx, const f8::DataSet* data_set) { curr_max_event_idx_ = max_event_idx; if (data_set) { for (auto& row : *data_set) { Event event; event.idx = a8::XValue(row[0]); event.sender_id = row[1]; event.target_id = row[2]; event.event_name = row[3]; event.param1 = row[4]; event.param2 = row[5]; event.param3 = row[6]; event.event_data = row[7]; event.status = a8::XValue(row[8]); event.createtime = a8::XValue(row[9]); event_hash_[event.idx] = event; } } } void Player::ProcessEvent() { if (event_hash_.empty()) { return; } std::vector processed_events; processed_events.reserve(100); for (auto& pair : event_hash_) { if (processed_events.size() > 100) { break; } Event& event = pair.second; if (event.event_name == EVENT_FRIEND_AGREE) { OnFriendAgreeEvent(event); DBHelper::Instance()->SetEventStatus(event.idx, AccountId(), 1); } else if (event.event_name == EVENT_FRIEND_DELETE) { OnFriendDeleteEvent(event); DBHelper::Instance()->SetEventStatus(event.idx, AccountId(), 1); } processed_events.push_back(pair.first); } for (long long event_id : processed_events) { event_hash_.erase(event_id); } } void Player::OnFriendAgreeEvent(Event& event) { if (GetFriendById(event.sender_id)) { return; } if (!CanAddFriend(event.sender_id)) { return; } Friend* friendobj = new Friend; { cs::MFUserInfo user_db; user_db.ParseFromString(event.event_data); TypeConvert::Convert(user_db.base_data(), friendobj->base_data); } friendobj->base_data.account_id = event.sender_id; AddFriend(friendobj); } void Player::OnFriendDeleteEvent(Event& event) { if (!GetFriendById(event.sender_id)) { return; } RemoveFriend(event.sender_id); } bool Player::CanAddFriend(const std::string& account_id) { if (GetFriendNum() >= MAX_FRIEND_NUM) { return false; } if (GetFriendById(account_id)) { return false; } int target_channel = f8::ExtractGameIdFromAccountId(account_id); int target_gameid = f8::ExtractChannelIdFromAccountId(account_id); int self_channel = f8::ExtractGameIdFromAccountId(AccountId()); int self_gameid = f8::ExtractChannelIdFromAccountId(AccountId()); if (target_gameid != self_gameid) { return false; } if (self_channel != 6000 && target_channel != 6000) { if (self_channel != target_channel) { return false; } } return true; } void Player::SyncRedPoint() { cs::SMUpdateRedPointNotify notifymsg; notifymsg.set_red_point_flags(red_point_flags_); SendMsg(notifymsg); } void Player::OnDailyReset() { role_data.today_apply_times = 0; } void Player::RecalcRedPoint() { auto on_ok = [] (a8::XParams& param, const f8::DataSet* data_set) { Player* hum = PlayerMgr::Instance()->GetPlayerByAccountId(param.sender.GetString()); if (hum) { if (data_set && data_set->size() > 0) { a8::SetBitFlag(hum->red_point_flags_, RPF_Apply); hum->SyncRedPoint(); } } }; auto on_error = [] (a8::XParams& param, int error_code, const std::string& error_msg) { }; a8::XObject conn_info = DBEngine::Instance()->GetConnInfo(myself.crc32_code); DBEngine::Instance()->ExecAsyncQuery ( conn_info, "SELECT idx, applyid " "FROM friend_apply WHERE idx > %d AND target_id='%s' AND status=0 LIMIT 1;", { last_apply_idx_, myself.base_data.account_id }, a8::XParams() .SetSender(myself.base_data.account_id), on_ok, on_error, myself.crc32_code ); } void Player::ClearApplyByIdx(long long idx) { auto itr = apply_hash_.find(idx); if (itr != apply_hash_.end()) { delete itr->second; apply_hash_.erase(itr); } } void Player::ClearApplyByTarget(const std::string& target_id) { std::vector deleted_applys; for (auto& pair : apply_hash_) { if (pair.second->target_id == target_id) { deleted_applys.push_back(pair.first); } } for (auto idx : deleted_applys) { ClearApplyByIdx(idx); } }