local LuaMongo = _G.LuaMongo local Util = require("common.Util") local Msg = require("core.Msg") local RoleLogic = require("role.RoleLogic") local ChatHandler = require("chat.Handler") local DB = require("common.DB") local ChatDBLogic = require("chat.ChatDBLogic") local RoleDBLogic = require("role.RoleDBLogic") local Lang = require("common.Lang") CHAT_RECORD_CNT = 30 -- 聊天记录保存60条 CHAT_RECORD_JINDU = CHAT_RECORD_JINDU or {} -- 聊天记录进度 CHAT_FRIEND_LIST_CNT = 20 -- 私聊最多保留20个好友 CHAT_RECORD = CHAT_RECORD or {} CHAT_RECORD_UNION = CHAT_RECORD_UNION or {} CHAT_RECORD_FRIEND = CHAT_RECORD_FRIEND or {} -- 玩家发言记录 CHAT_RECORD_REPETITION = CHAT_RECORD_REPETITION or {} -------------- 封装结构体 -------------------- -- 普通聊天记录结构体 local function fontRecord(human,net,msgType) if CHAT_RECORD[msgType] == nil then return 0 end local cnt = 0 local len = #CHAT_RECORD[msgType] for i = 1, len do local record = CHAT_RECORD[msgType][i] if human.db.friendBlack == nil or human.db.friendBlack[record.roleBase.uuid] == nil then cnt = cnt + 1 net[cnt].msgType = record.msgType local fields = {} RoleLogic.makeRoleBase(record.roleBase,net[cnt].roleBase) RoleLogic.makeRoleBaseFields(fields) local db = RoleDBLogic.getDb(record.roleBase.uuid,fields) if db then RoleLogic.makeRoleBase(db,net[cnt].roleBase) end net[cnt].vipLv = record.vipLv net[cnt].msg = record.msg net[cnt].sendTime = record.sendTime net[cnt].isJson = record.isJson net[cnt].videoUuid = record.videoUuid or "" net[cnt].unionFrame = record.unionFrame or 0 net[cnt].label = record.label or 0 net[cnt].svrName = record.svrName or "" end end return cnt end -- 好友私聊 local function fontFriendRecord(human,net,data,uuid,fUuid) local len = #data local cnt = 0 for i = 1, len do local v = data[i] if human.db.friendBlack == nil or human.db.friendBlack[v.roleBase.uuid] == nil then cnt = cnt + 1 net[cnt].msgType = v.msgType local fields = {} RoleLogic.makeRoleBase(v.roleBase,net[cnt].roleBase) RoleLogic.makeRoleBaseFields(fields) local db = RoleDBLogic.getDb(v.roleBase.uuid,fields) if db then RoleLogic.makeRoleBase(db,net[cnt].roleBase) end net[cnt].vipLv = v.vipLv net[cnt].msg = v.msg net[cnt].sendTime = v.sendTime net[cnt].isJson = v.isJson net[cnt].videoUuid = v.videoUuid or "" net[cnt].unionFrame = v.unionFrame or 0 net[cnt].label = v.label or 0 net[cnt].svrName = v.svrName or "" end end return cnt end -- 公会聊天 local function fontUnionRecord(human,net, unionUuid) if CHAT_RECORD_UNION[unionUuid] == nil then return 0 end local cnt = 0 local len = #CHAT_RECORD_UNION[unionUuid] for i = 1, len do local record = CHAT_RECORD_UNION[unionUuid][i] if human.db.friendBlack == nil or human.db.friendBlack[record.roleBase.uuid] == nil then cnt = cnt + 1 net[cnt].msgType = record.msgType RoleLogic.makeRoleBase(record.roleBase,net[cnt].roleBase) local fields = {} RoleLogic.makeRoleBaseFields(fields) local db = RoleDBLogic.getDb(record.roleBase.uuid,fields) if db then RoleLogic.makeRoleBase(db,net[cnt].roleBase) end net[cnt].vipLv = record.vipLv net[cnt].msg = record.msg net[cnt].sendTime = record.sendTime net[cnt].isJson = record.isJson net[cnt].videoUuid = record.videoUuid or "" net[cnt].unionFrame = record.unionFrame or 0 net[cnt].label = record.label or 0 net[cnt].svrName = record.svrName or "" end end return cnt end ----------------------------end---------------------------------------- -- 启动时,加载玩家私聊数据 function initAfterStart() CHAT_RECORD_FRIEND = {} local fields = {uuid = 1,fUuid = 1} LuaMongo.find(DB.db_chat_record,nil,fields) while true do local recordData = {} if not LuaMongo.next(recordData) then return end local cnt = 0 if CHAT_RECORD_FRIEND[recordData.uuid] == nil then CHAT_RECORD_FRIEND[recordData.uuid] = {count = 0,list = {}} end table.insert(CHAT_RECORD_FRIEND[recordData.uuid].list,recordData.fUuid) end end -- 添加聊天记录 -- uuid 自己的uuid -- fUuid 好友的Uuid -- 缓存中 count 为新消息总数,list 为私聊好友列表 function addRecord(human,chatItem, msgType,fUuid) local uuid = human.db._id local unionUuid = human.db.unionUuid local record = nil if msgType == ChatHandler.CHAT_TYPE_FRIEND then -- 好友聊天,记录好友到缓存 CHAT_RECORD_FRIEND[uuid] = CHAT_RECORD_FRIEND[uuid] or {count = 0,list = {}} CHAT_RECORD_FRIEND[fUuid] = CHAT_RECORD_FRIEND[fUuid] or {count = 0,list = {}} -- 判断uuid是否存在于缓存中 local exist,index = checkCacheFriend(uuid,fUuid) if exist == nil then -- 不存在则插入 table.insert(CHAT_RECORD_FRIEND[uuid].list, fUuid) if #CHAT_RECORD_FRIEND[uuid].list > CHAT_RECORD_CNT then -- 删除被顶好友记录 local delUuid = CHAT_RECORD_FRIEND[uuid].list[1] ChatDBLogic.delFriendChatRecord(uuid,fUuid) table.remove(CHAT_RECORD_FRIEND[uuid].list, 1) end else -- 存在则移除,并重新插入 table.remove(CHAT_RECORD_FRIEND[uuid].list, index) table.insert(CHAT_RECORD_FRIEND[uuid].list, fUuid) end exist,index = checkCacheFriend(fUuid,uuid) if exist == nil then table.insert(CHAT_RECORD_FRIEND[fUuid].list, uuid) if #CHAT_RECORD_FRIEND[fUuid].list > CHAT_RECORD_CNT then -- 删除被顶好友记录 local delUuid = CHAT_RECORD_FRIEND[fUuid].list[1] ChatDBLogic.delFriendChatRecord(fUuid,uuid) table.remove(CHAT_RECORD_FRIEND[fUuid].list, 1) end else -- 存在则移除,并重新插入 table.remove(CHAT_RECORD_FRIEND[fUuid].list, index) table.insert(CHAT_RECORD_FRIEND[fUuid].list, uuid) end CHAT_RECORD_FRIEND[fUuid].count = CHAT_RECORD_FRIEND[fUuid].count + 1 --加聊天记录到数据库 ChatDBLogic.addFriendChatRecord(uuid,fUuid,chatItem) ChatDBLogic.addFriendChatRecord(fUuid,uuid,chatItem) elseif msgType == ChatHandler.CHAT_TYPE_MIDDLE then -- 跨服聊天 -- 本地记录数据 if CHAT_RECORD[msgType] == nil then CHAT_RECORD[msgType] = {} end record = CHAT_RECORD[msgType] elseif msgType == ChatHandler.CHAT_TYPE_UNION then -- 公会聊天 if CHAT_RECORD_UNION[unionUuid] == nil then CHAT_RECORD_UNION[unionUuid] = {} end record = CHAT_RECORD_UNION[unionUuid] else -- 其他聊天 if CHAT_RECORD[msgType] == nil then CHAT_RECORD[msgType] = {} end record = CHAT_RECORD[msgType] end CHAT_RECORD_JINDU[msgType] = CHAT_RECORD_JINDU[msgType] or 0 CHAT_RECORD_JINDU[msgType] = CHAT_RECORD_JINDU[msgType] + 1 repetitionRecord(human,chatItem.msg) -- 插入聊天记录到缓存,好友聊天除外 if msgType ~= ChatHandler.CHAT_TYPE_FRIEND then -- human.db.chatRead = human.db.chatRead or {} human.db.chatRead[msgType] = human.db.chatRead[msgType] or 0 human.db.chatRead[msgType] = CHAT_RECORD_JINDU[msgType] local newTb = Util.copyTable(chatItem) table.insert(record, newTb) if #record > CHAT_RECORD_CNT then table.remove(record, 1) end end end -- 根据玩家Uuid 删除聊天记录 function delRecordByUuid(uuid, msgType) local tb = CHAT_RECORD[msgType] if tb == nil then return end for i = #tb, 1, -1 do local record = tb[i] if record.roleBase.uuid == uuid then table.remove(tb, i) end end end -- 添加公会聊天记录 function addUnionRecord(chatItem, unionUuid) if CHAT_RECORD_UNION[unionUuid] == nil then CHAT_RECORD_UNION[unionUuid] = {} end local newTb = Util.copyTable(chatItem) table.insert(CHAT_RECORD_UNION[unionUuid], newTb) if #CHAT_RECORD_UNION[unionUuid] > CHAT_RECORD_CNT then table.remove(CHAT_RECORD_UNION[unionUuid], 1) end end -- 初始化玩家阅读记录条数 function initHumanChatRead(human) human.db.chatRead = human.db.chatRead or {} end -- 根据类型获取聊天记录 function getChatRecord(human,type) if type == ChatHandler.CHAT_TYPE_FRIEND then return end local msgRet = Msg.gc.GC_CHAT_RECORD_QUERY -- 消息记录 local len = 0 if type == ChatHandler.CHAT_TYPE_UNION then -- 公会聊天 if human.db.unionUuid ~= nil then len = fontUnionRecord(human,msgRet.chatList,human.db.unionUuid) end else -- 其他聊天(包括跨服) len = fontRecord(human,msgRet.chatList,type) end msgRet.chatList[0] = len and len or 0 -- 未读信息 for i = 1,ChatHandler.CHAT_TYPE_CNT do local net = msgRet.notRead[i] net.msgType = i net.notRead = 0 -- 私聊特殊 if i == ChatHandler.CHAT_TYPE_FRIEND then if CHAT_RECORD_FRIEND[human.db._id] == nil then net.notRead = 0 else net.notRead = CHAT_RECORD_FRIEND[human.db._id].count end elseif i == ChatHandler.CHAT_TYPE_UNION then local len = CHAT_RECORD_JINDU[i] if len ~= nil then human.db.chatRead[i] = human.db.chatRead[i] or 0 net.notRead = len - human.db.chatRead[i] if net.notRead >= CHAT_RECORD_CNT then net.notRead = CHAT_RECORD_CNT elseif net.notRead < 0 then net.notRead = 0 end end else if CHAT_RECORD[i] ~= nil then local len = CHAT_RECORD_JINDU[i] human.db.chatRead[i] = human.db.chatRead[i] or 0 net.notRead = len - human.db.chatRead[i] if net.notRead >= CHAT_RECORD_CNT then net.notRead = CHAT_RECORD_CNT elseif net.notRead < 0 then net.notRead = 0 end end end -- 是当前查看类型 if type == i then local len = CHAT_RECORD_JINDU[i] human.db.chatRead[i] = len or 0 end end msgRet.notRead[0] = ChatHandler.CHAT_TYPE_CNT Msg.send(msgRet,human.fd) end -- 获取私聊聊天记录 function getChatFriendList(human) local msgRet = Msg.gc.GC_CHAT_FRIEND_RECORD local cnt = 0 if CHAT_RECORD_FRIEND[human.db._id] then local tb = CHAT_RECORD_FRIEND[human.db._id].list for k,v in pairs(tb) do local fields = {} RoleLogic.makeRoleBaseFields(fields) local db = RoleDBLogic.getDb(v,fields) cnt = cnt + 1 RoleLogic.makeRoleBase(db,msgRet.chatFriendList[cnt]) if cnt >= CHAT_FRIEND_LIST_CNT then break end end end msgRet.chatFriendList[0] = cnt Msg.send(msgRet,human.fd) if CHAT_RECORD_FRIEND[human.db._id] then -- 清空未读条数 CHAT_RECORD_FRIEND[human.db._id].count = 0 end end -- 根据uuid获取好友聊天记录 function getChatFriendRecord(human,uuid) -- 没有聊天记录,返回 if CHAT_RECORD_FRIEND[human.db._id] == nil then return end local recordTb = ChatDBLogic.getFriendChatRecord(human.db._id,uuid) -- 没有与该玩家的聊天记录 if recordTb == nil then return end local msgRet = Msg.gc.GC_CHAT_FRIEND_RECORD_BY_FRIEND local len = fontFriendRecord(human,msgRet.chatRecord,recordTb.chatRecord,human.db._id,uuid) msgRet.chatRecord[0] = len Msg.send(msgRet,human.fd) end -- 新增好友聊天 function addFriendChat(human,uuid) -- 新增聊天,只增加列表,不加记录,所以只对自己的缓存操作 CHAT_RECORD_FRIEND[human.db._id] = CHAT_RECORD_FRIEND[human.db._id] or {count = 0,list = {}} -- 已经在最近聊天对象列表中 for i = 1, #CHAT_RECORD_FRIEND[human.db._id].list do if CHAT_RECORD_FRIEND[human.db._id].list[i] == uuid then return end end table.insert(CHAT_RECORD_FRIEND[human.db._id].list, uuid) if #CHAT_RECORD_FRIEND[human.db._id].list > CHAT_FRIEND_LIST_CNT then -- 删除被顶好友记录 local delUuid = CHAT_RECORD_FRIEND[human.db._id].list[1] ChatDBLogic.delFriendChatRecord(human.db._id,uuid) table.remove(CHAT_RECORD_FRIEND[human.db._id].list, 1) end -- 添加数据库数据 ChatDBLogic.addFriendChatRecord(human.db._id,uuid) end function delFriendChatRecord(human,uuid) -- 清除缓存数据 -- 缓存中不存在私聊聊天数据 if CHAT_RECORD_FRIEND[human.db._id] == nil then return end -- 移除缓存中数据 local exist,index = checkCacheFriend(human.db._id,uuid) if exist ~= nil and index ~= nil then table.remove(CHAT_RECORD_FRIEND[human.db._id].list, index) end -- 清除数据库数据 ChatDBLogic.delFriendChatRecord(human.db._id,uuid) -- 查询聊天记录列表 getChatFriendList(human) end -- 删除双方私聊记录 function delFriendChatRecordDouble(fUuid,uuid) -- 清除数据库数据 ChatDBLogic.delFriendChatRecord(fUuid,uuid) -- 清除数据库数据 ChatDBLogic.delFriendChatRecord(uuid,fUuid) end -- 检查私聊缓存中是否存在当前好友 function checkCacheFriend(uuid,fUuid) if CHAT_RECORD_FRIEND[uuid] == nil then return end local len = #CHAT_RECORD_FRIEND[uuid].list if len <= 0 then return end for i = 1,len do local v = CHAT_RECORD_FRIEND[uuid].list[i] if v == fUuid then return true,i end end end -- 发送未读总数 function sendAllNotRead(human) local allNotRead = 0 -- 未读信息 for i = 1,ChatHandler.CHAT_TYPE_CNT do -- 私聊特殊 if i == ChatHandler.CHAT_TYPE_FRIEND then if CHAT_RECORD_FRIEND[human.db._id] ~= nil then allNotRead = allNotRead + CHAT_RECORD_FRIEND[human.db._id].count end else if CHAT_RECORD[i] ~= nil then local len = CHAT_RECORD_JINDU[i] human.db.chatRead[i] = human.db.chatRead[i] or 0 local notRead = len - human.db.chatRead[i] if notRead >= CHAT_RECORD_CNT then notRead = CHAT_RECORD_CNT elseif notRead < 0 then notRead = 0 end allNotRead = allNotRead + notRead end end end local msgRet = Msg.gc.GC_CHAT_NOT_READ_ALL msgRet.notRead = allNotRead Msg.send(msgRet,human.fd) end function repetitionRecord(human,str) -- 等级大于20级,返回 --if human.db.lv >= 20 then -- return --end -- 充值过,返回 if human.db.topupAcount ~= nil then return end -- 检验聊天内容 if CHAT_RECORD_REPETITION[human.db._id] ~= nil then if CHAT_RECORD_REPETITION[human.db._id][str] ~= nil then CHAT_RECORD_REPETITION[human.db._id][str] = CHAT_RECORD_REPETITION[human.db._id][str] + 1 if CHAT_RECORD_REPETITION[human.db._id][str] >= 10 then human.db.banSayTime = human.db.banSayTime or 0 local banTime = os.time() + 24*60*60 if human.db.banSayTime < banTime then human.db.banSayTime = banTime human.db.banSayReason = Lang.CHAT_BAN_REASON_JUBAO end end else CHAT_RECORD_REPETITION[human.db._id][str] = 1 end else CHAT_RECORD_REPETITION[human.db._id] = {} CHAT_RECORD_REPETITION[human.db._id][str] = 1 end end