ChatRecord.lua 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567
  1. local LuaMongo = _G.LuaMongo
  2. local Util = require("common.Util")
  3. local Msg = require("core.Msg")
  4. local RoleLogic = require("role.RoleLogic")
  5. local ChatHandler = require("chat.Handler")
  6. local DB = require("common.DB")
  7. local ChatDBLogic = require("chat.ChatDBLogic")
  8. local RoleDBLogic = require("role.RoleDBLogic")
  9. local Lang = require("common.Lang")
  10. CHAT_RECORD_CNT = 30 -- 聊天记录保存60条
  11. CHAT_MIDDLE_CNT = 30 -- 跨服聊天记录缓存条数
  12. CHAT_RECORD_JINDU = CHAT_RECORD_JINDU or {} -- 聊天记录进度
  13. CHAT_FRIEND_LIST_CNT = 20 -- 私聊最多保留20个好友
  14. CHAT_RECORD = CHAT_RECORD or {}
  15. CHAT_RECORD_UNION = CHAT_RECORD_UNION or {}
  16. CHAT_RECORD_FRIEND = CHAT_RECORD_FRIEND or {}
  17. -- 玩家发言记录
  18. CHAT_RECORD_REPETITION = CHAT_RECORD_REPETITION or {}
  19. local function chatRecord_IsMakeRoleBase(nMsgType)
  20. if ChatHandler.CHAT_TYPE_MIDDLE == nMsgType or ChatHandler.CHAT_TYPE_WARZONE == nMsgType then
  21. return false
  22. end
  23. return true
  24. end
  25. -------------- 封装结构体 --------------------
  26. -- 普通聊天记录结构体
  27. local function fontRecord(human,net,msgType)
  28. if CHAT_RECORD[msgType] == nil then
  29. return 0
  30. end
  31. local cnt = 0
  32. local len = #CHAT_RECORD[msgType]
  33. for i = 1, len do
  34. local record = CHAT_RECORD[msgType][i]
  35. if human.db.friendBlack == nil or human.db.friendBlack[record.roleBase.uuid] == nil then
  36. cnt = cnt + 1
  37. net[cnt].msgType = record.msgType
  38. local fields = {}
  39. -- 跨服直接赋值
  40. if false == chatRecord_IsMakeRoleBase(msgType) then
  41. net[cnt].roleBase = Util.copyTable(record.roleBase)
  42. else
  43. RoleLogic.makeRoleBase(record.roleBase,net[cnt].roleBase)
  44. end
  45. RoleLogic.makeRoleBaseFields(fields)
  46. local db = RoleDBLogic.getDb(record.roleBase.uuid,fields)
  47. if db and true == chatRecord_IsMakeRoleBase(msgType) then
  48. RoleLogic.makeRoleBase(db,net[cnt].roleBase)
  49. end
  50. net[cnt].vipLv = record.vipLv
  51. net[cnt].msg = record.msg
  52. net[cnt].sendTime = record.sendTime
  53. net[cnt].isJson = record.isJson
  54. net[cnt].videoUuid = record.videoUuid or ""
  55. net[cnt].unionFrame = record.unionFrame or 0
  56. net[cnt].label = record.label or 0
  57. net[cnt].svrName = record.svrName or ""
  58. end
  59. end
  60. return cnt
  61. end
  62. -- 好友私聊
  63. local function fontFriendRecord(human,net,data,uuid,fUuid)
  64. local len = #data
  65. local cnt = 0
  66. for i = 1, len do
  67. local v = data[i]
  68. if human.db.friendBlack == nil or human.db.friendBlack[v.roleBase.uuid] == nil then
  69. cnt = cnt + 1
  70. net[cnt].msgType = v.msgType
  71. local fields = {}
  72. RoleLogic.makeRoleBase(v.roleBase,net[cnt].roleBase)
  73. RoleLogic.makeRoleBaseFields(fields)
  74. local db = RoleDBLogic.getDb(v.roleBase.uuid,fields)
  75. if db then
  76. RoleLogic.makeRoleBase(db,net[cnt].roleBase)
  77. end
  78. net[cnt].vipLv = v.vipLv
  79. net[cnt].msg = v.msg
  80. net[cnt].sendTime = v.sendTime
  81. net[cnt].isJson = v.isJson
  82. net[cnt].videoUuid = v.videoUuid or ""
  83. net[cnt].unionFrame = v.unionFrame or 0
  84. net[cnt].label = v.label or 0
  85. net[cnt].svrName = v.svrName or ""
  86. end
  87. end
  88. return cnt
  89. end
  90. -- 公会聊天
  91. local function fontUnionRecord(human,net, unionUuid)
  92. if CHAT_RECORD_UNION[unionUuid] == nil then
  93. return 0
  94. end
  95. local cnt = 0
  96. local len = #CHAT_RECORD_UNION[unionUuid]
  97. for i = 1, len do
  98. local record = CHAT_RECORD_UNION[unionUuid][i]
  99. if human.db.friendBlack == nil or human.db.friendBlack[record.roleBase.uuid] == nil then
  100. cnt = cnt + 1
  101. net[cnt].msgType = record.msgType
  102. RoleLogic.makeRoleBase(record.roleBase,net[cnt].roleBase)
  103. local fields = {}
  104. RoleLogic.makeRoleBaseFields(fields)
  105. local db = RoleDBLogic.getDb(record.roleBase.uuid,fields)
  106. if db then
  107. RoleLogic.makeRoleBase(db,net[cnt].roleBase)
  108. end
  109. net[cnt].vipLv = record.vipLv
  110. net[cnt].msg = record.msg
  111. net[cnt].sendTime = record.sendTime
  112. net[cnt].isJson = record.isJson
  113. net[cnt].videoUuid = record.videoUuid or ""
  114. net[cnt].unionFrame = record.unionFrame or 0
  115. net[cnt].label = record.label or 0
  116. net[cnt].svrName = record.svrName or ""
  117. end
  118. end
  119. return cnt
  120. end
  121. ----------------------------end----------------------------------------
  122. -- 启动时,加载玩家私聊数据
  123. function initAfterStart()
  124. CHAT_RECORD_FRIEND = {}
  125. local fields = {uuid = 1,fUuid = 1}
  126. LuaMongo.find(DB.db_chat_record,nil,fields)
  127. while true do
  128. local recordData = {}
  129. if not LuaMongo.next(recordData) then
  130. return
  131. end
  132. local cnt = 0
  133. if CHAT_RECORD_FRIEND[recordData.uuid] == nil then
  134. CHAT_RECORD_FRIEND[recordData.uuid] = {count = 0,list = {}}
  135. end
  136. table.insert(CHAT_RECORD_FRIEND[recordData.uuid].list,recordData.fUuid)
  137. end
  138. end
  139. -- 添加聊天记录
  140. -- uuid 自己的uuid
  141. -- fUuid 好友的Uuid
  142. -- 缓存中 count 为新消息总数,list 为私聊好友列表
  143. function addRecord(human,chatItem, msgType,fUuid)
  144. local uuid = human.db._id
  145. local unionUuid = human.db.unionUuid
  146. local record = nil
  147. if msgType == ChatHandler.CHAT_TYPE_FRIEND then
  148. -- 好友聊天,记录好友到缓存
  149. CHAT_RECORD_FRIEND[uuid] = CHAT_RECORD_FRIEND[uuid] or {count = 0,list = {}}
  150. CHAT_RECORD_FRIEND[fUuid] = CHAT_RECORD_FRIEND[fUuid] or {count = 0,list = {}}
  151. -- 判断uuid是否存在于缓存中
  152. local exist,index = checkCacheFriend(uuid,fUuid)
  153. if exist == nil then
  154. -- 不存在则插入
  155. table.insert(CHAT_RECORD_FRIEND[uuid].list, fUuid)
  156. if #CHAT_RECORD_FRIEND[uuid].list > CHAT_RECORD_CNT then
  157. -- 删除被顶好友记录
  158. local delUuid = CHAT_RECORD_FRIEND[uuid].list[1]
  159. ChatDBLogic.delFriendChatRecord(uuid,fUuid)
  160. table.remove(CHAT_RECORD_FRIEND[uuid].list, 1)
  161. end
  162. else
  163. -- 存在则移除,并重新插入
  164. table.remove(CHAT_RECORD_FRIEND[uuid].list, index)
  165. table.insert(CHAT_RECORD_FRIEND[uuid].list, fUuid)
  166. end
  167. exist,index = checkCacheFriend(fUuid,uuid)
  168. if exist == nil then
  169. table.insert(CHAT_RECORD_FRIEND[fUuid].list, uuid)
  170. if #CHAT_RECORD_FRIEND[fUuid].list > CHAT_RECORD_CNT then
  171. -- 删除被顶好友记录
  172. local delUuid = CHAT_RECORD_FRIEND[fUuid].list[1]
  173. ChatDBLogic.delFriendChatRecord(fUuid,uuid)
  174. table.remove(CHAT_RECORD_FRIEND[fUuid].list, 1)
  175. end
  176. else
  177. -- 存在则移除,并重新插入
  178. table.remove(CHAT_RECORD_FRIEND[fUuid].list, index)
  179. table.insert(CHAT_RECORD_FRIEND[fUuid].list, uuid)
  180. end
  181. CHAT_RECORD_FRIEND[fUuid].count = CHAT_RECORD_FRIEND[fUuid].count + 1
  182. --加聊天记录到数据库
  183. ChatDBLogic.addFriendChatRecord(uuid,fUuid,chatItem)
  184. ChatDBLogic.addFriendChatRecord(fUuid,uuid,chatItem)
  185. elseif msgType == ChatHandler.CHAT_TYPE_MIDDLE then
  186. -- 跨服聊天
  187. -- 本地记录数据
  188. if CHAT_RECORD[msgType] == nil then
  189. CHAT_RECORD[msgType] = {}
  190. end
  191. record = CHAT_RECORD[msgType]
  192. elseif msgType == ChatHandler.CHAT_TYPE_WARZONE then
  193. if CHAT_RECORD[msgType] == nil then
  194. CHAT_RECORD[msgType] = {}
  195. end
  196. record = CHAT_RECORD[msgType]
  197. elseif msgType == ChatHandler.CHAT_TYPE_UNION then
  198. -- 公会聊天
  199. if CHAT_RECORD_UNION[unionUuid] == nil then
  200. CHAT_RECORD_UNION[unionUuid] = {}
  201. end
  202. record = CHAT_RECORD_UNION[unionUuid]
  203. else
  204. -- 其他聊天
  205. if CHAT_RECORD[msgType] == nil then
  206. CHAT_RECORD[msgType] = {}
  207. end
  208. record = CHAT_RECORD[msgType]
  209. end
  210. CHAT_RECORD_JINDU[msgType] = CHAT_RECORD_JINDU[msgType] or 0
  211. CHAT_RECORD_JINDU[msgType] = CHAT_RECORD_JINDU[msgType] + 1
  212. repetitionRecord(human,chatItem.msg)
  213. -- 插入聊天记录到缓存,好友聊天除外
  214. if msgType ~= ChatHandler.CHAT_TYPE_FRIEND then
  215. --
  216. human.db.chatRead = human.db.chatRead or {}
  217. human.db.chatRead[msgType] = human.db.chatRead[msgType] or 0
  218. human.db.chatRead[msgType] = CHAT_RECORD_JINDU[msgType]
  219. local newTb = Util.copyTable(chatItem)
  220. table.insert(record, newTb)
  221. if #record > CHAT_RECORD_CNT then
  222. table.remove(record, 1)
  223. end
  224. end
  225. end
  226. -- 添加跨服聊天记录
  227. function addMiddleRecord(chatItem, msgType)
  228. if msgType ~= ChatHandler.CHAT_TYPE_MIDDLE and msgType ~= ChatHandler.CHAT_TYPE_WARZONE then
  229. print("[addMiddleRecord] 此处返回了?msgType = "..msgType)
  230. return
  231. end
  232. local record = nil
  233. if CHAT_RECORD[msgType] == nil then
  234. CHAT_RECORD[msgType] = {}
  235. end
  236. record = CHAT_RECORD[msgType]
  237. local nLen = #record
  238. if nLen >= CHAT_MIDDLE_CNT then
  239. local nDelLen = nLen - CHAT_MIDDLE_CNT + 1
  240. for i = nDelLen, 1, -1 do
  241. table.remove(record, i)
  242. end
  243. end
  244. local newTb = Util.copyTable(chatItem)
  245. table.insert(record, newTb)
  246. end
  247. -- 根据玩家Uuid 删除聊天记录
  248. function delRecordByUuid(uuid, msgType)
  249. local tb = CHAT_RECORD[msgType]
  250. if tb == nil then
  251. return
  252. end
  253. for i = #tb, 1, -1 do
  254. local record = tb[i]
  255. if record.roleBase.uuid == uuid then
  256. table.remove(tb, i)
  257. end
  258. end
  259. end
  260. -- 添加公会聊天记录
  261. function addUnionRecord(chatItem, unionUuid)
  262. if CHAT_RECORD_UNION[unionUuid] == nil then
  263. CHAT_RECORD_UNION[unionUuid] = {}
  264. end
  265. local newTb = Util.copyTable(chatItem)
  266. table.insert(CHAT_RECORD_UNION[unionUuid], newTb)
  267. if #CHAT_RECORD_UNION[unionUuid] > CHAT_RECORD_CNT then
  268. table.remove(CHAT_RECORD_UNION[unionUuid], 1)
  269. end
  270. end
  271. -- 初始化玩家阅读记录条数
  272. function initHumanChatRead(human)
  273. human.db.chatRead = human.db.chatRead or {}
  274. end
  275. -- 根据类型获取聊天记录
  276. function getChatRecord(human,type)
  277. if type == ChatHandler.CHAT_TYPE_FRIEND then
  278. return
  279. end
  280. local msgRet = Msg.gc.GC_CHAT_RECORD_QUERY
  281. -- 消息记录
  282. local len = 0
  283. if type == ChatHandler.CHAT_TYPE_UNION then -- 公会聊天
  284. if human.db.unionUuid ~= nil then
  285. len = fontUnionRecord(human,msgRet.chatList,human.db.unionUuid)
  286. end
  287. else -- 其他聊天(包括跨服)
  288. len = fontRecord(human,msgRet.chatList,type)
  289. end
  290. msgRet.chatList[0] = len and len or 0
  291. -- 未读信息
  292. for i = 1,ChatHandler.CHAT_TYPE_CNT do
  293. local net = msgRet.notRead[i]
  294. net.msgType = i
  295. net.notRead = 0
  296. -- 私聊特殊
  297. if i == ChatHandler.CHAT_TYPE_FRIEND then
  298. if CHAT_RECORD_FRIEND[human.db._id] == nil then
  299. net.notRead = 0
  300. else
  301. net.notRead = CHAT_RECORD_FRIEND[human.db._id].count
  302. end
  303. elseif i == ChatHandler.CHAT_TYPE_UNION then
  304. local len = CHAT_RECORD_JINDU[i]
  305. if len ~= nil then
  306. human.db.chatRead[i] = human.db.chatRead[i] or 0
  307. net.notRead = len - human.db.chatRead[i]
  308. if net.notRead >= CHAT_RECORD_CNT then
  309. net.notRead = CHAT_RECORD_CNT
  310. elseif net.notRead < 0 then
  311. net.notRead = 0
  312. end
  313. end
  314. else
  315. if CHAT_RECORD[i] ~= nil then
  316. if i ~= ChatHandler.CHAT_TYPE_MIDDLE and i ~= ChatHandler.CHAT_TYPE_WARZONE then
  317. local len = CHAT_RECORD_JINDU[i]
  318. human.db.chatRead[i] = human.db.chatRead[i] or 0
  319. net.notRead = len - human.db.chatRead[i]
  320. if net.notRead >= CHAT_RECORD_CNT then
  321. net.notRead = CHAT_RECORD_CNT
  322. elseif net.notRead < 0 then
  323. net.notRead = 0
  324. end
  325. else
  326. net.notRead = 0
  327. end
  328. end
  329. end
  330. -- 是当前查看类型
  331. if type == i then
  332. local len = CHAT_RECORD_JINDU[i]
  333. human.db.chatRead[i] = len or 0
  334. end
  335. end
  336. msgRet.notRead[0] = ChatHandler.CHAT_TYPE_CNT
  337. Msg.send(msgRet,human.fd)
  338. end
  339. -- 获取私聊聊天记录
  340. function getChatFriendList(human)
  341. local msgRet = Msg.gc.GC_CHAT_FRIEND_RECORD
  342. local cnt = 0
  343. if CHAT_RECORD_FRIEND[human.db._id] then
  344. local tb = CHAT_RECORD_FRIEND[human.db._id].list
  345. for k,v in pairs(tb) do
  346. local fields = {}
  347. RoleLogic.makeRoleBaseFields(fields)
  348. local db = RoleDBLogic.getDb(v,fields)
  349. cnt = cnt + 1
  350. RoleLogic.makeRoleBase(db,msgRet.chatFriendList[cnt])
  351. if cnt >= CHAT_FRIEND_LIST_CNT then
  352. break
  353. end
  354. end
  355. end
  356. msgRet.chatFriendList[0] = cnt
  357. Msg.send(msgRet,human.fd)
  358. if CHAT_RECORD_FRIEND[human.db._id] then
  359. -- 清空未读条数
  360. CHAT_RECORD_FRIEND[human.db._id].count = 0
  361. end
  362. end
  363. -- 根据uuid获取好友聊天记录
  364. function getChatFriendRecord(human,uuid)
  365. -- 没有聊天记录,返回
  366. if CHAT_RECORD_FRIEND[human.db._id] == nil then
  367. return
  368. end
  369. local recordTb = ChatDBLogic.getFriendChatRecord(human.db._id,uuid)
  370. -- 没有与该玩家的聊天记录
  371. if recordTb == nil then
  372. return
  373. end
  374. local msgRet = Msg.gc.GC_CHAT_FRIEND_RECORD_BY_FRIEND
  375. local len = fontFriendRecord(human,msgRet.chatRecord,recordTb.chatRecord,human.db._id,uuid)
  376. msgRet.chatRecord[0] = len
  377. Msg.send(msgRet,human.fd)
  378. end
  379. -- 新增好友聊天
  380. function addFriendChat(human,uuid)
  381. -- 新增聊天,只增加列表,不加记录,所以只对自己的缓存操作
  382. CHAT_RECORD_FRIEND[human.db._id] = CHAT_RECORD_FRIEND[human.db._id] or {count = 0,list = {}}
  383. -- 已经在最近聊天对象列表中
  384. for i = 1, #CHAT_RECORD_FRIEND[human.db._id].list do
  385. if CHAT_RECORD_FRIEND[human.db._id].list[i] == uuid then
  386. return
  387. end
  388. end
  389. table.insert(CHAT_RECORD_FRIEND[human.db._id].list, uuid)
  390. if #CHAT_RECORD_FRIEND[human.db._id].list > CHAT_FRIEND_LIST_CNT then
  391. -- 删除被顶好友记录
  392. local delUuid = CHAT_RECORD_FRIEND[human.db._id].list[1]
  393. ChatDBLogic.delFriendChatRecord(human.db._id,uuid)
  394. table.remove(CHAT_RECORD_FRIEND[human.db._id].list, 1)
  395. end
  396. -- 添加数据库数据
  397. ChatDBLogic.addFriendChatRecord(human.db._id,uuid)
  398. end
  399. function delFriendChatRecord(human,uuid)
  400. -- 清除缓存数据
  401. -- 缓存中不存在私聊聊天数据
  402. if CHAT_RECORD_FRIEND[human.db._id] == nil then
  403. return
  404. end
  405. -- 移除缓存中数据
  406. local exist,index = checkCacheFriend(human.db._id,uuid)
  407. if exist ~= nil and index ~= nil then
  408. table.remove(CHAT_RECORD_FRIEND[human.db._id].list, index)
  409. end
  410. -- 清除数据库数据
  411. ChatDBLogic.delFriendChatRecord(human.db._id,uuid)
  412. -- 查询聊天记录列表
  413. getChatFriendList(human)
  414. end
  415. -- 删除双方私聊记录
  416. function delFriendChatRecordDouble(fUuid,uuid)
  417. -- 清除数据库数据
  418. ChatDBLogic.delFriendChatRecord(fUuid,uuid)
  419. -- 清除数据库数据
  420. ChatDBLogic.delFriendChatRecord(uuid,fUuid)
  421. end
  422. -- 检查私聊缓存中是否存在当前好友
  423. function checkCacheFriend(uuid,fUuid)
  424. if CHAT_RECORD_FRIEND[uuid] == nil then
  425. return
  426. end
  427. local len = #CHAT_RECORD_FRIEND[uuid].list
  428. if len <= 0 then
  429. return
  430. end
  431. for i = 1,len do
  432. local v = CHAT_RECORD_FRIEND[uuid].list[i]
  433. if v == fUuid then
  434. return true,i
  435. end
  436. end
  437. end
  438. -- 发送未读总数
  439. function sendAllNotRead(human)
  440. local allNotRead = 0
  441. -- 未读信息
  442. for i = 1,ChatHandler.CHAT_TYPE_CNT do
  443. -- 私聊特殊
  444. if i == ChatHandler.CHAT_TYPE_FRIEND then
  445. if CHAT_RECORD_FRIEND[human.db._id] ~= nil then
  446. allNotRead = allNotRead + CHAT_RECORD_FRIEND[human.db._id].count
  447. end
  448. else
  449. if CHAT_RECORD[i] ~= nil then
  450. if i ~= ChatHandler.CHAT_TYPE_MIDDLE and i~= ChatHandler.CHAT_TYPE_WARZONE then
  451. local len = CHAT_RECORD_JINDU[i]
  452. human.db.chatRead[i] = human.db.chatRead[i] or 0
  453. local notRead = len - human.db.chatRead[i]
  454. if notRead >= CHAT_RECORD_CNT then
  455. notRead = CHAT_RECORD_CNT
  456. elseif notRead < 0 then
  457. notRead = 0
  458. end
  459. allNotRead = allNotRead + notRead
  460. end
  461. end
  462. end
  463. end
  464. local msgRet = Msg.gc.GC_CHAT_NOT_READ_ALL
  465. msgRet.notRead = allNotRead
  466. Msg.send(msgRet,human.fd)
  467. end
  468. function repetitionRecord(human,str)
  469. -- 等级大于20级,返回
  470. --if human.db.lv >= 20 then
  471. -- return
  472. --end
  473. -- 充值过,返回
  474. if human.db.topupAcount ~= nil then
  475. return
  476. end
  477. -- 检验聊天内容
  478. if CHAT_RECORD_REPETITION[human.db._id] ~= nil then
  479. if CHAT_RECORD_REPETITION[human.db._id][str] ~= nil then
  480. CHAT_RECORD_REPETITION[human.db._id][str] = CHAT_RECORD_REPETITION[human.db._id][str] + 1
  481. if CHAT_RECORD_REPETITION[human.db._id][str] >= 10 then
  482. human.db.banSayTime = human.db.banSayTime or 0
  483. local banTime = os.time() + 24*60*60
  484. if human.db.banSayTime < banTime then
  485. human.db.banSayTime = banTime
  486. human.db.banSayReason = Lang.CHAT_BAN_REASON_JUBAO
  487. end
  488. end
  489. else
  490. CHAT_RECORD_REPETITION[human.db._id][str] = 1
  491. end
  492. else
  493. CHAT_RECORD_REPETITION[human.db._id] = {}
  494. CHAT_RECORD_REPETITION[human.db._id][str] = 1
  495. end
  496. end