role_chat.go 9.5 KB

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