ChatRecord.lua 17 KB

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