------------------------------------------------------------------ -- 角色相关排行榜 -- 排序规则 -- 征战:征战进度 -- 通天塔:层数 通关时间 -- 战力:战力 -- 等级:等级 ------------------------------------------------------------------ local LuaMongo = _G.lua_mongo local DB = require("common.DB") local BillboardDefine = require("billboard.BillboardDefine") local BillboardDB = require("billboard.BillboardDB") local BillboardAim = require("billboard.BillboardAim") local GlobalWorld = require("core.GlobalWorld") local CombatPosLogic = require("combat.CombatPosLogic") local CombatDefine = require("combat.CombatDefine") local Util = require("common.Util") local AbsActLogic = require("absAct.AbsActLogic") -- 加载角色排行 function loadBoard() -- 角色 local cnt = 0 LuaMongo.find(DB.db_char, nil, BillboardDB.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(BillboardDefine.TYPE_BATTLE, data, true) -- 通天塔 updateData(BillboardDefine.TYPE_TOWER, data, true) -- 战力 updateData(BillboardDefine.TYPE_ZHANDOULI, data, true) -- 等级 updateData(BillboardDefine.TYPE_LV, data, true) -- 无尽之路 updateData(BillboardDefine.TYPE_LIANYU, data, true) -- 冰龙巢穴 updateData(BillboardDefine.TYPE_DRAGON, data, true) -- ABS活动 AbsActLogic.updateBillBoard(data) end AbsActLogic.updateBillBoardRank() --计算世界等级 GlobalWorld.doCalcWorldLv() end -- 排名值 function getValues(boardType, db) if boardType == BillboardDefine.TYPE_BATTLE then local fininID = db.guajiID return (fininID > 0) and fininID elseif boardType == BillboardDefine.TYPE_TOWER then if db.tower and (db.tower.lv or 0) > 0 then return db.tower.lv, db.tower.usetime end elseif boardType == BillboardDefine.TYPE_ZHANDOULI then local fakeHuman = {db = db} return CombatPosLogic.getCombatHeroZDL(fakeHuman, CombatDefine.COMBAT_TYPE1) elseif boardType == BillboardDefine.TYPE_LV then return db.lv elseif boardType == BillboardDefine.TYPE_UNION then return db.zhandouli, db.lv elseif boardType == BillboardDefine.TYPE_LIANYU then if db.lianyu and db.lianyu.maxLv then return db.lianyu.maxLv end elseif boardType == BillboardDefine.TYPE_DRAGON then if db.dragonCopy and db.dragonCopy.time and db.dragonCopy.dayHurt then if Util.isSameDay(db.dragonCopy.time) and db.dragonCopy.dayHurt > 0 then return db.dragonCopy.dayHurt end end end end -- 比较 function cmpValues(boardType, data1, data2) if data1.value1 ~= data2.value1 then return data1.value1 > data2.value1 end if data1.value2 ~= data2.value2 then if boardType == BillboardDefine.TYPE_TOWER then return data1.value2 < data2.value2 else return data1.value2 > data2.value2 end end if (data1.time or 0) ~=(data2.time or 0) then return(data1.time or 0) <(data2.time or 0) end return true end -- 设置值 local function setValues(boardType, data, db, value1, value2) data.uuid = db._id data.value1 = value1 data.value2 = value2 or 0 data.time = BillboardDB.getTime(boardType, db) end -- local TempData = nil function getCacheData(boardType, db, value1, value2) TempData = TempData or BillboardDB.initRankData() setValues(boardType, TempData, db, value1, value2) return TempData end function updateData(boardType, db, isInit) local board = BillboardDB.getBoard(boardType, isInit) if not board then return end local value1, value2 = getValues(boardType, db) if not value1 then return end local dbrank = board.uuid2rank[db._id] 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 -- 刷新上榜时间 BillboardDB.refreshTime(boardType, db) BillboardAim.onCallback(boardType, db, value1) end local maxRank = #board.rank2data local rank = maxRank + 1 local tempData = getCacheData(boardType, db, value1, value2) for i = maxRank, 1, -1 do local tdata = board.rank2data[i] if cmpValues(boardType, tdata, tempData) then break end board.rank2data[i + 1] = tdata rank = i end if rank > BillboardDefine.MAX_CNT then return end local data = nil if maxRank < BillboardDefine.MAX_CNT then data = BillboardDB.initRankData() else data = board.rank2data[BillboardDefine.MAX_CNT + 1] end setValues(boardType, data, db, value1, value2) board.rank2data[rank] = data board.rank2data[BillboardDefine.MAX_CNT + 1] = nil if rank ~= dbrank then board.dirty = true end return true end