player_chat.go 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806
  1. package player
  2. import (
  3. actorRemote "f1-game/internal/actor_remote"
  4. "f1-game/internal/code"
  5. "f1-game/internal/component/redis"
  6. "f1-game/internal/constant"
  7. "f1-game/internal/data"
  8. "f1-game/internal/enum"
  9. "f1-game/internal/event"
  10. "f1-game/internal/extend/utils"
  11. nameEvent "f1-game/internal/name/event"
  12. nameLocal "f1-game/internal/name/local"
  13. nameRemote "f1-game/internal/name/remote"
  14. nameRoute "f1-game/internal/name/route"
  15. "f1-game/internal/pb"
  16. "f1-game/internal/sessions"
  17. "f1-game/nodes/game/internal/db"
  18. dbChat "f1-game/nodes/game/internal/db/data/chat"
  19. "f1-game/nodes/game/player/asset"
  20. ao "f1-game/nodes/game/player/asset/origin"
  21. "f1-game/nodes/game/player/chat"
  22. csnowflake "github.com/cherry-game/cherry/extend/snowflake"
  23. ctime "github.com/cherry-game/cherry/extend/time"
  24. cfacade "github.com/cherry-game/cherry/facade"
  25. cproto "github.com/cherry-game/cherry/net/proto"
  26. )
  27. func (p *actorPlayer) initChat() {
  28. p.Local().Register(nameLocal.Player_ChatSend, p.chatSend)
  29. p.Local().Register(nameLocal.Player_ChatMsgList, p.chatMsgList)
  30. p.Local().Register(nameLocal.Player_ChatGroupCreate, p.chatGroupCreate)
  31. p.Local().Register(nameLocal.Player_ChatGroupPlayerList, p.chatGroupPlayerList)
  32. p.Local().Register(nameLocal.Player_ChatGroupPlayerChange, p.chatGroupPlayerChange)
  33. p.Local().Register(nameLocal.Player_ChatGroupDismiss, p.chatGroupDismiss)
  34. p.Local().Register(nameLocal.Player_ChatGroupInviteConfirm, p.chatGroupInviteConfirm)
  35. p.Local().Register(nameLocal.Player_ChatGroupQuit, p.chatGroupQuit)
  36. p.Local().Register(nameLocal.Player_ChatGroupMute, p.chatGroupMute)
  37. p.Local().Register(nameLocal.Player_ChatPrivateSend, p.chatPrivateSend)
  38. p.Local().Register(nameLocal.Player_ChatPrivateMsgList, p.chatPrivateMsgList)
  39. p.Local().Register(nameLocal.Player_ChatSetting, p.chatSetting)
  40. p.Local().Register(nameLocal.Player_Complaint, p.complaint)
  41. p.Remote().Register(nameRemote.Player_ChatGroupInvite, p.chatGroupInvite)
  42. p.Remote().Register(nameRemote.Player_ChatGroupMemberRemove, p.chatGroupMemberRemove)
  43. p.Remote().Register(nameRemote.Player_ChatPrivateMsgSend, p.chatPrivateMsgSend)
  44. p.Remote().Register(nameRemote.Player_ChatRoomUpdate, p.chatRoomUpdate)
  45. p.Remote().Register(nameRemote.Player_ChatMapSystemMsg, p.chatMapSystemMsg)
  46. p.EventRegister(nameEvent.Chat_SystemMsg, p.chatSystemMsg)
  47. }
  48. func (p *actorPlayer) chatSend(session *cproto.Session, req *pb.ChatSend) {
  49. if req.ChatID < 1 || req.ChatType < 1 {
  50. p.ResponseCode(session, code.IllegalArgument)
  51. return
  52. }
  53. if !enum.CheckChatType(req.ChatType) {
  54. p.ResponseCode(session, code.ChatSendTypeError)
  55. return
  56. }
  57. var (
  58. chatTable = p.ChatTable()
  59. chatType = enum.ChatType(req.ChatType)
  60. )
  61. chatRoom, found := chatTable.GetChatRoom(chatType, req.ChatID)
  62. if !found {
  63. p.ResponseCode(session, code.ChatChannelNotAvailable)
  64. return
  65. }
  66. var (
  67. playerTable = p.PlayerTable()
  68. chatTypeConfig, _ = data.ChatType.GetByChatType(chatType)
  69. )
  70. if chatTypeConfig.SendOpenLv > 0 && playerTable.Lord.Level < chatTypeConfig.SendOpenLv {
  71. p.ResponseCode(session, code.ChatSendLvNotEnough)
  72. return
  73. }
  74. // 过滤换行回车和屏蔽词
  75. req.Text = data.MaskWord.Replace(req.Text)
  76. if len(req.Text) < 1 {
  77. p.ResponseCode(session, code.ChatSendTextIsEmpty)
  78. return
  79. }
  80. // 检查长度限制
  81. if !utils.CheckStrLen(req.Text, chatTypeConfig.TextLen) {
  82. p.ResponseCode(session, code.ChatSendTextTooLong)
  83. return
  84. }
  85. var (
  86. nowTime = ctime.Now()
  87. lastSendTime = ctime.NewSecond(chatRoom.LastSendTime)
  88. )
  89. // 发言频率限制
  90. if chatTypeConfig.SendRate > 0 && nowTime.DiffInSecondsWithAbs(&lastSendTime) < chatTypeConfig.SendRate {
  91. p.ResponseCode(session, code.ChatSendTextTooFast)
  92. return
  93. }
  94. // 检查免费发送次数是否已经用完
  95. if chatTypeConfig.FreeSendCount > 0 && chatRoom.FreeSendCount() < 1 {
  96. // 消耗的道具
  97. _, errCode := asset.Service().Sub(p.playerID, chatTypeConfig.SendCost.ID, chatTypeConfig.SendCost.Num, ao.ChatSendCost)
  98. if code.IsFail(errCode) {
  99. p.ResponseCode(session, errCode)
  100. return
  101. }
  102. }
  103. chatRoom.UpdateSendCount(nowTime.ToSecond())
  104. chatTable.Save2Queue()
  105. p.Response(session, &pb.I32{
  106. Value: chatRoom.FreeSendCount(),
  107. })
  108. // 从redis获取玩家聊天消息数据
  109. chatPlayer := redis.Game.GetChatPlayer(p.playerID)
  110. // 构建消息,推送到chat节点
  111. msgListProto := chat.Service().BuildMsgListProto(chatPlayer, req, nowTime.ToSecond())
  112. actorRemote.Chat.Send(msgListProto)
  113. }
  114. // 获取某个聊天室的消息列表
  115. func (p *actorPlayer) chatMsgList(session *cproto.Session, req *pb.ChatMsgRequest) {
  116. if req.ChatID < 1 || req.ChatType < 1 || req.LastMsgID < 0 {
  117. p.ResponseCode(session, code.IllegalArgument)
  118. return
  119. }
  120. if !enum.CheckChatType(req.ChatType) {
  121. p.ResponseCode(session, code.IllegalArgument)
  122. return
  123. }
  124. var (
  125. chatType = enum.ChatType(req.ChatType)
  126. chatID = req.ChatID
  127. lastMsgID = req.LastMsgID
  128. )
  129. // 其他频道,检查频道聊天室是否存在
  130. if !p.ChatTable().IsChatRoomExist(chatType, chatID) {
  131. p.ResponseCode(session, code.ChatGroupNotFound)
  132. return
  133. }
  134. rsp := redis.Chat.GetChatMsgList(chatType, chatID, lastMsgID)
  135. p.Response(session, rsp)
  136. }
  137. // 获取某个群组的玩家列表
  138. func (p *actorPlayer) chatGroupPlayerList(session *cproto.Session, req *pb.I64) {
  139. if req.Value < 1 {
  140. p.ResponseCode(session, code.IllegalArgument)
  141. return
  142. }
  143. var (
  144. chatID = req.Value // 聊天室ID
  145. chatTable = p.ChatTable()
  146. )
  147. if !chatTable.IsChatRoomExist(enum.ChatType_Group, chatID) {
  148. p.ResponseCode(session, code.ChatGroupNotFound)
  149. return
  150. }
  151. // 获取群组的成员列表
  152. playerIDList, found := redis.Chat.GetGroupMembers(chatID)
  153. if !found {
  154. p.ResponseCode(session, code.ChatGroupNotFound)
  155. return
  156. }
  157. chatPlayerMap := redis.Game.GetChatPlayerMap(playerIDList...)
  158. if chatPlayerMap == nil {
  159. p.ResponseCode(session, code.PlayerDetailNotFound)
  160. return
  161. }
  162. rsp := &pb.ChatPlayerList{
  163. List: chatTable.ToPlayersProto(chatPlayerMap, playerIDList),
  164. }
  165. p.Response(session, rsp)
  166. }
  167. // 创建群组聊天室
  168. func (p *actorPlayer) chatGroupCreate(session *cproto.Session, req *pb.GroupCreate) {
  169. if p.PlayerTable().Lord.Level < data.Const.FriendGroupCreateOpenLv {
  170. p.ResponseCode(session, code.ChatGroupCreateLvNotEnough)
  171. return
  172. }
  173. if len(req.Name) < 1 {
  174. p.ResponseCode(session, code.ChatGroupNameIsEmpty)
  175. return
  176. }
  177. // 检查群组名称长度
  178. if !utils.CheckStrLen(req.Name, data.Const.FriendGroupNameMaxLength) {
  179. p.ResponseCode(session, code.ChatGroupNameTooLong)
  180. return
  181. }
  182. // 检查屏蔽词
  183. if data.MaskWord.Check(req.Name) {
  184. p.ResponseCode(session, code.ChatGroupNameIllegal)
  185. return
  186. }
  187. chatTypeConfig, _ := data.ChatType.GetByChatType(enum.ChatType_Group)
  188. // 邀请人数超过上限
  189. if len(req.PlayerIDList) > chatTypeConfig.PlayerLimit {
  190. p.ResponseCode(session, code.ChatGroupMemberLimit)
  191. return
  192. }
  193. chatTable := p.ChatTable()
  194. // 检查群组玩家邀请列表,不是好友不能邀请
  195. for _, playerID := range req.PlayerIDList {
  196. if !chatTable.IsFriend(playerID) {
  197. p.ResponseCode(session, code.ChatGroupInviteNotFriend)
  198. return
  199. }
  200. }
  201. if chatTable.GetCreateGroupCount() >= data.Const.FriendGroupCreateLimit {
  202. p.ResponseCode(session, code.ChatGroupCreateLimit)
  203. return
  204. }
  205. // 添加群组到玩家身上
  206. newChatID := redis.GUID.NewChatID()
  207. newChatRoom := dbChat.NewChatRoom(enum.ChatType_Group, newChatID, req.Name, p.playerID)
  208. chatTable.AddChatRoom(newChatRoom)
  209. chatTable.Save2Queue()
  210. // 创建成功就添加自己为群组成员
  211. redis.Chat.AddGroupMember(newChatID, p.playerID)
  212. p.Debug("chatGroupCreate create success. newChatID = %d", newChatID)
  213. // 自己加入聊天室成员列表
  214. retCode := actorRemote.Chat.GroupJoin(newChatRoom.ChatID, p.playerID)
  215. if code.IsFail(retCode) {
  216. p.ResponseCode(session, retCode)
  217. return
  218. }
  219. if len(req.PlayerIDList) > 0 {
  220. p.groupPlayerChangeSend(newChatRoom, req.PlayerIDList)
  221. }
  222. p.Response(session, newChatRoom.ToChatRoomProto())
  223. }
  224. func (p *actorPlayer) chatGroupPlayerChange(session *cproto.Session, req *pb.GroupPlayerChange) {
  225. if req.ChatID < 1 {
  226. p.ResponseCode(session, code.IllegalArgument)
  227. return
  228. }
  229. var (
  230. chatTable = p.ChatTable()
  231. chatRoom, found = chatTable.GetChatRoom(enum.ChatType_Group, req.ChatID)
  232. )
  233. if !found {
  234. p.ResponseCode(session, code.ChatGroupNotFound)
  235. return
  236. }
  237. // 没有群组权限
  238. if chatRoom.OwnerPlayerID != p.playerID {
  239. p.ResponseCode(session, code.ChatGroupPermissionDenied)
  240. return
  241. }
  242. chatTypeConfig, _ := data.ChatType.GetByChatType(enum.ChatType_Group)
  243. // 邀请人数超过上限
  244. if len(req.PlayerIDList) > chatTypeConfig.PlayerLimit {
  245. p.ResponseCode(session, code.ChatGroupMemberLimit)
  246. return
  247. }
  248. var (
  249. checkedIDList []int64 // 已经检测过的玩家ID列表
  250. )
  251. // 检测最新的成员列表是否为好友(不是好友不能邀请)
  252. for _, playerID := range req.PlayerIDList {
  253. if playerID == p.playerID {
  254. continue
  255. }
  256. if chatTable.IsFriend(playerID) {
  257. checkedIDList = append(checkedIDList, playerID)
  258. }
  259. }
  260. // checkedIDList len=0 可能移除所有人
  261. p.groupPlayerChangeSend(chatRoom, checkedIDList)
  262. p.ResponseCode(session, code.OK)
  263. }
  264. // 发起群组玩家变更消息
  265. func (p *actorPlayer) groupPlayerChangeSend(chatRoom *dbChat.ChatRoom, playerIDList []int64) {
  266. playerChangeReq := &pb.ChatGroupPlayerChange{
  267. ChatID: chatRoom.ChatID,
  268. Name: chatRoom.Name,
  269. OwnerPlayerID: chatRoom.OwnerPlayerID,
  270. PlayerIDList: playerIDList,
  271. }
  272. actorRemote.Chat.GroupPlayerChange(playerChangeReq)
  273. }
  274. // 解散群组聊天室
  275. func (p *actorPlayer) chatGroupDismiss(session *cproto.Session, req *pb.I64) {
  276. if req.Value < 1 {
  277. p.ResponseCode(session, code.IllegalArgument)
  278. return
  279. }
  280. var (
  281. chatID = req.Value // 聊天室ID
  282. chatTable = p.ChatTable()
  283. )
  284. chatRoom, found := chatTable.GetChatRoom(enum.ChatType_Group, chatID)
  285. if !found {
  286. p.ResponseCode(session, code.ChatGroupNotFound)
  287. return
  288. }
  289. if chatRoom.OwnerPlayerID != p.playerID {
  290. p.ResponseCode(session, code.ChatGroupPermissionDenied)
  291. return
  292. }
  293. actorRemote.Chat.Destory(enum.ChatType_Group, chatID)
  294. p.ResponseCode(session, code.OK)
  295. }
  296. // 群组邀请确认
  297. func (p *actorPlayer) chatGroupInviteConfirm(session *cproto.Session, req *pb.GroupInviteConfirm) {
  298. chatTable := p.ChatTable()
  299. // 一键拒绝所有邀请
  300. if req.IsRejectAll {
  301. chatTable.GroupInviteList.Clear()
  302. chatTable.Save2Queue()
  303. p.ResponseCode(session, code.OK)
  304. return
  305. }
  306. if req.ChatID < 1 {
  307. p.ResponseCode(session, code.IllegalArgument)
  308. return
  309. }
  310. // 验证邀请是否OK
  311. groupInvite, found := chatTable.GetGroupInvite(req.ChatID)
  312. if !found {
  313. p.ResponseCode(session, code.ChatGroupInviteNotFound)
  314. return
  315. }
  316. // 拒绝群组邀请
  317. if !req.IsAccept {
  318. // 先删除邀请记录
  319. chatTable.RemoveGroupInvite(req.ChatID)
  320. chatTable.Save2Queue()
  321. p.ResponseCode(session, code.OK)
  322. return
  323. }
  324. // 拥有的群组数量上限
  325. if chatTable.GroupCount() >= data.Const.FriendGroupHaveCountLimit {
  326. p.ResponseCode(session, code.ChatGroupHaveCountLimit)
  327. return
  328. }
  329. // 先删除邀请记录
  330. chatTable.RemoveGroupInvite(req.ChatID)
  331. chatTable.Save2Queue()
  332. // 已经在群里,则忽略
  333. if chatRoom, found := chatTable.GetChatRoom(enum.ChatType_Group, req.ChatID); found {
  334. p.Response(session, chatRoom.ToChatRoomProto())
  335. return
  336. }
  337. // 确认后,把自己加入聊天室成员列表
  338. retCode := actorRemote.Chat.GroupJoin(req.ChatID, p.playerID)
  339. if code.IsFail(retCode) {
  340. p.ResponseCode(session, retCode)
  341. return
  342. }
  343. // 加入进自己的聊天室集合
  344. newChatRoom := dbChat.NewChatRoom(enum.ChatType_Group, groupInvite.ChatID, groupInvite.Name, groupInvite.OwnerPlayerID)
  345. chatTable.AddChatRoom(newChatRoom)
  346. chatTable.Save2Queue()
  347. p.Response(session, newChatRoom.ToChatRoomProto())
  348. }
  349. // 主动退出一个群组
  350. func (p *actorPlayer) chatGroupQuit(session *cproto.Session, req *pb.I64) {
  351. if req.Value < 1 {
  352. p.ResponseCode(session, code.IllegalArgument)
  353. return
  354. }
  355. var (
  356. chatID = req.Value // 聊天室ID
  357. chatTable = p.ChatTable()
  358. )
  359. chatRoom, found := chatTable.GetChatRoom(enum.ChatType_Group, chatID)
  360. if !found {
  361. p.ResponseCode(session, code.ChatGroupNotFound)
  362. return
  363. }
  364. // 不允许退出自己创建的群组,只能解散群组
  365. if chatRoom.OwnerPlayerID == p.playerID {
  366. p.ResponseCode(session, code.IllegalArgument)
  367. return
  368. }
  369. chatTable.RemoveChatRoom(enum.ChatType_Group, chatID)
  370. chatTable.Save2Queue()
  371. // 主动退出则只需要移出群组,不用通知其他人
  372. actorRemote.Chat.GroupQuit(chatID, p.playerID)
  373. p.ResponseCode(session, code.OK)
  374. }
  375. // 群组免打扰设置
  376. func (p *actorPlayer) chatGroupMute(session *cproto.Session, req *pb.GroupMute) {
  377. if req.ChatID < 1 {
  378. p.ResponseCode(session, code.IllegalArgument)
  379. return
  380. }
  381. chatTable := p.ChatTable()
  382. chatRoom, found := chatTable.GetChatRoom(enum.ChatType_Group, req.ChatID)
  383. if !found {
  384. p.ResponseCode(session, code.ChatGroupNotFound)
  385. return
  386. }
  387. chatRoom.SetMute(req.IsMute)
  388. chatTable.Save2Queue()
  389. p.ResponseCode(session, code.OK)
  390. }
  391. // 发送私聊消息
  392. func (p *actorPlayer) chatPrivateSend(session *cproto.Session, req *pb.ChatPrivateSend) {
  393. if req.TargetID < 1 {
  394. p.ResponseCode(session, code.IllegalArgument)
  395. return
  396. }
  397. var (
  398. playerTable = p.PlayerTable()
  399. toPlayerID = req.TargetID
  400. chatTypeConfig, _ = data.ChatType.GetByChatType(enum.ChatType_Private)
  401. )
  402. if chatTypeConfig.SendOpenLv > 0 && playerTable.Lord.Level < chatTypeConfig.SendOpenLv {
  403. p.ResponseCode(session, code.ChatSendLvNotEnough)
  404. return
  405. }
  406. var (
  407. chatTable = p.ChatTable()
  408. now = ctime.Now()
  409. )
  410. // 发言频率限制
  411. if chatTypeConfig.SendRate > 0 {
  412. var sendTime int64
  413. if friend, found := chatTable.GetFriend(toPlayerID); found {
  414. sendTime = friend.LastSendTime
  415. } else if private, found := chatTable.GetPrivate(toPlayerID); found {
  416. sendTime = private.LastSendTime
  417. }
  418. if ctime.NewSecond(sendTime).DiffInSecondsWithAbs(&now) < chatTypeConfig.SendRate {
  419. p.ResponseCode(session, code.ChatSendTextTooFast)
  420. return
  421. }
  422. }
  423. // 拉黑不能私聊
  424. if chatTable.IsBlack(toPlayerID) {
  425. p.ResponseCode(session, code.ChatPrivateBlackList)
  426. return
  427. }
  428. // 过滤换行回车和屏蔽词
  429. req.Text = data.MaskWord.Replace(req.Text)
  430. if len(req.Text) < 1 {
  431. p.ResponseCode(session, code.ChatSendTextIsEmpty)
  432. return
  433. }
  434. if !utils.CheckStrLen(req.Text, chatTypeConfig.TextLen) {
  435. p.ResponseCode(session, code.ChatSendTextTooLong)
  436. return
  437. }
  438. // 检查玩家是否存在
  439. chatPlayerMap := redis.Game.GetChatPlayerMap(p.playerID, toPlayerID)
  440. if len(chatPlayerMap) != 2 {
  441. p.ResponseCode(session, code.PlayerDetailNotFound)
  442. return
  443. }
  444. chatPlayer := chatPlayerMap[p.playerID]
  445. sendReq := chat.Service().BuildMsgProto(chatPlayer, enum.ChatMsgType_Text, req.Text, now.ToSecond(), nil)
  446. // 最近聊天内容
  447. lastChatContent := dbChat.NewChatContent(sendReq.MsgID, sendReq.SendTime, sendReq.Type, sendReq.Text, sendReq.Params)
  448. // 判断是否是好友,更新好友或者私聊的最近一次聊天时间
  449. if friendRelation, found := chatTable.GetFriend(toPlayerID); found {
  450. friendRelation.FriendUpdate(toPlayerID, lastChatContent, true)
  451. } else {
  452. chatTable.PrivateUpdate(toPlayerID, lastChatContent, true)
  453. }
  454. chatTable.Save2Queue()
  455. redis.Chat.AddPrivateMsg(p.playerID, toPlayerID, chatTypeConfig.MsgLimit, sendReq)
  456. toChatPlayer := chatPlayerMap[toPlayerID]
  457. // 通知对方,这里不用判断对方状态
  458. actorRemote.GamePlayer.Call(toChatPlayer.GameNodeID, toPlayerID, nameRemote.Player_ChatPrivateMsgSend, sendReq)
  459. p.Response(session, sendReq)
  460. }
  461. // 获取某玩家的私聊消息列表
  462. func (p *actorPlayer) chatPrivateMsgList(session *cproto.Session, req *pb.I64I64) {
  463. if req.Key < 1 || req.Value < 0 {
  464. p.ResponseCode(session, code.IllegalArgument)
  465. return
  466. }
  467. var (
  468. targetID = req.Key // 私聊对象玩家ID
  469. lastMsgID = req.Value // 消息ID
  470. )
  471. msgs := redis.Chat.GetPrivateMsgs(p.playerID, targetID, lastMsgID)
  472. if msgs == nil {
  473. p.ResponseCode(session, code.Error)
  474. return
  475. }
  476. p.Response(session, msgs)
  477. }
  478. // 聊天设置
  479. func (p *actorPlayer) chatSetting(session *cproto.Session, req *pb.ChatSetting) {
  480. chatTable := p.ChatTable()
  481. chatTable.SetChatMute(req.IsFriendInviteMute, req.IsGroupInviteMute, req.IsPrivateChatMute)
  482. chatTable.Save2Queue()
  483. p.ResponseCode(session, code.OK)
  484. }
  485. // 举报玩家
  486. func (p *actorPlayer) complaint(session *cproto.Session, req *pb.Complaint) {
  487. if req.TargetID < 1 {
  488. p.ResponseCode(session, code.IllegalArgument)
  489. return
  490. }
  491. complaintType := enum.ComplaintType(req.ComplaintType)
  492. if complaintType < enum.ComplaintType_SpamAd || complaintType > enum.ComplaintType_Other {
  493. p.ResponseCode(session, code.IllegalArgument)
  494. return
  495. }
  496. if complaintType == enum.ComplaintType_Other && len(req.Content) < 1 {
  497. p.ResponseCode(session, code.ComplaintContentEmpty)
  498. return
  499. }
  500. if !utils.CheckStrLen(req.Content, data.Const.ComplaintContentLimit) {
  501. p.ResponseCode(session, code.ComplaintContentTooLong)
  502. return
  503. }
  504. if data.MaskWord.Check(req.Content) {
  505. p.ResponseCode(session, code.ComplaintContextIllegal)
  506. return
  507. }
  508. newComplaintID := csnowflake.NextID()
  509. newComplaintTable := db.NewComplaintTable(newComplaintID, p.playerID, req.TargetID, complaintType, req.Content)
  510. newComplaintTable.Save2Queue()
  511. p.ResponseCode(session, code.OK)
  512. }
  513. // 接收群组邀请求
  514. func (p *actorPlayer) chatGroupInvite(req *pb.GroupInvite) {
  515. chatTable := p.ChatTable()
  516. // 禁用群组邀请
  517. if !chatTable.IsGroupInviteMute {
  518. return
  519. }
  520. if _, found := chatTable.GetGroupInvite(req.ChatID); found {
  521. // 已经存在了,则忽略
  522. return
  523. }
  524. // 消息放入邀请列表中
  525. groupInvite := chatTable.NewGroupInvite(req.ChatID, req.Name, req.InvitePlayer.PlayerID)
  526. chatTable.AddGroupInvite(groupInvite)
  527. chatTable.Save2Queue()
  528. sessions.PushPlayer(p.playerID, nameRoute.PushGamePlayer_ChatGroupInvite, req)
  529. }
  530. // 通知群组聊天室成员离开
  531. func (p *actorPlayer) chatGroupMemberRemove(req *pb.I64Bool) {
  532. var (
  533. chatTable = p.ChatTable()
  534. chatID = req.Key // 聊天室ID
  535. isDismiss = req.Value // 是否解散
  536. )
  537. chatRoom, found := chatTable.GetChatRoom(enum.ChatType_Group, chatID)
  538. if found {
  539. // 从玩家群组集合移除
  540. chatTable.RemoveChatRoom(enum.ChatType_Group, chatID)
  541. chatTable.Save2Queue()
  542. }
  543. mailSendReq := &pb.SendMail{
  544. ToPlayerID: p.playerID,
  545. TemplateID: constant.MailID_ChatGroupRemove,
  546. TemplateParams: []string{chatRoom.Name},
  547. }
  548. // 解散群组
  549. if isDismiss {
  550. mailSendReq.TemplateID = constant.MailID_ChatGroupDismissal
  551. }
  552. // 发送邮件通知
  553. actorRemote.GameMail.Send(p.App().NodeID(), mailSendReq)
  554. sessions.PushPlayer(p.playerID, nameRoute.PushGamePlayer_ChatGroupLeave, req)
  555. }
  556. // 收到私聊消息
  557. func (p *actorPlayer) chatPrivateMsgSend(req *pb.ChatMsg) {
  558. var (
  559. chatTable = p.ChatTable()
  560. toPlayerID = req.Sender.PlayerID // 发送者ID
  561. )
  562. // 拒绝私聊
  563. if !chatTable.IsFriend(toPlayerID) && !chatTable.IsPrivateChatMute {
  564. return
  565. }
  566. // 黑名单
  567. if chatTable.IsBlack(toPlayerID) {
  568. return
  569. }
  570. // 最近聊天内容
  571. lastChatContent := dbChat.NewChatContent(req.MsgID, req.SendTime, req.Type, req.Text, req.Params)
  572. // 如果不是好友就放到最近私聊里面,如果在最近里面就更新时间
  573. if friendRelation, found := chatTable.GetFriend(toPlayerID); found {
  574. friendRelation.FriendUpdate(toPlayerID, lastChatContent, false)
  575. } else {
  576. chatTable.PrivateUpdate(toPlayerID, lastChatContent, false)
  577. }
  578. chatTable.Save2Queue()
  579. chatTypeConfig, _ := data.ChatType.GetByChatType(enum.ChatType_Private)
  580. redis.Chat.AddPrivateMsg(p.playerID, toPlayerID, chatTypeConfig.MsgLimit, req)
  581. sessions.PushPlayer(p.playerID, nameRoute.PushGamePlayer_ChatPrivateNew, req)
  582. }
  583. // 系统消息事件
  584. func (p *actorPlayer) chatSystemMsg(eventData cfacade.IEventData) {
  585. e, ok := eventData.(*event.ChatSystemMsg)
  586. if !ok {
  587. return
  588. }
  589. params := e.Params()
  590. if params == nil {
  591. return
  592. }
  593. textType := enum.ChatMsgType(params.Type)
  594. if !data.ChatMsgTemplate.ContainChatMsgType(textType) {
  595. // 跳过没有配置的类型
  596. return
  597. }
  598. chatTable := db.GetChatTable(p.playerID)
  599. newSystemMsg := chatTable.AddSystemMsg(params, int(data.Const.SystemChatLimit))
  600. chatTable.Save2Queue()
  601. if p.isOnline {
  602. sessions.PushPlayer(p.playerID, nameRoute.PushGamePlayer_ChatSystemNew, newSystemMsg.ToProto())
  603. }
  604. }
  605. // 聊天室更新(联盟或者沙盘地图更新的时候触发)
  606. func (p *actorPlayer) chatRoomUpdate(req *pb.PlayerChatRoomUpdate) {
  607. var (
  608. chatType = enum.ChatType(req.ChatType) // 聊天室类型
  609. chatID = req.ChatID // 聊天室ID
  610. isExit = req.IsExit // 是否退出
  611. chatTable = db.GetChatTable(p.playerID)
  612. )
  613. chatRoom, found := chatTable.GetChatRoom(chatType, chatID)
  614. if isExit {
  615. // 如果已经不存在了,则忽略
  616. if !found {
  617. return
  618. }
  619. chatTable.RemoveChatRoom(chatType, chatID)
  620. if chatType == enum.ChatType_League {
  621. // 删除redis的联盟聊天室成员
  622. redis.Chat.DelLeagueMember(chatID, p.playerID)
  623. }
  624. } else {
  625. chatRoom = dbChat.NewChatRoom(chatType, chatID, "", 0)
  626. chatTable.AddChatRoom(chatRoom)
  627. // 新加入就推送最新的20条消息
  628. actorRemote.Chat.Push(chatRoom.ChatType, p.playerID, chatID)
  629. if chatType == enum.ChatType_League {
  630. // 添加redis的联盟聊天室成员
  631. redis.Chat.AddLeagueMember(chatID, p.playerID)
  632. }
  633. }
  634. // 保存
  635. chatTable.Save2Queue()
  636. sessions.PushPlayer(p.playerID, nameRoute.PushGamePlayer_ChatRoomUpdate, &pb.ChatRoomUpdate{
  637. ChatRoom: chatRoom.ToChatRoomProto(),
  638. IsExit: isExit,
  639. })
  640. }
  641. // 收到地图节点的系统消息
  642. func (p *actorPlayer) chatMapSystemMsg(req *pb.ParamsTemplate) {
  643. chatSystemEvent := event.NewChatSystemMsgByTemplate(p.playerID, req)
  644. p.PostEvent(chatSystemEvent)
  645. }