role_chat.go 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309
  1. package model
  2. import (
  3. "rocommon/util"
  4. model2 "roserver/baseserver/model"
  5. "roserver/serverproto"
  6. "unicode/utf8"
  7. )
  8. type RoleChat struct {
  9. SaveObject
  10. bCopyData bool
  11. offlineMsgList []*serverproto.ChatPlayerBriefInfo
  12. lastChatTime uint64
  13. getWorldMsgTime uint64
  14. }
  15. func newRoleChat(r *Role) *RoleChat {
  16. roleChat := &RoleChat{
  17. SaveObject: SaveObject{
  18. role: r,
  19. },
  20. bCopyData: false,
  21. }
  22. return roleChat
  23. }
  24. func (this *RoleChat) Load(msg interface{}) bool {
  25. proRole := msg.(*serverproto.Role)
  26. if proRole != nil && proRole.RoleChat != nil {
  27. this.offlineMsgList = append(proRole.RoleChat.OfflineMsgPlayerList)
  28. }
  29. return true
  30. }
  31. func (this *RoleChat) Save() {
  32. }
  33. func (this *RoleChat) CopyData(data *serverproto.RoleChat) {
  34. if !this.bCopyData {
  35. this.bCopyData = true
  36. data.OfflineMsgPlayerList = append(this.offlineMsgList)
  37. }
  38. }
  39. func (this *RoleChat) CheckChatInvalid(targetId uint64, msgType int32, msg *serverproto.CSChatMessageReq) serverproto.ErrorCode {
  40. if this.role.GetUUid() == targetId {
  41. util.InfoF("uid=%v chat can not send self", this.role.GetUUid())
  42. return serverproto.ErrorCode_ERROR_CHAT_CAN_NOT_SEND_SELF
  43. }
  44. msgLen := utf8.RuneCountInString(msg.Message.Message)
  45. if msgLen > 200 || len(msg.Message.Message) <= 0 {
  46. util.InfoF("uid=%v chat content len limit msgLen=%v", this.role.GetUUid(), msgLen)
  47. return serverproto.ErrorCode_ERROR_CHAT_MSG_CONTENT_LIMIT
  48. }
  49. nowTime := util.GetTimeMilliseconds()
  50. if this.lastChatTime > 0 && nowTime > this.lastChatTime && (nowTime-this.lastChatTime) < model2.ChatWorldTime {
  51. return serverproto.ErrorCode_ERROR_CHAT_MSG_INTER_TIME_LIMIT
  52. }
  53. if this.role.GetTotalRecharge() >= model2.ChatWorldTotalRecharge {
  54. return serverproto.ErrorCode_ERROR_OK
  55. }
  56. if msgType == int32(serverproto.ChatMessageType_CMT_WORLD) {
  57. //玩家角色等级限制
  58. if this.role.GetRoleLevel() < model2.ChatWorldRoleLevel && model2.ChatWorldRoleLevel > 0 {
  59. return serverproto.ErrorCode_ERROR_CHAT_WORLD_ROLE_LEVEL_LIMIT
  60. }
  61. //地图推进进度限制
  62. if this.role.GetRoleBattle().GetLevelId() <= model2.ChatWorldMapLevel && model2.ChatWorldMapLevel > 0 {
  63. return serverproto.ErrorCode_ERROR_CHAT_WORLD_MAP_LEVEL_LIMIT
  64. }
  65. }
  66. return serverproto.ErrorCode_ERROR_OK
  67. }
  68. // bSystemChat表示系统功能消息,非聊天信息
  69. func (this *RoleChat) SendMsg(targetId uint64, msgType int32, msg *serverproto.CSChatMessageReq, bSystemChat bool) {
  70. if msg.Message == nil {
  71. return
  72. }
  73. //屏蔽字处理
  74. oldContentMsg := msg.Message.Message
  75. msg.Message.Message = SensitiveUtil.HandleWord(msg.Message.Message, '*')
  76. fromId := &serverproto.ChatPlayerBriefInfo{
  77. Uid: this.role.GetUUid(),
  78. NickName: this.role.GetNickName(),
  79. ImgId: this.role.GetImageId(),
  80. ConfigId: this.role.GetRoleHero().GetMainHero().ConfigId,
  81. Level: this.role.GetRoleLevel(),
  82. HeadFrameId: this.role.GetRoleBase().RoleData().HeadFrameId,
  83. Gender: this.role.GetRoleBase().GetRoleSex(),
  84. VipLevel: this.role.GetRoleVipLevel(),
  85. HeadId: this.role.GetHeadId(),
  86. }
  87. chatNtf := &serverproto.SCChatMessageNtf{}
  88. chatNtf.MsgList = append(chatNtf.MsgList, &serverproto.MessageContentInfo{
  89. Type: msgType,
  90. FromId: fromId,
  91. Message: msg.Message,
  92. TargetId: targetId,
  93. })
  94. msg.FromId = fromId
  95. msg.Message.SendTime = uint64(util.GetTimeMilliseconds())
  96. //发送聊天消息次数任务
  97. if !bSystemChat {
  98. TaskMagCheck(this.role, serverproto.TaskType_Chat_Message_Count, 1)
  99. }
  100. var ChannelName = ""
  101. switch (serverproto.ChatMessageType)(msgType) {
  102. case serverproto.ChatMessageType_CMT_PERSONAL:
  103. if msg.Message.SubType == 0 &&
  104. !this.role.roleStatistic.CheckChatMsg(msgType, msg.TargetId, oldContentMsg) {
  105. //封号/踢人
  106. break
  107. }
  108. targetRole := RoleMag.GetRoleFromUUid(msg.TargetId)
  109. if targetRole != nil {
  110. if !targetRole.(*Role).GetRoleSocial().IsInBlackList(fromId.Uid) && !this.role.GetRoleSocial().IsInBlackList(targetId) {
  111. targetRole.ReplayGate(chatNtf, true)
  112. }
  113. //回复自己发送消息成功
  114. ackMsg := &serverproto.SCChatMessageAck{
  115. Error: int32(serverproto.ErrorCode_ERROR_OK),
  116. Type: msgType,
  117. TargetId: msg.TargetId,
  118. Message: msg.Message,
  119. }
  120. this.role.ReplayGate(ackMsg, true)
  121. //发送给db保存聊天消息到mysql
  122. if !bSystemChat {
  123. this.SendDB2Mysql(this.role.GetUUid(), msg.TargetId, msgType, msg.Message)
  124. }
  125. } else {
  126. if this.role.GetRoleSocial().IsInBlackList(targetId) {
  127. //回复自己发送消息成功
  128. ackMsg := &serverproto.SCChatMessageAck{
  129. Error: int32(serverproto.ErrorCode_ERROR_OK),
  130. Type: msgType,
  131. TargetId: msg.TargetId,
  132. Message: msg.Message,
  133. }
  134. this.role.ReplayGate(ackMsg, true)
  135. } else {
  136. this.role.SendSocial(msg)
  137. }
  138. ChannelName = "PERSONAL"
  139. }
  140. case serverproto.ChatMessageType_CMT_WORLD:
  141. //禁言
  142. if msg.Message.SubType == 0 &&
  143. !this.role.roleStatistic.CheckChatMsg(msgType, msg.TargetId, oldContentMsg) {
  144. //自言自语
  145. this.role.ReplayGate(chatNtf, true)
  146. break
  147. }
  148. AddWorldMsg(msg.Type, msg.FromId, msg.Message, nil)
  149. //当前服务器的玩家直接下发
  150. RoleMag.SendMsg2OnlinePlayer(chatNtf, this.role.GetUUid())
  151. //广播给其他game服务器
  152. this.role.SendSocial(msg)
  153. //发送给db保存聊天消息到mysql
  154. if !bSystemChat {
  155. this.SendDB2Mysql(this.role.GetUUid(), 0, msgType, msg.Message)
  156. }
  157. ChannelName = "WORLD"
  158. case serverproto.ChatMessageType_CMT_GUILD:
  159. //禁言
  160. if msg.Message.SubType == 0 &&
  161. !this.role.roleStatistic.CheckChatMsg(msgType, msg.TargetId, oldContentMsg) {
  162. //自言自语
  163. this.role.ReplayGate(msg, true)
  164. break
  165. }
  166. ntfMsg := &serverproto.SSGuildChatMessageNtf{
  167. Type: msg.Type,
  168. Message: msg.Message,
  169. FromId: msg.FromId,
  170. GuildId: this.role.GetRoleGuildId(),
  171. }
  172. this.role.SendGuild(ntfMsg)
  173. if !bSystemChat {
  174. this.SendDB2Mysql(this.role.GetUUid(), 0, msgType, msg.Message)
  175. }
  176. ChannelName = "GUILD"
  177. //跨服聊天
  178. case serverproto.ChatMessageType_CMT_YuanHang:
  179. case serverproto.ChatMessageType_CMT_Map:
  180. //禁言(SubType用来表示系统消息,例如发起求助消息)
  181. if msg.Message.SubType == 0 &&
  182. !this.role.roleStatistic.CheckChatMsg(msgType, msg.TargetId, oldContentMsg) {
  183. //自言自语
  184. this.role.ReplayGate(msg, true)
  185. break
  186. }
  187. //是否在场景地图
  188. curSpaceId := this.role.GetRoleCross().GetCrossCurSpaceId()
  189. if curSpaceId <= 0 {
  190. util.InfoF("uid=%v send msg err not in space", this.role.GetUUid())
  191. break
  192. }
  193. ssGCrossMsg := &serverproto.SSGCrossChatMessageReq{
  194. Type: msg.Type,
  195. Message: msg.Message,
  196. FromId: fromId,
  197. TargetId: msg.TargetId,
  198. CurSpaceId: curSpaceId,
  199. }
  200. this.role.SendSocial(ssGCrossMsg)
  201. }
  202. //言论日志
  203. nLog := &NeteaseLogRoleChat{}
  204. nLog.Content = msg.Message.Message
  205. nLog.Channel = ChannelName
  206. nLog.ChatTime = msg.Message.SendTime
  207. if msgType == int32(serverproto.ChatMessageType_CMT_PERSONAL) {
  208. targetRole := RoleMag.GetRoleFromUUid(msg.TargetId)
  209. if targetRole != nil {
  210. nLog.LogRoleChat(this.role, targetRole.(*Role))
  211. }
  212. } else {
  213. nLog.LogRoleChat(this.role, nil)
  214. }
  215. }
  216. func (this *RoleChat) AddOfflineMsg(offlinePlayerList []*serverproto.ChatPlayerBriefInfo) {
  217. for idx := 0; idx < len(offlinePlayerList); idx++ {
  218. bFind := false
  219. for k := 0; k < len(this.offlineMsgList); k++ {
  220. if this.offlineMsgList[k].Uid == offlinePlayerList[idx].Uid {
  221. bFind = true
  222. break
  223. }
  224. }
  225. if !bFind {
  226. this.offlineMsgList = append(this.offlineMsgList, offlinePlayerList[idx])
  227. }
  228. }
  229. }
  230. func (this *RoleChat) GetOfflineMsg(targetPlayerId uint64) serverproto.ErrorCode {
  231. for idx := range this.offlineMsgList {
  232. if this.offlineMsgList[idx].Uid == targetPlayerId {
  233. reqMsg := &serverproto.CSChatOfflineMsgReq{
  234. TargetId: targetPlayerId,
  235. SelfId: this.role.GetUUid(),
  236. }
  237. this.role.SendDb(reqMsg)
  238. this.offlineMsgList = append(this.offlineMsgList[:idx], this.offlineMsgList[idx+1:]...)
  239. return serverproto.ErrorCode_ERROR_OK
  240. }
  241. }
  242. util.InfoF("uid=%v GetOfflineMsg not offline msg=%v->%v", this.role.GetUUid(), this.role.GetUUid(), targetPlayerId)
  243. return serverproto.ErrorCode_ERROR_FAIL
  244. }
  245. func (this *RoleChat) WorldMsgNtf() {
  246. ackMsg := &serverproto.SCChatMessageNtf{}
  247. nowTime := util.GetTimeMilliseconds()
  248. if this.getWorldMsgTime == 0 || nowTime-this.getWorldMsgTime >= 2000 {
  249. GetWorldMsg(ackMsg, this.role.GetRoleSocial().BlackList())
  250. this.getWorldMsgTime = nowTime
  251. }
  252. this.role.ReplayGate(ackMsg, true)
  253. }
  254. func (this *RoleChat) SendDB2Mysql(fromId, targetId uint64, msgType int32, content *serverproto.ChatMessageInfo) {
  255. ssMsg := &serverproto.SSWebGMChatMsgNtf{
  256. Uid: fromId,
  257. TargetUid: targetId,
  258. MsgType: msgType,
  259. Content: content,
  260. }
  261. this.role.SendDb(ssMsg)
  262. //通过social->gmweb 发送给gm后台做聊天消息监控
  263. ssMsgGmweb := &serverproto.SSWebGMChatMsgNtf{
  264. Uid: fromId,
  265. TargetUid: targetId,
  266. MsgType: msgType,
  267. Content: content,
  268. ChatSelfName: this.role.GetNickName(),
  269. SelectZoneId: this.role.GetSelectZone(),
  270. }
  271. this.role.SendSocial(ssMsgGmweb)
  272. }