ChatRecord.lua 18 KB

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