-- 绝对时间排行榜活动 中心服逻辑 local LuaMongo = _G.lua_mongo local InnerMsg = require("core.InnerMsg") local Util = require("common.Util") local HtmlUtil = require("common.HtmlUtil") local Lang = require("common.Lang") local CommonDB = require("common.CommonDB") local Msg = require("core.Msg") local ObjHuman = require("core.ObjHuman") local Broadcast = require("broadcast.Broadcast") local Grid = require("bag.Grid") local BagLogic = require("bag.BagLogic") local ItemDefine = require("bag.ItemDefine") local MiddleManager = require("middle.MiddleManager") local AbsActDefine = require("absAct.AbsActDefine") local AbsActLogic = require("absAct.AbsActLogic") local Log = require("common.Log") local AbsActExcel = require("excel.absAct") local RoleLogic = require("role.RoleLogic") local DB = require("common.DB") local Log = require("common.Log") local MailManager = require("mail.MailManager") local MiddleLogic = require("middle.MiddleLogic") local MailExcel = require("excel.mail") local Lang = require("common.Lang") local Broadcast = require("broadcast.Broadcast") local YunYingLogic = require("yunying.YunYingLogic") db = db or {} -- 加载排行榜 function loadBoard() -- 角色 local cnt = 0 LuaMongo.find(DB.db_abs_billboard, fields) while true do local data = { } if not LuaMongo.next(data) then break end cnt = cnt + 1 if cnt % 1000 == 0 then _G.collectgarbage("step", 100000) end -- 充值榜 updateData(data, true) end end -- 启动后初始化 function initAfterStart() if _G.is_middle ~= true then return end loadBoard() end -- 初始data function initData() local data = {} data.value1 = 0 data.value2 = 0 data.time = 0 data.uuid = nil return data end -- 获取 function getBoard(mainId,actId, nosort) local board = db[mainId] and db[mainId][actId] or nil if not board then initBoard(mainId,actId) board = db[mainId] and db[mainId][actId] or nil end if board and board.dirty and (not nosort) then board.dirty = nil updateRank(board) end return board end -- 初始化 function initBoard(mainId,actId) db[mainId] = db[mainId] or {} local board = {} board.uuid2rank = {} -- 根据UUID获取名次 board.rank2data = {} -- 根据名次获取DATA board.dirty = nil -- 是否改变过 board.actId = actId -- 类型 board.mainId = mainId -- 类型 db[mainId][actId] = board end -- 刷新上榜时间 function refreshTime(data) data.billboard = data.billboard or {} data.billboard[data.mainId] = data.billboard[data.mainId] or {} data.billboard[data.actId] = os.time() end -- 获取上榜时间 function getTime(data) if not data.billboard or not data.billboard[data.mainId] then return end return data.billboard[data.mainId][data.actId] end -- 排序 function updateRank(board) if not board then return end for uuid in pairs(board.uuid2rank) do board.uuid2rank[uuid] = nil end for rank, data in ipairs(board.rank2data) do board.uuid2rank[data.uuid] = rank end end -- 获取排名名次 function getRank(mainId,actId, uuid) local board = getBoard(mainId,actId) if not board then return end return board.uuid2rank[uuid] end -- 根据名次获取信息 function getRankData(mainId,actId, rank) local board = getBoard(mainId,actId) if not board then return end return board.rank2data[rank] end -- 排名值 function getValues(db) return db.param end -- 比较 function cmpValues(data1, data2) if data1.value1 ~= data2.value1 then return data1.value1 > data2.value1 end if data1.value2 ~= data2.value2 then return data1.value2 > data2.value2 end if (data1.time or 0) ~=(data2.time or 0) then return(data1.time or 0) <(data2.time or 0) end return true end -- 设置值 function setValues(tempData, data, value1, value2) tempData.uuid = data.uuid tempData.value1 = value1 tempData.value2 = value2 or 0 tempData.time = getTime(data) end -- local TempData = nil function updateData(data, isInit) local board = getBoard(data.mainId,data.actId, isInit) if not board then return end local value1 = getValues(data) if not value1 then return end local dbrank = board.uuid2rank[data.uuid] local dbdata = dbrank and board.rank2data[dbrank] if dbdata then if dbdata.value1 == value1 and dbdata.value2 ==(value2 or 0) then return -- 优化,原来值跟新值一样 end table.remove(board.rank2data, dbrank) end if not isInit then -- 刷新上榜时间 refreshTime(data) end local maxRank = #board.rank2data local rank = maxRank + 1 TempData = TempData or initData() setValues(TempData, data, value1, value2) for i = maxRank, 1, -1 do local tdata = board.rank2data[i] if cmpValues(tdata, TempData) then break end board.rank2data[i + 1] = tdata rank = i end if rank > AbsActDefine.BILLBOARD_MAX_CNT then return end local data2 = nil if maxRank < AbsActDefine.BILLBOARD_MAX_CNT then data2 = initData() else data2 = board.rank2data[AbsActDefine.BILLBOARD_MAX_CNT + 1] end setValues(data2, data, value1, value2) board.rank2data[rank] = data2 board.rank2data[AbsActDefine.BILLBOARD_MAX_CNT + 1] = nil if rank ~= dbrank then board.dirty = true end return true end ----------------------------------------------------------------------- --绝对时间活动 数据库操作 -start local tempTb = {} local queryByUuid = { uuid = nil } local auTb = {} local billboardData = {} -- 加入队列 function add(msg) Util.cleanTable(auTb) auTb.uuid = msg.roleBase.uuid auTb.roleBase = {} RoleLogic.makeRoleBase(msg.roleBase,auTb.roleBase) auTb.svrIndex = msg.svrIndex auTb.svrName = msg.svrName auTb.mainId = msg.mainId auTb.actId = msg.actId local data = query(msg.roleBase.uuid) if data ~= nil then queryByUuid.uuid = msg.roleBase.uuid tempTb["$set"] = nil tempTb["$set"] = auTb LuaMongo.update(DB.db_abs_billboard, queryByUuid, tempTb) return auTb end LuaMongo.insert(DB.db_abs_billboard, auTb) return auTb end -- 查询队列 function query(uuid, fileds) queryByUuid.uuid = uuid local data={} LuaMongo.find(DB.db_abs_billboard, queryByUuid, fileds) if not LuaMongo.next(data) then return nil end return data end -- 更新 function chargeUpdate(uuid, param,actId,mainId) queryByUuid.uuid = uuid local updateTb = {["param"] = param,["actId"] = actId,["mainId"] = mainId} tempTb["$set"] = nil tempTb["$set"] = updateTb LuaMongo.update(DB.db_abs_billboard, queryByUuid, tempTb) end --绝对时间活动 数据库操作 -end ------------------------------------------------------------------------ --绝对时间 排行榜 start function billboardSet(fd, msg) -- 加入数据库 local data = add(msg) -- 更新数据 chargeUpdate(msg.roleBase.uuid, msg.op.param,msg.actId,msg.mainId) data.param = msg.op.param updateData(data) end function LW_ABS_ACT_BILLBOARD_DB(fd,msg) local board = getBoard(msg.mainId,msg.actId) if not board then return end local msgRet = InnerMsg.wl.WL_ABS_ACT_BILLBOARD_DB_RETURN msgRet.actId = msg.actId msgRet.mainId = msg.mainId msgRet.rankDb = Util.copyTable(board) InnerMsg.sendMsg(fd,msgRet) end -- 数据查询 function billboardQuery(fd, msg) local board = getBoard(msg.mainId,msg.actId) if board == nil then return end local boardLen = #board.rank2data boardLen = math.min(boardLen, AbsActDefine.BILLBOARD_MAX_CNT) local msgRet = InnerMsg.wl.WL_ABS_ACT_BILLBOARD_QUERY msgRet.uuid = msg.uuid msgRet.actId = msg.actId msgRet.mainId = msg.mainId msgRet.list = {} local len = 0 for i = 1, boardLen do local data = board.rank2data[i] local uuid = data and data.uuid local db = query(uuid, fields) len = len + 1 msgRet.list[len] = {} local net = msgRet.list[len] net.roleBase = net.roleBase or {} RoleLogic.makeRoleBase(db.roleBase,net.roleBase) net.rank = i net.param = db.param net.svrName = db.svrName end msgRet.list[0] = len InnerMsg.sendMsg(fd, msgRet) end --[[ function billboardReward() -- for k,v in pairs(db) do local state, endTime, starTime = AbsActLogic.isStarted(human, k) local absConfig = AbsActExcel.absActivity[k] for actId,data in pairs(v) do -- 如果活动开启状态为未开启,或者排行榜数据活动ID与当前开启活动ID不一致,则认为排行榜中活动已结束,该发放奖励 if actId ~= absConfig.actId or not state then local config = Util.copyTable(AbsActExcel.billboard) if not config then return end local boardLen = #data.rank2data local configLen = #config if boardLen > 0 then boardLen = math.min(boardLen, AbsActDefine.BILLBOARD_MAX_CNT) for i = 1, boardLen do local dbData = board.rank2data[i] local uuid = dbData and dbData.uuid local pDb = query(uuid, fields) local dcId = 0 -- 选出所在档次 for i = 1,configLen do if config[i].actId == actId and config[i].mainId == k then if pDb.param >= config[i].param and config[i].cnt > 0 then if dcId == 0 then dcId = i else dcId = dcId > i and i or dcId end end end end if dcId ~= 0 then config[dcId].cnt = config[dcId].cnt - 1 local mailConfig = MailExcel.mail[config[dcId].mailId] local title = mailConfig.title local senderName = mailConfig.senderName local content = Util.format(mailConfig.content, pDb.param, rank) MiddleLogic.sendWLMail(MailManager.SYSTEM, uuid, title, content, config[dcId].reward, senderName, pDb.svrIndex) else Log.write(Log.LOGID_DEBUG, "billboardReward: "..dcId.." uuid: "..uuid.." rank: "..i) end end initBoard(id) end -- 清空数据库 LuaMongo.remove(DB.db_abs_billboard,{["mainId"] = k,["actId"] = actId}) end end end end]] function LW_ABS_ACT_BILLBOARD_DB_CLEAN(fd,msg) initBoard(msg.mainId,msg.actId) LuaMongo.remove(DB.db_abs_billboard,{["mainId"] = msg.mainId,["actId"] = msg.actId}) end