1
This commit is contained in:
parent
c69747652e
commit
8f2a129f4b
419
server/imserver/chatmgr.cc
Normal file
419
server/imserver/chatmgr.cc
Normal file
@ -0,0 +1,419 @@
|
||||
#include "precompile.h"
|
||||
|
||||
#include <f8/timer.h>
|
||||
|
||||
#include "chatmgr.h"
|
||||
#include "player.h"
|
||||
#include "playermgr.h"
|
||||
|
||||
struct ChatedUserRec
|
||||
{
|
||||
bool has_unread_msg = false;
|
||||
bool dirty = false;
|
||||
std::map<std::string, ChatMsgRec> users;
|
||||
};
|
||||
|
||||
ChatMsgRec::~ChatMsgRec()
|
||||
{
|
||||
for (cs::MFChatMsg* msg : msg_list) {
|
||||
delete msg;
|
||||
}
|
||||
msg_list.clear();
|
||||
}
|
||||
|
||||
void ChatMsgRec::Pop(size_t max_num)
|
||||
{
|
||||
while (msg_list.size() > max_num) {
|
||||
msg_list.erase(msg_list.begin());
|
||||
}
|
||||
}
|
||||
|
||||
void ChatMsgRec::PopAndDelete(size_t max_num)
|
||||
{
|
||||
while (msg_list.size() > max_num) {
|
||||
cs::MFChatMsg* msg = *msg_list.begin();
|
||||
msg_list.erase(msg_list.begin());
|
||||
delete msg;
|
||||
}
|
||||
}
|
||||
|
||||
void ChatMgr::Init()
|
||||
{
|
||||
world_msg_id_ = a8::GetMilliSecond();
|
||||
guild_msg_id_ = a8::GetMilliSecond();
|
||||
temp_msg_id_ = a8::GetMilliSecond();
|
||||
}
|
||||
|
||||
void ChatMgr::UnInit()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void ChatMgr::FillSMUpdateChatRedPointNotify(Player* hum, cs::SMUpdateChatRedPointNotify& msg)
|
||||
{
|
||||
#if 0
|
||||
if (world_msgrec_.curr_id > hum->world_channel_last_id) {
|
||||
msg.add_has_unread_msg_channels(kCCWorld);
|
||||
}
|
||||
if (hum->GuildId() != 0) {
|
||||
auto itr = guild_msgrec_.find(hum->GuildId());
|
||||
if (itr != guild_msgrec_.end()) {
|
||||
if (itr->second.curr_id > hum->guild_channel_last_id) {
|
||||
msg.add_has_unread_msg_channels(kCCGuild);
|
||||
}
|
||||
}
|
||||
}
|
||||
ChatedUserRec* chated_user = GetChatedUser(hum->AccountId());
|
||||
if (chated_user) {
|
||||
if (chated_user->dirty) {
|
||||
chated_user->has_unread_msg = false;
|
||||
chated_user->dirty = false;
|
||||
}
|
||||
if (chated_user->has_unread_msg) {
|
||||
msg.add_has_unread_msg_channels(kCCPrivate);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void ChatMgr::FillSMUpdatePrivateChatRedPointNotify(Player* hum,
|
||||
cs::SMUpdatePrivateChatRedPointNotify& msg)
|
||||
{
|
||||
#if 0
|
||||
ChatedUserRec* chated_user = GetChatedUser(hum->AccountId());
|
||||
if (chated_user) {
|
||||
for (auto& pair : chated_user->users) {
|
||||
if (pair.second.curr_id < pair.second.last_id) {
|
||||
msg.add_has_unread_msg_accounts(pair.first);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void ChatMgr::ProcWorldChat(Player* hum, const cs::CMSendChatMsg& msg)
|
||||
{
|
||||
cs::MFChatMsg* p = new cs::MFChatMsg();
|
||||
FillMFChatMsg(p, hum, ++world_msg_id_, msg.chat_channel(), msg.msg_type(), msg.msg_body());
|
||||
|
||||
world_msgrec_.curr_id = world_msg_id_;
|
||||
world_msgrec_.msg_list.push_back(p);
|
||||
world_msgrec_.PopAndDelete(50);
|
||||
#if 0
|
||||
PlayerMgr::Instance()->TraversePlayer
|
||||
([](Player* hum)
|
||||
{
|
||||
ChatMgr::Instance()->SyncWorldChatMsg(hum);
|
||||
});
|
||||
#endif
|
||||
}
|
||||
|
||||
void ChatMgr::ProcPrivateChat(Player* hum, const cs::CMSendChatMsg& msg)
|
||||
{
|
||||
if (hum->AccountId() == msg.target()) {
|
||||
return;
|
||||
}
|
||||
#if 0
|
||||
Friend* target = hum->GetFriendById(msg.target());
|
||||
if (!target) {
|
||||
return;
|
||||
}
|
||||
cs::MFChatMsg* p = new cs::MFChatMsg();
|
||||
FillMFChatMsg(p, hum, 0, msg.chat_channel(), msg.msg_type(), msg.msg_body());
|
||||
{
|
||||
TypeConvert::Convert(target->base_data, *p->mutable_receiver()->mutable_base_data());
|
||||
TypeConvert::Convert(target->temp_custom_data, *p->mutable_receiver()->mutable_temp_custom_data());
|
||||
}
|
||||
|
||||
AddChatedUser(hum->AccountId(), msg.target(), p, hum->IncDBPrivateChatLastId());
|
||||
ChatMgr::Instance()->SyncPrivateChatMsg(hum);
|
||||
Player* target_hum = PlayerMgr::Instance()->GetPlayerByAccountId(msg.target());
|
||||
if (target_hum) {
|
||||
ChatMgr::Instance()->SyncPrivateChatMsg(target_hum);
|
||||
AddChatedUser(msg.target(), hum->AccountId(), p, target_hum->IncDBPrivateChatLastId());
|
||||
} else {
|
||||
AddChatedUser(msg.target(), hum->AccountId(), p, 0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void ChatMgr::ProcGuildChat(Player* hum, const cs::CMSendChatMsg& msg)
|
||||
{
|
||||
#if 0
|
||||
if (hum->GuildId() == 0) {
|
||||
return;
|
||||
}
|
||||
cs::MFChatMsg* p = new cs::MFChatMsg();
|
||||
FillMFChatMsg(p, hum, ++guild_msg_id_, msg.chat_channel(), msg.msg_type(), msg.msg_body());
|
||||
|
||||
auto itr = guild_msgrec_.find(hum->GuildId());
|
||||
if (itr != guild_msgrec_.end()) {
|
||||
itr->second.msg_list.push_back(p);
|
||||
itr->second.PopAndDelete(50);
|
||||
} else {
|
||||
ChatMsgRec msgrec;
|
||||
msgrec.curr_id = guild_msg_id_;
|
||||
guild_msgrec_[hum->GuildId()] = msgrec;
|
||||
}
|
||||
#if 0
|
||||
Guild* guild = GuildMgr::Instance()->GetGuild(hum->GuildId());
|
||||
if (guild) {
|
||||
guild->TraverseMember
|
||||
(
|
||||
[] (GuildMember* member)
|
||||
{
|
||||
Player* hum = PlayerMgr::Instance()->GetPlayerByAccountId(member->account_id);
|
||||
if (hum) {
|
||||
ChatMgr::Instance()->SyncGuildChatMsg(hum);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
void ChatMgr::ProcTeamChat(Player* hum, const cs::CMSendChatMsg& msg)
|
||||
{
|
||||
cs::MFChatMsg* p = new cs::MFChatMsg();
|
||||
FillMFChatMsg(p, hum, ++temp_msg_id_, msg.chat_channel(), msg.msg_type(), msg.msg_body());
|
||||
|
||||
cs::SMChatMsgNotify notifymsg;
|
||||
*notifymsg.add_msg_list() = *p;
|
||||
for (auto& member_id : msg.members()) {
|
||||
#if 0
|
||||
Player* hum = PlayerMgr::Instance()->GetPlayerByAccountId(member_id);
|
||||
if (hum) {
|
||||
hum->SendMsg(notifymsg);
|
||||
if (hum->chat_channel == kCCTeam) {
|
||||
a8::SetBitFlag(hum->red_point_flags_, RPF_Chat);
|
||||
hum->SyncRedPoint();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
delete p;
|
||||
}
|
||||
|
||||
void ChatMgr::ProcBigHornChat(Player* hum, const cs::CMSendChatMsg& msg)
|
||||
{
|
||||
cs::MFChatMsg* p = new cs::MFChatMsg();
|
||||
FillMFChatMsg(p, hum, ++temp_msg_id_, msg.chat_channel(), msg.msg_type(), msg.msg_body());
|
||||
|
||||
cs::SMChatMsgNotify notifymsg;
|
||||
*notifymsg.add_msg_list() = *p;
|
||||
#if 0
|
||||
PlayerMgr::Instance()->TraversePlayer
|
||||
([¬ifymsg](Player* hum)
|
||||
{
|
||||
hum->SendMsg(notifymsg);
|
||||
});
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
{
|
||||
p->set_msg_uuid(++world_msg_id_);
|
||||
p->set_chat_channel(kCCWorld);
|
||||
world_msgrec_.curr_id = world_msg_id_;
|
||||
world_msgrec_.msg_list.push_back(p);
|
||||
world_msgrec_.PopAndDelete(50);
|
||||
PlayerMgr::Instance()->TraversePlayer
|
||||
([](Player* hum)
|
||||
{
|
||||
ChatMgr::Instance()->SyncWorldChatMsg(hum);
|
||||
});
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void ChatMgr::ProcLoopMsgChat(Player* hum, const cs::CMSendChatMsg& msg)
|
||||
{
|
||||
cs::MFChatMsg* p = new cs::MFChatMsg();
|
||||
FillMFChatMsg(p, hum, ++temp_msg_id_, msg.chat_channel(), msg.msg_type(), msg.msg_body());
|
||||
|
||||
cs::SMChatMsgNotify notifymsg;
|
||||
*notifymsg.add_msg_list() = *p;
|
||||
#if 0
|
||||
PlayerMgr::Instance()->TraversePlayer
|
||||
([¬ifymsg](Player* hum)
|
||||
{
|
||||
hum->SendMsg(notifymsg);
|
||||
});
|
||||
#endif
|
||||
delete p;
|
||||
}
|
||||
|
||||
ChatedUserRec* ChatMgr::GetChatedUser(const std::string& account_id)
|
||||
{
|
||||
auto itr = private_chated_users_.find(account_id);
|
||||
return itr != private_chated_users_.end() ? itr->second : nullptr;
|
||||
}
|
||||
|
||||
void ChatMgr::SyncWorldChatMsg(Player* hum)
|
||||
{
|
||||
#if 0
|
||||
if (hum->chat_channel == kCCWorld) {
|
||||
cs::SMChatMsgNotify notifymsg;
|
||||
for (cs::MFChatMsg* chat_msg : world_msgrec_.msg_list) {
|
||||
if (chat_msg->msg_uuid() > hum->world_channel_last_id) {
|
||||
*notifymsg.add_msg_list() = *chat_msg;
|
||||
hum->world_channel_last_id = chat_msg->msg_uuid();
|
||||
}
|
||||
}
|
||||
if (notifymsg.msg_list().size() > 0) {
|
||||
hum->SendMsg(notifymsg);
|
||||
}
|
||||
} else {
|
||||
hum->MarkNewMsg();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void ChatMgr::SyncPrivateChatMsg(Player* hum)
|
||||
{
|
||||
#if 0
|
||||
if (hum->chat_channel == kCCPrivate) {
|
||||
ChatedUserRec* chated_user = GetChatedUser(hum->AccountId());
|
||||
if (chated_user) {
|
||||
cs::SMChatMsgNotify notifymsg;
|
||||
auto itr = chated_user->users.find(hum->private_target);
|
||||
if (itr != chated_user->users.end()) {
|
||||
for (cs::MFChatMsg* chat_msg : itr->second.msg_list) {
|
||||
if (chat_msg->msg_uuid() > itr->second.curr_id) {
|
||||
*notifymsg.add_msg_list() = *chat_msg;
|
||||
itr->second.curr_id = chat_msg->msg_uuid();
|
||||
chated_user->dirty = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (notifymsg.msg_list().size() > 0) {
|
||||
hum->SendMsg(notifymsg);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
hum->MarkNewMsg();
|
||||
a8::SetBitFlag(hum->red_point_flags_, RPF_Chat);
|
||||
hum->SyncRedPoint();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void ChatMgr::SyncGuildChatMsg(Player* hum)
|
||||
{
|
||||
#if 0
|
||||
if (hum->GuildId() == 0) {
|
||||
return;
|
||||
}
|
||||
auto itr = guild_msgrec_.find(hum->GuildId());
|
||||
if (itr != guild_msgrec_.end()) {
|
||||
if (hum->chat_channel == kCCGuild) {
|
||||
cs::SMChatMsgNotify notifymsg;
|
||||
for (cs::MFChatMsg* chat_msg : itr->second.msg_list) {
|
||||
if (chat_msg->msg_uuid() > hum->guild_channel_last_id) {
|
||||
*notifymsg.add_msg_list() = *chat_msg;
|
||||
hum->guild_channel_last_id = chat_msg->msg_uuid();
|
||||
}
|
||||
}
|
||||
if (notifymsg.msg_list().size() > 0) {
|
||||
hum->SendMsg(notifymsg);
|
||||
}
|
||||
} else {
|
||||
hum->MarkNewMsg();
|
||||
a8::SetBitFlag(hum->red_point_flags_, RPF_Chat);
|
||||
hum->SyncRedPoint();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void ChatMgr::OnPlayerOnline(Player* hum)
|
||||
{
|
||||
ChatedUserRec* user = GetChatedUser(hum->AccountId());
|
||||
if (user) {
|
||||
#if 0
|
||||
long long init_last_id = hum->GetDBPrivateChatLastId();
|
||||
for (auto& pair : user->users) {
|
||||
for (auto& msg : pair.second.msg_list) {
|
||||
if (msg->msg_uuid() == 0) {
|
||||
msg->set_msg_uuid(hum->IncDBPrivateChatLastId());
|
||||
} else if (msg->msg_uuid() > init_last_id){
|
||||
msg->set_msg_uuid(hum->IncDBPrivateChatLastId());
|
||||
}
|
||||
if (msg->msg_uuid() > pair.second.last_id) {
|
||||
pair.second.last_id = msg->msg_uuid();
|
||||
}
|
||||
if (pair.second.curr_id > pair.second.last_id) {
|
||||
pair.second.curr_id = pair.second.last_id;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void ChatMgr::OnPlayerOffline(Player* hum)
|
||||
{
|
||||
#if 0
|
||||
a8::Timer::Instance()->AddDeadLineTimer
|
||||
(1000 * 60 * 5,
|
||||
a8::XParams()
|
||||
.SetSender(hum->AccountId()),
|
||||
[] (const a8::XParams& param)
|
||||
{
|
||||
if (!PlayerMgr::Instance()->GetPlayerByAccountId(param.sender)) {
|
||||
ChatMgr::Instance()->RemoveChatedUser(param.sender);
|
||||
}
|
||||
});
|
||||
#endif
|
||||
}
|
||||
|
||||
void ChatMgr::AddChatedUser(const std::string& sender_id, const std::string& receiver_id,
|
||||
cs::MFChatMsg* chat_msg, long long last_id)
|
||||
{
|
||||
cs::MFChatMsg* chat_msg_copy = new cs::MFChatMsg;
|
||||
*chat_msg_copy = *chat_msg;
|
||||
chat_msg_copy->set_msg_uuid(last_id);
|
||||
ChatedUserRec* user = nullptr;
|
||||
{
|
||||
auto itr = private_chated_users_.find(sender_id);
|
||||
if (itr == private_chated_users_.end()) {
|
||||
private_chated_users_[sender_id] = new ChatedUserRec;
|
||||
itr = private_chated_users_.find(sender_id);
|
||||
}
|
||||
user = itr->second;
|
||||
}
|
||||
{
|
||||
user->dirty = false;
|
||||
user->has_unread_msg = true;
|
||||
auto itr = user->users.find(receiver_id);
|
||||
if (itr == user->users.end()) {
|
||||
user->users[receiver_id] = ChatMsgRec();
|
||||
itr = user->users.find(receiver_id);
|
||||
}
|
||||
itr->second.last_id = last_id;
|
||||
itr->second.msg_list.push_back(chat_msg_copy);
|
||||
itr->second.PopAndDelete(50);
|
||||
}
|
||||
}
|
||||
|
||||
void ChatMgr::FillMFChatMsg(cs::MFChatMsg* msg, Player* sender, long long msg_uuid,
|
||||
int chat_channel, int msg_type, const std::string& msg_body)
|
||||
{
|
||||
#if 0
|
||||
msg->set_msg_uuid(msg_uuid);
|
||||
sender->FillMFUserInfo(msg->mutable_sender());
|
||||
msg->set_chat_channel(chat_channel);
|
||||
msg->set_msg_type(msg_type);
|
||||
msg->set_msg_body(msg_body);
|
||||
msg->set_send_time(time(nullptr));
|
||||
#endif
|
||||
}
|
||||
|
||||
void ChatMgr::RemoveChatedUser(const std::string& account_id)
|
||||
{
|
||||
auto itr = private_chated_users_.find(account_id);
|
||||
if (itr != private_chated_users_.end()) {
|
||||
delete itr->second;
|
||||
private_chated_users_.erase(account_id);
|
||||
}
|
||||
}
|
63
server/imserver/chatmgr.h
Normal file
63
server/imserver/chatmgr.h
Normal file
@ -0,0 +1,63 @@
|
||||
#pragma once
|
||||
|
||||
#include "cs_proto.pb.h"
|
||||
|
||||
struct ChatMsgRec
|
||||
{
|
||||
long long curr_id = 0;
|
||||
long long last_id = 0;
|
||||
std::list<cs::MFChatMsg*> msg_list;
|
||||
|
||||
~ChatMsgRec();
|
||||
void Pop(size_t max_num);
|
||||
void PopAndDelete(size_t max_num);
|
||||
};
|
||||
|
||||
class Player;
|
||||
struct ChatedUserRec;
|
||||
class ChatMgr : public a8::Singleton<ChatMgr>
|
||||
{
|
||||
private:
|
||||
ChatMgr() {};
|
||||
friend class a8::Singleton<ChatMgr>;
|
||||
|
||||
public:
|
||||
void Init();
|
||||
void UnInit();
|
||||
|
||||
void FillSMUpdateChatRedPointNotify(Player* hum, cs::SMUpdateChatRedPointNotify& msg);
|
||||
void FillSMUpdatePrivateChatRedPointNotify(Player* hum, cs::SMUpdatePrivateChatRedPointNotify& msg);
|
||||
|
||||
void ProcWorldChat(Player* hum, const cs::CMSendChatMsg& msg);
|
||||
void ProcPrivateChat(Player* hum, const cs::CMSendChatMsg& msg);
|
||||
void ProcGuildChat(Player* hum, const cs::CMSendChatMsg& msg);
|
||||
void ProcTeamChat(Player* hum, const cs::CMSendChatMsg& msg);
|
||||
void ProcBigHornChat(Player* hum, const cs::CMSendChatMsg& msg);
|
||||
void ProcLoopMsgChat(Player* hum, const cs::CMSendChatMsg& msg);
|
||||
|
||||
void SyncWorldChatMsg(Player* hum);
|
||||
void SyncPrivateChatMsg(Player* hum);
|
||||
void SyncGuildChatMsg(Player* hum);
|
||||
|
||||
void OnPlayerOnline(Player* hum);
|
||||
void OnPlayerOffline(Player* hum);
|
||||
|
||||
private:
|
||||
ChatedUserRec* GetChatedUser(const std::string& account_id);
|
||||
void AddChatedUser(const std::string& sender_id, const std::string& receiver_id,
|
||||
cs::MFChatMsg* chat_msg, long long last_id);
|
||||
void FillMFChatMsg(cs::MFChatMsg* msg, Player* sender, long long msg_uuid,
|
||||
int chat_channel, int msg_type, const std::string& msg_body);
|
||||
void RemoveChatedUser(const std::string& account_id);
|
||||
|
||||
private:
|
||||
long long world_msg_id_ = 1000;
|
||||
long long guild_msg_id_ = 1000;
|
||||
long long temp_msg_id_ = 1000;
|
||||
ChatMsgRec world_msgrec_;
|
||||
std::map<long long, ChatMsgRec> guild_msgrec_;
|
||||
std::map<std::string, ChatedUserRec*> private_chated_users_;
|
||||
std::map<std::string, cs::MFChatMsg*> team_msg_hash_;
|
||||
ChatMsgRec bighorn_msgrec_;
|
||||
ChatMsgRec loop_msgrec_;
|
||||
};
|
@ -14,7 +14,6 @@ class Player : public std::enable_shared_from_this<Player>
|
||||
{
|
||||
public:
|
||||
int socket_handle = 0;
|
||||
std::string account_id;
|
||||
|
||||
void _CMSendChatMsg(f8::MsgHdr& hdr, const cs::CMSendChatMsg& msg);
|
||||
void _CMSendCustomMsg(f8::MsgHdr& hdr, const cs::CMSendCustomMsg& msg);
|
||||
@ -23,6 +22,9 @@ class Player : public std::enable_shared_from_this<Player>
|
||||
void _CMSetCurrPrivateChatTarget(f8::MsgHdr& hdr, const cs::CMSetCurrPrivateChatTarget& msg);
|
||||
std::weak_ptr<UserInfo> GetUserInfo() { return user_info_; };
|
||||
|
||||
const std::string& AccountId() { return account_id_; };
|
||||
|
||||
private:
|
||||
std::string account_id_;
|
||||
std::weak_ptr<UserInfo> user_info_;
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user