ChatRecord.lua 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558
  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 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_UNION then
  190. -- 公会聊天
  191. if CHAT_RECORD_UNION[unionUuid] == nil then
  192. CHAT_RECORD_UNION[unionUuid] = {}
  193. end
  194. record = CHAT_RECORD_UNION[unionUuid]
  195. else
  196. -- 其他聊天
  197. if CHAT_RECORD[msgType] == nil then
  198. CHAT_RECORD[msgType] = {}
  199. end
  200. record = CHAT_RECORD[msgType]
  201. end
  202. CHAT_RECORD_JINDU[msgType] = CHAT_RECORD_JINDU[msgType] or 0
  203. CHAT_RECORD_JINDU[msgType] = CHAT_RECORD_JINDU[msgType] + 1
  204. repetitionRecord(human,chatItem.msg)
  205. -- 插入聊天记录到缓存,好友聊天除外
  206. if msgType ~= ChatHandler.CHAT_TYPE_FRIEND then
  207. --
  208. human.db.chatRead = human.db.chatRead or {}
  209. human.db.chatRead[msgType] = human.db.chatRead[msgType] or 0
  210. human.db.chatRead[msgType] = CHAT_RECORD_JINDU[msgType]
  211. local newTb = Util.copyTable(chatItem)
  212. table.insert(record, newTb)
  213. if #record > CHAT_RECORD_CNT then
  214. table.remove(record, 1)
  215. end
  216. end
  217. end
  218. -- 添加跨服聊天记录
  219. function addMiddleRecord(chatItem, msgType)
  220. if msgType ~= ChatHandler.CHAT_TYPE_MIDDLE then
  221. return
  222. end
  223. local record = nil
  224. if CHAT_RECORD[msgType] == nil then
  225. CHAT_RECORD[msgType] = {}
  226. end
  227. record = CHAT_RECORD[msgType]
  228. local nLen = #record
  229. if nLen >= CHAT_MIDDLE_CNT then
  230. local nDelLen = nLen - CHAT_MIDDLE_CNT + 1
  231. for i = nDelLen, 1, -1 do
  232. table.remove(record, i)
  233. end
  234. end
  235. local newTb = Util.copyTable(chatItem)
  236. table.insert(record, newTb)
  237. if #record > CHAT_RECORD_CNT then
  238. table.remove(record, 1)
  239. end
  240. end
  241. -- 根据玩家Uuid 删除聊天记录
  242. function delRecordByUuid(uuid, msgType)
  243. local tb = CHAT_RECORD[msgType]
  244. if tb == nil then
  245. return
  246. end
  247. for i = #tb, 1, -1 do
  248. local record = tb[i]
  249. if record.roleBase.uuid == uuid then
  250. table.remove(tb, i)
  251. end
  252. end
  253. end
  254. -- 添加公会聊天记录
  255. function addUnionRecord(chatItem, unionUuid)
  256. if CHAT_RECORD_UNION[unionUuid] == nil then
  257. CHAT_RECORD_UNION[unionUuid] = {}
  258. end
  259. local newTb = Util.copyTable(chatItem)
  260. table.insert(CHAT_RECORD_UNION[unionUuid], newTb)
  261. if #CHAT_RECORD_UNION[unionUuid] > CHAT_RECORD_CNT then
  262. table.remove(CHAT_RECORD_UNION[unionUuid], 1)
  263. end
  264. end
  265. -- 初始化玩家阅读记录条数
  266. function initHumanChatRead(human)
  267. human.db.chatRead = human.db.chatRead or {}
  268. end
  269. -- 根据类型获取聊天记录
  270. function getChatRecord(human,type)
  271. if type == ChatHandler.CHAT_TYPE_FRIEND then
  272. return
  273. end
  274. local msgRet = Msg.gc.GC_CHAT_RECORD_QUERY
  275. -- 消息记录
  276. local len = 0
  277. if type == ChatHandler.CHAT_TYPE_UNION then -- 公会聊天
  278. if human.db.unionUuid ~= nil then
  279. len = fontUnionRecord(human,msgRet.chatList,human.db.unionUuid)
  280. end
  281. else -- 其他聊天(包括跨服)
  282. len = fontRecord(human,msgRet.chatList,type)
  283. end
  284. msgRet.chatList[0] = len and len or 0
  285. -- 未读信息
  286. for i = 1,ChatHandler.CHAT_TYPE_CNT do
  287. local net = msgRet.notRead[i]
  288. net.msgType = i
  289. net.notRead = 0
  290. -- 私聊特殊
  291. if i == ChatHandler.CHAT_TYPE_FRIEND then
  292. if CHAT_RECORD_FRIEND[human.db._id] == nil then
  293. net.notRead = 0
  294. else
  295. net.notRead = CHAT_RECORD_FRIEND[human.db._id].count
  296. end
  297. elseif i == ChatHandler.CHAT_TYPE_UNION then
  298. local len = CHAT_RECORD_JINDU[i]
  299. if len ~= nil then
  300. human.db.chatRead[i] = human.db.chatRead[i] or 0
  301. net.notRead = len - human.db.chatRead[i]
  302. if net.notRead >= CHAT_RECORD_CNT then
  303. net.notRead = CHAT_RECORD_CNT
  304. elseif net.notRead < 0 then
  305. net.notRead = 0
  306. end
  307. end
  308. else
  309. if CHAT_RECORD[i] ~= nil then
  310. if i ~= ChatHandler.CHAT_TYPE_MIDDLE then
  311. local len = CHAT_RECORD_JINDU[i]
  312. human.db.chatRead[i] = human.db.chatRead[i] or 0
  313. net.notRead = len - human.db.chatRead[i]
  314. if net.notRead >= CHAT_RECORD_CNT then
  315. net.notRead = CHAT_RECORD_CNT
  316. elseif net.notRead < 0 then
  317. net.notRead = 0
  318. end
  319. else
  320. net.notRead = 0
  321. end
  322. end
  323. end
  324. -- 是当前查看类型
  325. if type == i then
  326. local len = CHAT_RECORD_JINDU[i]
  327. human.db.chatRead[i] = len or 0
  328. end
  329. end
  330. msgRet.notRead[0] = ChatHandler.CHAT_TYPE_CNT
  331. Msg.send(msgRet,human.fd)
  332. end
  333. -- 获取私聊聊天记录
  334. function getChatFriendList(human)
  335. local msgRet = Msg.gc.GC_CHAT_FRIEND_RECORD
  336. local cnt = 0
  337. if CHAT_RECORD_FRIEND[human.db._id] then
  338. local tb = CHAT_RECORD_FRIEND[human.db._id].list
  339. for k,v in pairs(tb) do
  340. local fields = {}
  341. RoleLogic.makeRoleBaseFields(fields)
  342. local db = RoleDBLogic.getDb(v,fields)
  343. cnt = cnt + 1
  344. RoleLogic.makeRoleBase(db,msgRet.chatFriendList[cnt])
  345. if cnt >= CHAT_FRIEND_LIST_CNT then
  346. break
  347. end
  348. end
  349. end
  350. msgRet.chatFriendList[0] = cnt
  351. Msg.send(msgRet,human.fd)
  352. if CHAT_RECORD_FRIEND[human.db._id] then
  353. -- 清空未读条数
  354. CHAT_RECORD_FRIEND[human.db._id].count = 0
  355. end
  356. end
  357. -- 根据uuid获取好友聊天记录
  358. function getChatFriendRecord(human,uuid)
  359. -- 没有聊天记录,返回
  360. if CHAT_RECORD_FRIEND[human.db._id] == nil then
  361. return
  362. end
  363. local recordTb = ChatDBLogic.getFriendChatRecord(human.db._id,uuid)
  364. -- 没有与该玩家的聊天记录
  365. if recordTb == nil then
  366. return
  367. end
  368. local msgRet = Msg.gc.GC_CHAT_FRIEND_RECORD_BY_FRIEND
  369. local len = fontFriendRecord(human,msgRet.chatRecord,recordTb.chatRecord,human.db._id,uuid)
  370. msgRet.chatRecord[0] = len
  371. Msg.send(msgRet,human.fd)
  372. end
  373. -- 新增好友聊天
  374. function addFriendChat(human,uuid)
  375. -- 新增聊天,只增加列表,不加记录,所以只对自己的缓存操作
  376. CHAT_RECORD_FRIEND[human.db._id] = CHAT_RECORD_FRIEND[human.db._id] or {count = 0,list = {}}
  377. -- 已经在最近聊天对象列表中
  378. for i = 1, #CHAT_RECORD_FRIEND[human.db._id].list do
  379. if CHAT_RECORD_FRIEND[human.db._id].list[i] == uuid then
  380. return
  381. end
  382. end
  383. table.insert(CHAT_RECORD_FRIEND[human.db._id].list, uuid)
  384. if #CHAT_RECORD_FRIEND[human.db._id].list > CHAT_FRIEND_LIST_CNT then
  385. -- 删除被顶好友记录
  386. local delUuid = CHAT_RECORD_FRIEND[human.db._id].list[1]
  387. ChatDBLogic.delFriendChatRecord(human.db._id,uuid)
  388. table.remove(CHAT_RECORD_FRIEND[human.db._id].list, 1)
  389. end
  390. -- 添加数据库数据
  391. ChatDBLogic.addFriendChatRecord(human.db._id,uuid)
  392. end
  393. function delFriendChatRecord(human,uuid)
  394. -- 清除缓存数据
  395. -- 缓存中不存在私聊聊天数据
  396. if CHAT_RECORD_FRIEND[human.db._id] == nil then
  397. return
  398. end
  399. -- 移除缓存中数据
  400. local exist,index = checkCacheFriend(human.db._id,uuid)
  401. if exist ~= nil and index ~= nil then
  402. table.remove(CHAT_RECORD_FRIEND[human.db._id].list, index)
  403. end
  404. -- 清除数据库数据
  405. ChatDBLogic.delFriendChatRecord(human.db._id,uuid)
  406. -- 查询聊天记录列表
  407. getChatFriendList(human)
  408. end
  409. -- 删除双方私聊记录
  410. function delFriendChatRecordDouble(fUuid,uuid)
  411. -- 清除数据库数据
  412. ChatDBLogic.delFriendChatRecord(fUuid,uuid)
  413. -- 清除数据库数据
  414. ChatDBLogic.delFriendChatRecord(uuid,fUuid)
  415. end
  416. -- 检查私聊缓存中是否存在当前好友
  417. function checkCacheFriend(uuid,fUuid)
  418. if CHAT_RECORD_FRIEND[uuid] == nil then
  419. return
  420. end
  421. local len = #CHAT_RECORD_FRIEND[uuid].list
  422. if len <= 0 then
  423. return
  424. end
  425. for i = 1,len do
  426. local v = CHAT_RECORD_FRIEND[uuid].list[i]
  427. if v == fUuid then
  428. return true,i
  429. end
  430. end
  431. end
  432. -- 发送未读总数
  433. function sendAllNotRead(human)
  434. local allNotRead = 0
  435. -- 未读信息
  436. for i = 1,ChatHandler.CHAT_TYPE_CNT do
  437. -- 私聊特殊
  438. if i == ChatHandler.CHAT_TYPE_FRIEND then
  439. if CHAT_RECORD_FRIEND[human.db._id] ~= nil then
  440. allNotRead = allNotRead + CHAT_RECORD_FRIEND[human.db._id].count
  441. end
  442. else
  443. if CHAT_RECORD[i] ~= nil then
  444. if i ~= ChatHandler.CHAT_TYPE_MIDDLE then
  445. local len = CHAT_RECORD_JINDU[i]
  446. human.db.chatRead[i] = human.db.chatRead[i] or 0
  447. local notRead = len - human.db.chatRead[i]
  448. if notRead >= CHAT_RECORD_CNT then
  449. notRead = CHAT_RECORD_CNT
  450. elseif notRead < 0 then
  451. notRead = 0
  452. end
  453. allNotRead = allNotRead + notRead
  454. end
  455. end
  456. end
  457. end
  458. local msgRet = Msg.gc.GC_CHAT_NOT_READ_ALL
  459. msgRet.notRead = allNotRead
  460. Msg.send(msgRet,human.fd)
  461. end
  462. function repetitionRecord(human,str)
  463. -- 等级大于20级,返回
  464. --if human.db.lv >= 20 then
  465. -- return
  466. --end
  467. -- 充值过,返回
  468. if human.db.topupAcount ~= nil then
  469. return
  470. end
  471. -- 检验聊天内容
  472. if CHAT_RECORD_REPETITION[human.db._id] ~= nil then
  473. if CHAT_RECORD_REPETITION[human.db._id][str] ~= nil then
  474. CHAT_RECORD_REPETITION[human.db._id][str] = CHAT_RECORD_REPETITION[human.db._id][str] + 1
  475. if CHAT_RECORD_REPETITION[human.db._id][str] >= 10 then
  476. human.db.banSayTime = human.db.banSayTime or 0
  477. local banTime = os.time() + 24*60*60
  478. if human.db.banSayTime < banTime then
  479. human.db.banSayTime = banTime
  480. human.db.banSayReason = Lang.CHAT_BAN_REASON_JUBAO
  481. end
  482. end
  483. else
  484. CHAT_RECORD_REPETITION[human.db._id][str] = 1
  485. end
  486. else
  487. CHAT_RECORD_REPETITION[human.db._id] = {}
  488. CHAT_RECORD_REPETITION[human.db._id][str] = 1
  489. end
  490. end