2023-09-06 18:03:36 +08:00

275 lines
6.9 KiB
Go

package main
import (
"cs"
"github.com/golang/protobuf/proto"
"time"
)
type ChatMgr struct {
pm *PlayerMgr
fm *FriendsMgr
gm *GuildMgr
worldMsgRec *ChatMsgRec
guildMsgRec map[int64]*ChatMsgRec
privateChatUsers map[string]*ChatUserRec
worldMsgId uint64
guildMsgId uint64
tmpMsgId uint64
}
func NewChatMgr(pm *PlayerMgr, fm *FriendsMgr, gm *GuildMgr) *ChatMgr {
cm := &ChatMgr{
pm: pm,
fm: fm,
gm: gm,
worldMsgRec: &ChatMsgRec{},
guildMsgRec: make(map[int64]*ChatMsgRec),
privateChatUsers: make(map[string]*ChatUserRec),
}
// Default values
cm.worldMsgId = 1000
cm.guildMsgId = 1000
cm.tmpMsgId = 1000
return cm
}
func (cm *ChatMgr) init() {}
func (cm *ChatMgr) FillMFChatMsg(msg *cs.MFChatMsg, accountId *string,
msgAutoId uint64, chatChannel int32, msgType int32, msgBody *string) {
msg.MsgUuid = &msgAutoId
msg.Sender = accountId
msg.ChatChannel = &chatChannel
msg.MsgType = &msgType
msg.MsgBody = msgBody
unixSec := time.Now().Unix()
msg.SendTime = &unixSec
}
func (cm *ChatMgr) FillSMUpdateChatRedPointNotify(p *Player, msg *cs.SMUpdateChatRedPointNotify) {
// New messages flag
if cm.worldMsgRec.CurrID > p.worldChannelLastId {
msg.HasUnreadMsgChannels = append(msg.HasUnreadMsgChannels, kCCWorld)
}
guildId := cm.gm.GetGuildIdByAccountId(p.accountId)
if guildId > 0 {
if msgRec, exists := cm.guildMsgRec[guildId]; exists {
if msgRec.CurrID > p.guildChannelLastId {
msg.HasUnreadMsgChannels = append(msg.HasUnreadMsgChannels, kCCGuild)
}
}
}
userRec := cm.GetChatUser(&p.accountId)
if userRec != nil {
if userRec.Dirty {
userRec.HasUnreadMsg = false
userRec.Dirty = false
}
if userRec.HasUnreadMsg {
msg.HasUnreadMsgChannels = append(msg.HasUnreadMsgChannels, kCCPrivate)
}
}
}
func (cm *ChatMgr) FillSMUpdatePrivateChatRedPointNotify(p *Player, msg *cs.SMUpdatePrivateChatRedPointNotify) {
userRec := cm.GetChatUser(&p.accountId)
if userRec == nil {
return
}
for accountId, msgRec := range userRec.Users {
if msgRec.CurrID < msgRec.LastID {
msg.HasUnreadMsgAccounts = append(msg.HasUnreadMsgAccounts, accountId)
}
}
}
func (cm *ChatMgr) ProcWorldChat(p *Player, msg *cs.CMSendChatMsg) {
accountId := p.GetAccountId()
chatMsg := new(cs.MFChatMsg)
cm.worldMsgId++
cm.FillMFChatMsg(chatMsg, &accountId, cm.worldMsgId, *msg.ChatChannel, *msg.MsgType, msg.MsgBody)
cm.worldMsgRec.CurrID = cm.worldMsgId
cm.worldMsgRec.AddChatMsg(chatMsg)
// TraversePlayer
for _, p2 := range cm.pm.GetPlayers() {
cm.SyncWorldChatMsg(p2)
}
}
func (cm *ChatMgr) ProcGuildChat(p *Player, msg *cs.CMSendChatMsg) {
guild := cm.gm.GetGuildByAccountId(p.accountId)
if guild == nil {
return
}
guildId := guild.GetGuildId()
cm.guildMsgId++
chatMsg := new(cs.MFChatMsg)
cm.FillMFChatMsg(chatMsg, &p.accountId, cm.guildMsgId, *msg.ChatChannel, *msg.MsgType, msg.MsgBody)
if msgRec, exists := cm.guildMsgRec[guildId]; exists {
msgRec.AddChatMsg(chatMsg)
} else {
msgRec := &ChatMsgRec{}
msgRec.CurrID = cm.guildMsgId
cm.guildMsgRec[guildId] = msgRec
}
// TraverseMember
for _, member := range guild.Members {
guildMember := playerMgr.GetPlayerByAccountId(member.GetAccountId())
if guildMember != nil {
cm.SyncGuildChatMsg(guildMember)
}
}
}
func (cm *ChatMgr) ProcPrivateChat(p *Player, msg *cs.CMSendChatMsg) {
targetAccountId := msg.GetTargetAccountId()
if p.accountId == targetAccountId {
return
}
// 确定是否好友
targetAccount := cm.fm.GetFriendByAccountId(p.accountId, targetAccountId)
if targetAccount == nil {
return
}
chatMsg := new(cs.MFChatMsg)
cm.FillMFChatMsg(chatMsg, &p.accountId, 0, *msg.ChatChannel, *msg.MsgType, msg.MsgBody)
cm.AddChatUser(p.accountId, msg.GetTargetAccountId(), chatMsg, p.IncrPrivateChatLastId())
cm.SyncPrivateChatMsg(p)
// 聊天好友在线
targetPlayer := cm.pm.GetPlayerByAccountId(targetAccountId)
if targetPlayer != nil {
cm.SyncPrivateChatMsg(targetPlayer)
} else {
cm.AddChatUser(targetAccountId, p.GetAccountId(), chatMsg, 0)
}
}
func (cm *ChatMgr) SyncWorldChatMsg(p *Player) {
if p.chatChannel == kCCWorld {
notifyMsg := &cs.SMChatMsgNotify{}
for _, chatMsg := range cm.worldMsgRec.ChatMsgList {
if chatMsg.GetMsgUuid() > p.worldChannelLastId {
notifyMsg.MsgList = append(notifyMsg.MsgList, chatMsg)
p.worldChannelLastId = chatMsg.GetMsgUuid()
}
}
if len(notifyMsg.MsgList) > 0 {
p.SendMsg(notifyMsg)
}
return
}
p.MarkNewMsg()
}
func (cm *ChatMgr) SyncPrivateChatMsg(p *Player) {
if p.chatChannel == kCCPrivate {
chatUser := cm.GetChatUser(&p.accountId)
if chatUser == nil {
return
}
notifyMsg := &cs.SMChatMsgNotify{}
for accountId, chatMsgRec := range chatUser.Users {
if accountId == p.privateTargetAccountId {
for _, chatMsg := range chatMsgRec.ChatMsgList {
if *chatMsg.MsgUuid > chatMsgRec.CurrID {
notifyMsg.MsgList = append(notifyMsg.MsgList, chatMsg)
chatMsgRec.CurrID = *chatMsg.MsgUuid
chatUser.Dirty = true
}
}
}
}
if len(notifyMsg.MsgList) > 0 {
p.SendMsg(notifyMsg)
}
}
p.MarkNewMsg()
}
func (cm *ChatMgr) SyncGuildChatMsg(p *Player) {
guildId := cm.gm.GetGuildIdByAccountId(p.accountId)
if guildId <= 0 {
return
}
msgRec, exists := cm.guildMsgRec[guildId]
if !exists {
return
}
if p.chatChannel == kCCGuild {
notifyMsg := &cs.SMChatMsgNotify{}
for _, chatMsg := range msgRec.ChatMsgList {
if chatMsg.GetMsgUuid() > p.guildChannelLastId {
notifyMsg.MsgList = append(notifyMsg.MsgList, chatMsg)
p.guildChannelLastId = chatMsg.GetMsgUuid()
}
}
if len(notifyMsg.MsgList) > 0 {
p.SendMsg(notifyMsg)
}
return
}
p.MarkNewMsg()
// player.SyncRedPoint()
}
func (cm *ChatMgr) AddChatUser(senderAccountId, receiverAccountId string, chatMsg *cs.MFChatMsg, lastId uint64) {
chatMsgCopy := new(cs.MFChatMsg)
proto.Merge(chatMsgCopy, chatMsg)
chatMsgCopy.MsgUuid = &lastId
if _, exists := cm.privateChatUsers[senderAccountId]; !exists {
cm.privateChatUsers[senderAccountId] = &ChatUserRec{}
}
userRec := cm.privateChatUsers[senderAccountId]
userRec.Dirty = true
userRec.HasUnreadMsg = true
if _, exists := cm.privateChatUsers[senderAccountId].Users[receiverAccountId]; !exists {
cm.privateChatUsers[senderAccountId].Users[receiverAccountId] = &ChatMsgRec{}
}
receiverUserRec := cm.privateChatUsers[senderAccountId].Users[receiverAccountId]
receiverUserRec.LastID = lastId
receiverUserRec.AddChatMsg(chatMsgCopy)
}
func (cm *ChatMgr) GetChatUser(accountId *string) *ChatUserRec {
if userRec, exists := cm.privateChatUsers[*accountId]; exists {
return userRec
}
return nil
}
func (cm *ChatMgr) RemoveChatUser(accountId *string) {
delete(cm.privateChatUsers, *accountId)
}
func (cm *ChatMgr) markMessagesAsRead(sender, receiver string) {
userRec, exists := cm.privateChatUsers[receiver]
if !exists {
return
}
msgRec, exists := userRec.Users[sender]
if !exists {
return
}
msgRec.LastID = msgRec.CurrID
}