ChatRecord.lua 18 KB

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