package model import ( "rocommon/util" model2 "roserver/baseserver/model" "roserver/serverproto" "unicode/utf8" ) type RoleChat struct { SaveObject bCopyData bool offlineMsgList []*serverproto.ChatPlayerBriefInfo lastChatTime uint64 getWorldMsgTime uint64 } func newRoleChat(r *Role) *RoleChat { roleChat := &RoleChat{ SaveObject: SaveObject{ role: r, }, bCopyData: false, } return roleChat } func (this *RoleChat) Load(msg interface{}) bool { proRole := msg.(*serverproto.Role) if proRole != nil && proRole.RoleChat != nil { this.offlineMsgList = append(proRole.RoleChat.OfflineMsgPlayerList) } return true } func (this *RoleChat) Save() { } func (this *RoleChat) CopyData(data *serverproto.RoleChat) { if !this.bCopyData { this.bCopyData = true data.OfflineMsgPlayerList = append(this.offlineMsgList) } } func (this *RoleChat) CheckChatInvalid(targetId uint64, msgType int32, msg *serverproto.CSChatMessageReq) serverproto.ErrorCode { if this.role.GetUUid() == targetId { util.InfoF("uid=%v chat can not send self", this.role.GetUUid()) return serverproto.ErrorCode_ERROR_CHAT_CAN_NOT_SEND_SELF } msgLen := utf8.RuneCountInString(msg.Message.Message) if msgLen > 200 || len(msg.Message.Message) <= 0 { util.InfoF("uid=%v chat content len limit msgLen=%v", this.role.GetUUid(), msgLen) return serverproto.ErrorCode_ERROR_CHAT_MSG_CONTENT_LIMIT } nowTime := util.GetTimeMilliseconds() if this.lastChatTime > 0 && nowTime > this.lastChatTime && (nowTime-this.lastChatTime) < model2.ChatWorldTime { return serverproto.ErrorCode_ERROR_CHAT_MSG_INTER_TIME_LIMIT } if msgType == int32(serverproto.ChatMessageType_CMT_WORLD) { totalRecharge := this.role.GetTotalRecharge() if model2.ChatWorldRoleLevel > 0 { //玩家角色等级限制 if this.role.GetRoleLevel() < model2.ChatWorldRoleLevel { if model2.ChatWorldTotalRecharge <= 0 || totalRecharge < model2.ChatWorldTotalRecharge { return serverproto.ErrorCode_ERROR_CHAT_WORLD_ROLE_LEVEL_LIMIT } } } if model2.ChatWorldMapLevel > 0 { //地图推进进度限制 if this.role.GetRoleBattle().GetLevelId() <= model2.ChatWorldMapLevel { if model2.ChatWorldTotalRecharge <= 0 || totalRecharge < model2.ChatWorldTotalRecharge { return serverproto.ErrorCode_ERROR_CHAT_WORLD_MAP_LEVEL_LIMIT } } } ////玩家角色等级限制 //if this.role.GetRoleLevel() < model2.ChatWorldRoleLevel && model2.ChatWorldRoleLevel > 0 { // return serverproto.ErrorCode_ERROR_CHAT_WORLD_ROLE_LEVEL_LIMIT //} ////地图推进进度限制 //if this.role.GetRoleBattle().GetLevelId() <= model2.ChatWorldMapLevel && model2.ChatWorldMapLevel > 0 { // return serverproto.ErrorCode_ERROR_CHAT_WORLD_MAP_LEVEL_LIMIT //} } return serverproto.ErrorCode_ERROR_OK } //bSystemChat表示系统功能消息,非聊天信息 func (this *RoleChat) SendMsg(targetId uint64, msgType int32, msg *serverproto.CSChatMessageReq, bSystemChat bool) { if msg.Message == nil { return } //屏蔽字处理 oldContentMsg := msg.Message.Message msg.Message.Message = SensitiveUtil.HandleWord(msg.Message.Message, '*') fromId := &serverproto.ChatPlayerBriefInfo{ Uid: this.role.GetUUid(), NickName: this.role.GetNickName(), ImgId: this.role.GetImageId(), ConfigId: this.role.GetRoleHero().GetMainHero().ConfigId, Level: this.role.GetRoleLevel(), HeadFrameId: this.role.GetRoleBase().RoleData().HeadFrameId, Gender: this.role.GetRoleBase().GetRoleSex(), VipLevel: this.role.GetRoleVipLevel(), HeadId: this.role.GetHeadId(), } chatNtf := &serverproto.SCChatMessageNtf{} chatNtf.MsgList = append(chatNtf.MsgList, &serverproto.MessageContentInfo{ Type: msgType, FromId: fromId, Message: msg.Message, TargetId: targetId, }) msg.FromId = fromId msg.Message.SendTime = uint64(util.GetTimeMilliseconds()) //发送聊天消息次数任务 if !bSystemChat { TaskMagCheck(this.role, serverproto.TaskType_Chat_Message_Count, 1) } var ChannelName = "" switch (serverproto.ChatMessageType)(msgType) { case serverproto.ChatMessageType_CMT_PERSONAL: if msg.Message.SubType == 0 && !this.role.roleStatistic.CheckChatMsg(msgType, msg.TargetId, oldContentMsg) { //封号/踢人 break } targetRole := RoleMag.GetRoleFromUUid(msg.TargetId) if targetRole != nil { if !targetRole.(*Role).GetRoleSocial().IsInBlackList(fromId.Uid) && !this.role.GetRoleSocial().IsInBlackList(targetId) { targetRole.ReplayGate(chatNtf, true) } //回复自己发送消息成功 ackMsg := &serverproto.SCChatMessageAck{ Error: int32(serverproto.ErrorCode_ERROR_OK), Type: msgType, TargetId: msg.TargetId, Message: msg.Message, } this.role.ReplayGate(ackMsg, true) //发送给db保存聊天消息到mysql if !bSystemChat { this.SendDB2Mysql(this.role.GetUUid(), msg.TargetId, msgType, msg.Message) } } else { if this.role.GetRoleSocial().IsInBlackList(targetId) { //回复自己发送消息成功 ackMsg := &serverproto.SCChatMessageAck{ Error: int32(serverproto.ErrorCode_ERROR_OK), Type: msgType, TargetId: msg.TargetId, Message: msg.Message, } this.role.ReplayGate(ackMsg, true) } else { this.role.SendSocial(msg) } ChannelName = "PERSONAL" } case serverproto.ChatMessageType_CMT_WORLD: //禁言 if msg.Message.SubType == 0 && !this.role.roleStatistic.CheckChatMsg(msgType, msg.TargetId, oldContentMsg) { //自言自语 this.role.ReplayGate(chatNtf, true) break } AddWorldMsg(msg.Type, msg.FromId, msg.Message, nil) //当前服务器的玩家直接下发 RoleMag.SendMsg2OnlinePlayer(chatNtf, this.role.GetUUid()) //广播给其他game服务器 this.role.SendSocial(msg) //发送给db保存聊天消息到mysql if !bSystemChat { this.SendDB2Mysql(this.role.GetUUid(), 0, msgType, msg.Message) } ChannelName = "WORLD" case serverproto.ChatMessageType_CMT_GUILD: //禁言 if msg.Message.SubType == 0 && !this.role.roleStatistic.CheckChatMsg(msgType, msg.TargetId, oldContentMsg) { //自言自语 this.role.ReplayGate(msg, true) break } ntfMsg := &serverproto.SSGuildChatMessageNtf{ Type: msg.Type, Message: msg.Message, FromId: msg.FromId, GuildId: this.role.GetRoleGuildId(), } this.role.SendGuild(ntfMsg) if !bSystemChat { this.SendDB2Mysql(this.role.GetUUid(), 0, msgType, msg.Message) } ChannelName = "GUILD" //跨服聊天 case serverproto.ChatMessageType_CMT_YuanHang: case serverproto.ChatMessageType_CMT_Map: //禁言(SubType用来表示系统消息,例如发起求助消息) if msg.Message.SubType == 0 && !this.role.roleStatistic.CheckChatMsg(msgType, msg.TargetId, oldContentMsg) { //自言自语 this.role.ReplayGate(msg, true) break } //是否在场景地图 curSpaceId := this.role.GetRoleCross().GetCrossCurSpaceId() if curSpaceId <= 0 { util.InfoF("uid=%v send msg err not in space", this.role.GetUUid()) break } ssGCrossMsg := &serverproto.SSGCrossChatMessageReq{ Type: msg.Type, Message: msg.Message, FromId: fromId, TargetId: msg.TargetId, CurSpaceId: curSpaceId, } this.role.SendSocial(ssGCrossMsg) } //言论日志 nLog := &NeteaseLogRoleChat{} nLog.Content = msg.Message.Message nLog.Channel = ChannelName nLog.ChatTime = msg.Message.SendTime if msgType == int32(serverproto.ChatMessageType_CMT_PERSONAL) { targetRole := RoleMag.GetRoleFromUUid(msg.TargetId) if targetRole != nil { nLog.LogRoleChat(this.role, targetRole.(*Role)) } } else { nLog.LogRoleChat(this.role, nil) } } func (this *RoleChat) AddOfflineMsg(offlinePlayerList []*serverproto.ChatPlayerBriefInfo) { for idx := 0; idx < len(offlinePlayerList); idx++ { bFind := false for k := 0; k < len(this.offlineMsgList); k++ { if this.offlineMsgList[k].Uid == offlinePlayerList[idx].Uid { bFind = true break } } if !bFind { this.offlineMsgList = append(this.offlineMsgList, offlinePlayerList[idx]) } } } func (this *RoleChat) GetOfflineMsg(targetPlayerId uint64) serverproto.ErrorCode { for idx := range this.offlineMsgList { if this.offlineMsgList[idx].Uid == targetPlayerId { reqMsg := &serverproto.CSChatOfflineMsgReq{ TargetId: targetPlayerId, SelfId: this.role.GetUUid(), } this.role.SendDb(reqMsg) this.offlineMsgList = append(this.offlineMsgList[:idx], this.offlineMsgList[idx+1:]...) return serverproto.ErrorCode_ERROR_OK } } util.InfoF("uid=%v GetOfflineMsg not offline msg=%v->%v", this.role.GetUUid(), this.role.GetUUid(), targetPlayerId) return serverproto.ErrorCode_ERROR_FAIL } func (this *RoleChat) WorldMsgNtf() { ackMsg := &serverproto.SCChatMessageNtf{} nowTime := util.GetTimeMilliseconds() if this.getWorldMsgTime == 0 || nowTime-this.getWorldMsgTime >= 2000 { GetWorldMsg(ackMsg, this.role.GetRoleSocial().BlackList()) this.getWorldMsgTime = nowTime } this.role.ReplayGate(ackMsg, true) } func (this *RoleChat) SendDB2Mysql(fromId, targetId uint64, msgType int32, content *serverproto.ChatMessageInfo) { ssMsg := &serverproto.SSWebGMChatMsgNtf{ Uid: fromId, TargetUid: targetId, MsgType: msgType, Content: content, } this.role.SendDb(ssMsg) //通过social->gmweb 发送给gm后台做聊天消息监控 ssMsgGmweb := &serverproto.SSWebGMChatMsgNtf{ Uid: fromId, TargetUid: targetId, MsgType: msgType, Content: content, ChatSelfName: this.role.GetNickName(), SelectZoneId: this.role.GetSelectZone(), } this.role.SendSocial(ssMsgGmweb) }