123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954 |
- RankScript = {}
- local rankScriptConst = {
- -- 排行榜刷新时间id
- RANK_REFRESH_TIME = 16,
- -- 排行榜上限人数id
- RANK_LIMIT_MEMBERS = 17,
- -- 排行榜奖励时间id
- RANK_REWARD_TIME = 10002,
- -- 排行榜类型
- RANK_TYPES = {
- levelType = 1,
- BraveTestType = 2,
- FightValueType = 3,
- },
- -- 职业类型
- CAREERS = {
- 0, 1, 2, 3, 4, 5, 6
- },
- -- 发奖励周期时间
- REWARD_PERIOD = 7 * 24 * 60 * 60,
- -- REWARD_PERIOD = 10,
- -- 奖励邮件
- REWARD_MAIL = 110001,
- REWARD_TITLE = "排行榜",
- -- 本地或跨服排行榜
- LOCAL_RANK = 1,
- CROSS_RANK = 2,
- }
- function RankScript.stopRefreshData(actor)
- -- 暂时不做
- end
- -- 请求排行榜数据
- function RankScript.loadRankData(actor, msgData)
- local career = tonumber(msgData["career"])
- local type = tonumber(msgData["type"])
- local rootType = tonumber(msgData["roottype"]) or 1
- if career == nil or type == nil then
- return
- end
- -- 请求数据
- local id = ConfigDataManager.getTableValue("cfg_rank", "id", "roottype", rootType, "career", career, "type", type)
- if id == "" or id == nil then
- return
- end
- local rankRoles = RankScript.getRankDataByPrimaryKey(actor, tonumber(id), rootType)
- -- if rankRoles ~= nil and next(rankRoles) ~= nil then
- -- local sendMsg = RankScript.buidClientNeedRankData(actor, id, rankRoles)
- -- sendluamsg(actor, LuaMessageIdToClient.SEND_RANK_DATA_TO_CLIENT, sendMsg)
- -- else
- -- sendluamsg(actor, LuaMessageIdToClient.SEND_RANK_DATA_TO_CLIENT, {})
- -- end
- local sendMsg = RankScript.buidClientNeedRankData(actor, id, rankRoles)
- sendluamsg(actor, LuaMessageIdToClient.SEND_RANK_DATA_TO_CLIENT, sendMsg)
- end
- -- 构建客户端需要排行榜数据,上榜的和个人的
- function RankScript.buidClientNeedRankData(actor, id, rankDatas)
- local myRankData = RankScript.getMyRankDataByPrimaryKey(actor, id) or {}
- local sendMsg = {
- id = id,
- rankDatas = rankDatas,
- myRankData = myRankData
- }
- return sendMsg
- end
- function RankScript.initAndSendReward()
- local rankRewardTime = ConfigDataManager.getTableValue("cfg_global", "value", "id", rankScriptConst.RANK_REWARD_TIME)
- if rankRewardTime == "" or rankRewardTime == nil then
- return
- end
- -- gameDebug.print("rankRewardTime:", rankRewardTime)
- local weekAndHour = string.splitByAll(rankRewardTime, "#")
- local forWeek = tonumber(weekAndHour[1]) + 1
- local forHour = tonumber(weekAndHour[2])
- local nowTime = getbaseinfo("now")
- local nowYear = year(nowTime)
- local nowMonth = month(nowTime)
- local nowDay = day(nowTime)
- local nowHour = hour(nowTime)
- local nowMinute = minute(nowTime)
- local nowSecond = second(nowTime)
- -- 计算目标星期和时间
- local targetDayOfWeek = forWeek
- local targetTime = { hour = forHour, min = 0, sec = 0 }
- -- 查找目标日期
- local targetDate = { year = nowYear, month = nowMonth, day = nowDay }
- while os.date("*t", os.time(targetDate))["wday"] ~= targetDayOfWeek do
- targetDate.day = targetDate.day + 1
- end
- -- 检查目标时间是否已经过去
- local nowDateTime = {
- year = nowYear,
- month = nowMonth,
- day = nowDay,
- hour = nowHour,
- min = nowMinute,
- sec = nowSecond
- }
- local targetDateTime = {
- year = targetDate.year,
- month = targetDate.month,
- day = targetDate.day,
- hour = targetTime.hour,
- min = targetTime.min,
- sec = targetTime.sec
- }
- if os.time(targetDateTime) < os.time(nowDateTime) then
- targetDate.day = targetDate.day + 7
- end
- -- 计算目标日期和时间
- targetDateTime = {
- year = targetDate.year,
- month = targetDate.month,
- day = targetDate.day,
- hour = targetTime.hour,
- min = targetTime.min,
- sec = targetTime.sec
- }
- local targetDateTimeTime = os.time(targetDateTime)
- -- 计算延迟
- local delay = targetDateTimeTime - os.time(nowDateTime)
- setontimerex(102, rankScriptConst.REWARD_PERIOD, delay)
- end
- function ontimerex102()
- -- 定时发奖励
- local serverType = getbaseinfo("servertype")
- local rankDatas = {}
- if serverType == 2 then
- RankScript.crossUpdate()
- rankDatas = getsysvar("Q$rankCrossData", 1) or {}
- else
- RankScript.updateRankOnTimeOrNight(false)
- rankDatas = getsysvar("Q$rankData") or {}
- end
- if next(rankDatas) ~= nil then
- RankScript.sendReward(rankDatas)
- end
- end
- -- 发奖励
- function RankScript.sendReward(rankDatas)
- for oneId, rankDataList in pairs(rankDatas) do
- local currLine = ConfigDataManager.getTable("cfg_rank", "id", oneId)[1]
- local rewardRule = currLine["rewardrule"]
- local rewardThing = currLine["reward"]
- -- lg('rewardRule', rewardRule)
- -- lg('rewardThing', rewardThing)
- if rewardRule == "" or rewardThing == "" then
- goto nextReward
- end
- local rewardRuleList = string.splitByAll(rewardRule, "#")
- -- lg('rewardRuleList:', rewardRuleList)
- local rewardThingByRankno = string.splitByAll(rewardThing, "|")
- -- lg('rewardThingByRankno:', rewardThingByRankno)
- local rewardThingMap = {}
- for rankno, itemAndCount in ipairs(rewardThingByRankno) do
- if itemAndCount ~= "" and itemAndCount ~= nil then
- local item = string.splitByAll(itemAndCount, "#")[1]
- local count = string.splitByAll(itemAndCount, "#")[2]
- if item and count then
- rewardThingMap[rankno] = { item, count }
- end
- end
- end
- -- lg('rewardThingMap:', rewardThingMap)
- if #rewardRuleList > 0 and #rewardThingMap > 0 then
- -- lg('有奖励可以发放')
- for _, currRole in ipairs(rankDataList) do
- local rankNo = currRole["rankno"]
- if array.contains(rewardRuleList, tostring(rankNo)) then
- -- lg('该角色发放奖励')
- local actor = currRole["actor"]
- local item = rewardThingMap[rankNo][1]
- local count = rewardThingMap[rankNo][2]
- local itemBing = ConfigDataManager.getTableValue("cfg_bind", "bind", "id", 14)
- if item and count then
- sendconfigmailbyrid(actor, actor:toString(),
- rankScriptConst.REWARD_MAIL, { [tonumber(item)] = tonumber(count) },
- rankScriptConst.REWARD_TITLE, itemBing)
- end
- end
- end
- end
- :: nextReward ::
- end
- end
- function RankScript.isNight()
- local nowTime = getbaseinfo("now")
- local nowHour = hour(nowTime)
- local nowMinute = minute(nowTime)
- if nowHour == 0 and nowMinute <= 10 and nowMinute >= 3 then
- return true
- end
- return false
- end
- -- 变量改为Q类型,凌晨清除数据后要将所有数据重刷一遍
- function RankScript.updateAll()
- if RankScript.isNight() then
- local nowTime = getbaseinfo("now")
- local nowHour = hour(nowTime)
- local nowMinute = minute(nowTime)
- info("凌晨刷新排行榜全部数据,当前时间:", "hour:", nowHour, "min:", nowMinute)
- -- 角色信息刷新
- RankScript.updateRoles()
- -- 排行榜数据全刷新
- RankScript.updateRankOnTimeOrNight(false)
- end
- end
- -- 获取所有本地角色数据
- function RankScript.updateRoles()
- local serverType = getbaseinfo("servertype")
- if serverType == 1 then
- local roles = getallrolesummaryinfos()
- local allRoles = {}
- if roles then
- for _, role in ipairs(roles) do
- local actor = role["actor"]
- local buidRole = RankScript.buildOneRole(actor)
- table.insert(allRoles, buidRole)
- end
- info("排行榜刷新全部角色信息成功")
- setsysvar("Q$allRankRoles", allRoles)
- end
- -- 重启立即全部更新
- RankScript.updateRankOnTimeOrNight(false)
- end
- end
- function RankScript.addNewRole(actor)
- local role = RankScript.buildOneRole(actor)
- local allRole = getsysvar(actor, "Q$allRankRoles") or {}
- for i = #allRole, 1, -1 do
- local storeRole = allRole[i]
- local actorInRole = storeRole["actor"]
- if actorInRole:toString() == actor:toString() then
- return
- end
- end
- table.insert(allRole, role)
- setsysvar(actor, "Q$allRankRoles", allRole)
- end
- function RankScript.removeRole(actor)
- local allRole = getsysvar(actor, "Q$allRankRoles") or {}
- for i = #allRole, 1, -1 do
- local role = allRole[i]
- local actorInRole = role["actor"]
- if actorInRole:toString() == actor:toString() then
- table.remove(allRole, i)
- break
- end
- end
- setsysvar(actor, "Q$allRankRoles", allRole)
- end
- -- 更新在线状态
- function RankScript.updateOnline(actor, state)
- local allRole = getsysvar(actor, "Q$allRankRoles") or {}
- for i = #allRole, 1, -1 do
- local role = allRole[i]
- local actorInRole = role["actor"]
- if actorInRole:toString() == actor:toString() then
- role["online"] = state
- role["actor"] = actor
- break
- end
- end
- setsysvar(actor, "Q$allRankRoles", allRole)
- end
- -- 开启更新定时器
- function RankScript.openRankTimer()
- local refreshTime = ConfigDataManager.getTableValue("cfg_global", "value", "id", rankScriptConst.RANK_REFRESH_TIME)
- if refreshTime == "" or refreshTime == nil then
- return
- end
- refreshTime = tonumber(refreshTime)
- if refreshTime <= 0 then
- return
- end
- refreshTime = refreshTime * 60
- setontimerex(101, refreshTime)
- end
- -- 定时刷新排行榜数据
- function ontimerex101()
- if RankScript.isNight() then
- return
- end
- local serverType = getbaseinfo("servertype")
- if serverType == 1 then
- -- 本地
- RankScript.updateRankOnTimeOrNight(true)
- AngelMajorGrail.initGrailRanking()
- end
- if serverType == 2 then
- -- 跨服
- RankScript.crossUpdate()
- -- AngelMajorGrail.initGrailRanking()
- end
- end
- -- 更新排行榜数据,true本地定时刷新,false本地凌晨刷新
- function RankScript.updateRankOnTimeOrNight(isOnTimer)
- local serverType = getbaseinfo("servertype")
- if serverType == 1 then
- -- 本地
- local allRoleInfos = getsysvar("Q$allRankRoles")
- if allRoleInfos ~= nil and next(allRoleInfos) ~= nil then
- RankScript.updateLocalRankData(allRoleInfos, isOnTimer)
- else
- info("刷新排行榜时角色信息为空")
- end
- end
- end
- -- 更新本地排行榜数据
- function RankScript.updateLocalRankData(allRoleInfos, isOnTime)
- local flag = isOnTime and "定时" or "凌晨"
- info("定时或凌晨更新排行榜数据--" .. "角色数量信息:" .. #allRoleInfos .. " 是否定时:" .. flag)
- local rankTables = ConfigDataManager.getList("cfg_rank")
- if rankTables == nil or next(rankTables) == nil then
- return
- end
- local limitCount = ConfigDataManager.getTableValue("cfg_global", "value", "id",
- rankScriptConst.RANK_LIMIT_MEMBERS)
- if tonumber(limitCount) <= 0 or limitCount == "" or limitCount == nil then
- return
- end
- RankScript.giveAllData(allRoleInfos, isOnTime)
- local rolesByCareerCategory = {}
- for _, career in ipairs(rankScriptConst.CAREERS) do
- local currRoles = RankScript.filterRolesByCareer(allRoleInfos, career)
- if currRoles ~= nil and next(currRoles) ~= nil then
- rolesByCareerCategory[career] = currRoles
- end
- end
- local rankDatas = getsysvar("Q$rankData") or {}
- local tempRankData = {}
- if isOnTime then
- -- 定时刷新
- for _, type in pairs(rankScriptConst.RANK_TYPES) do
- RankScript.updateDataOnTimer(rolesByCareerCategory, type, rankDatas,
- limitCount, tempRankData)
- end
- else
- -- 凌晨刷新
- for _, type in pairs(rankScriptConst.RANK_TYPES) do
- RankScript.updateDataOnNight(rolesByCareerCategory, type,
- limitCount, tempRankData)
- end
- end
- -- lg("刷新后排行榜数据", tempRankData)
- setsysvar("Q$rankData", tempRankData)
- end
- function RankScript.giveAllData(allRoleInfos, isOnTime)
- for _, role in ipairs(allRoleInfos) do
- local actor = role["actor"]
- local isOnline = role["online"]
- if (isOnTime and isOnline) or (not isOnTime) then
- -- 等级赋值
- role["level"] = getbaseinfo(actor, "level")
- role["unionname"] = getbaseinfo(actor, "guildname")
- role["rankTime"] = getplaydef(actor, "T$levelRankTime") or getbaseinfo("nowsec")
- -- 试炼赋值
- local braveTestInfo = getplaydef(actor, "T$braveTestInfos") or {}
- role["braveLevel"] = braveTestInfo["currLevel"] or 0
- role["braveTime"] = braveTestInfo["braveTime"] or 0
- -- 战斗赋值
- local myCareer = role["career"]
- local attrValue
- if tonumber(myCareer) == 2 then
- attrValue = getattrinfo(actor, "maxmc")
- else
- attrValue = getattrinfo(actor, "maxdc")
- end
- local armor = getattrinfo(actor, "armor") or 0
- local fightValue = tonumber(attrValue or 0) + tonumber(armor)
- if fightValue == 0 then
- local mapId = getbaseinfo(actor, "unimapid")
- local currActor = getactor(actor, actor:toString(), mapId)
- if tonumber(myCareer) == 2 then
- attrValue = getattrinfo(currActor, "maxmc")
- else
- attrValue = getattrinfo(currActor, "maxdc")
- end
- armor = getattrinfo(currActor, "armor") or 0
- fightValue = tonumber(attrValue or 0) + tonumber(armor)
- end
- role["fightValue"] = fightValue
- end
- end
- end
- -- 根据职业筛选角色
- function RankScript.filterRolesByCareer(allRoleInfos, career)
- local currRoles = {}
- -- 综合榜不做职业筛选
- if tonumber(career) == rankScriptConst.CAREERS[1] then
- -- 综合榜会覆盖其他榜的排名,复制一份新的
- return array.deepCopy(allRoleInfos)
- end
- for _, roleInfo in ipairs(allRoleInfos) do
- if tonumber(roleInfo["career"]) == tonumber(career) then
- table.insert(currRoles, roleInfo)
- end
- end
- return currRoles
- end
- -- 根据类型定时更新排行榜数据
- function RankScript.updateDataOnTimer(rolesByCareerCategory, type, rankDatas,
- limitCount, tempRankData)
- if rolesByCareerCategory == nil or type == nil or type <= 0 then
- return
- end
- for career, rolesInCareerCategory in pairs(rolesByCareerCategory) do
- -- 如果是多个类型,因为是同一份roles引用,后面的type设置value会覆盖前面的,应该重新复制一份
- local roles = array.deepCopy(rolesInCareerCategory)
- local currLineId = ConfigDataManager.getTableValue("cfg_rank", "id", "roottype", rankScriptConst.LOCAL_RANK,
- "career", career, "type", type)
- if currLineId == "" or currLineId == nil then
- return
- end
- local lastHadStoreRoles = rankDatas[currLineId] or {}
- -- 创建一个哈希表来存储上次排名中的角色信息
- local lastRoleMap = {}
- if next(lastHadStoreRoles) ~= nil then
- for _, lastRole in ipairs(lastHadStoreRoles) do
- lastRoleMap[lastRole["actor"]:toString()] = lastRole
- end
- end
- if tonumber(type) == rankScriptConst.RANK_TYPES.levelType then
- for _, role in ipairs(roles) do
- local actor = role["actor"]
- local actorStr = actor:toString()
- local isOnline = role["online"]
- local lastRole = lastRoleMap[actorStr]
- if isOnline then
- if lastRole then
- -- 存在上次排名记录
- local newLevel = role["level"]
- role["value"] = newLevel
- local preLevel = lastRole["value"]
- if preLevel ~= newLevel then
- local now = getbaseinfo("nowsec")
- role["rankTime"] = now
- setplaydef(actor, "T$levelRankTime", now)
- end
- else
- -- 不存在上次排名记录
- local newLevel = role["level"]
- role["value"] = newLevel
- local ranKTime = role["rankTime"]
- setplaydef(actor, "T$levelRankTime", ranKTime)
- end
- else
- -- 离线角色处理
- if lastRole then
- -- lg("不在线存在上次排名记录")
- role["unionname"] = lastRole["unionname"]
- role["value"] = lastRole["value"]
- role["rankTime"] = lastRole["rankTime"]
- else
- -- lg("不在线不存在上次排名记录")
- role["value"] = 0
- end
- end
- end
- RankScript.sortRolesByValueAndOnRankTime(roles)
- elseif tonumber(type) == rankScriptConst.RANK_TYPES.BraveTestType then
- -- 勇气试炼榜
- for _, role in ipairs(roles) do
- local actor = role["actor"]
- local actorStr = actor:toString()
- local isOnline = role["online"]
- local lastRole = lastRoleMap[actorStr]
- if isOnline then
- role["value"] = role["braveLevel"] or 0
- else
- -- 离线角色处理
- if lastRole then
- -- 存在上次排名记录
- role["value"] = lastRole["value"]
- role["braveTime"] = lastRole["braveTime"]
- else
- -- 不存在上次排名记录
- role["value"] = 0
- role["braveTime"] = 0
- end
- end
- end
- -- 试炼榜排序
- RankScript.sortRolesByValueAndBraveTime(roles)
- elseif tonumber(type) == rankScriptConst.RANK_TYPES.FightValueType then
- -- 战斗力榜
- for _, role in ipairs(roles) do
- local actor = role["actor"]
- local actorStr = actor:toString()
- local isOnline = role["online"]
- local lastRole = lastRoleMap[actorStr]
- if isOnline then
- role["value"] = role["fightValue"]
- else
- -- 离线角色处理
- if lastRole then
- -- 存在上次排名记录
- role["unionname"] = lastRole["unionname"]
- role["value"] = lastRole["value"]
- else
- -- 不存在上次排名记录
- role["value"] = 0
- end
- end
- end
- -- 战斗力榜排序
- RankScript.sortRolesByFightValue(roles)
- end
- -- 限制上榜人数
- RankScript.limitAndSetNo(roles, type, limitCount, currLineId, tempRankData)
- end
- end
- -- 凌晨清除数据后要将所有数据重刷一遍
- function RankScript.updateDataOnNight(rolesByCareerCategory, type, limitCount, tempRankData)
- if rolesByCareerCategory == nil or type == nil or type <= 0 then
- return
- end
- for career, rolesInCareerCategory in pairs(rolesByCareerCategory) do
- local roles = array.deepCopy(rolesInCareerCategory)
- local currLineId = ConfigDataManager.getTableValue("cfg_rank", "id", "roottype", rankScriptConst.LOCAL_RANK,
- "career", career,
- "type", type)
- if currLineId == "" or currLineId == nil then
- return
- end
- if tonumber(type) == rankScriptConst.RANK_TYPES.levelType then
- for _, role in pairs(roles) do
- role["value"] = role["level"]
- end
- RankScript.sortRolesByValueAndOnRankTime(roles)
- elseif tonumber(type) == rankScriptConst.RANK_TYPES.BraveTestType then
- for _, role in pairs(roles) do
- role["value"] = role["braveLevel"]
- end
- RankScript.sortRolesByValueAndBraveTime(roles)
- elseif tonumber(type) == rankScriptConst.RANK_TYPES.FightValueType then
- for _, role in pairs(roles) do
- role["value"] = role["fightValue"]
- end
- RankScript.sortRolesByFightValue(roles)
- end
- RankScript.limitAndSetNo(roles, type, limitCount, currLineId, tempRankData)
- end
- end
- -- 跨服刷新
- function RankScript.crossUpdate()
- local serverType = getbaseinfo("servertype")
- if serverType == 2 then
- local result = {}
- local hosts = gethosts()
- local limitCount = ConfigDataManager.getTableValue("cfg_global", "value", "id",
- rankScriptConst.RANK_LIMIT_MEMBERS)
- for _, type in pairs(rankScriptConst.RANK_TYPES) do
- for _, career in pairs(rankScriptConst.CAREERS) do
- local id = ConfigDataManager.getTableValue("cfg_rank", "id", "roottype", rankScriptConst.LOCAL_RANK,
- "type", type, "career", career)
- local crossId = ConfigDataManager.getTableValue("cfg_rank", "id", "roottype", rankScriptConst.CROSS_RANK,
- "type", type, "career", career)
- if not string.isNullOrEmpty(crossId) then
- local mergeRoleData = {}
- for _, host in ipairs(hosts) do
- local rankDatas = getsysvar(host, "Q$rankData") or {}
- local rankData = rankDatas[id] or {}
- RankScript.arrayMerge(mergeRoleData, rankData)
- end
- if tonumber(type) == rankScriptConst.RANK_TYPES.levelType then
- RankScript.sortRolesByValueAndOnRankTime(mergeRoleData)
- elseif tonumber(type) == rankScriptConst.RANK_TYPES.BraveTestType then
- RankScript.sortRolesByValueAndBraveTime(mergeRoleData)
- elseif tonumber(type) == rankScriptConst.RANK_TYPES.FightValueType then
- RankScript.sortRolesByFightValue(mergeRoleData)
- end
- RankScript.limitAndSetNo(mergeRoleData, type, tonumber(limitCount), crossId, result)
- end
- end
- end
- -- lg(result)
- setsysvar("Q$rankCrossData", result, 1)
- for _, host in ipairs(hosts) do
- setsysvar(host, "Q$rankCrossData", result)
- end
- end
- end
- function RankScript.arrayMerge(arr1, arr2)
- for i, v in ipairs(arr2) do
- table.insert(arr1, v)
- end
- end
- -- 限制上榜人数,并设置排名
- function RankScript.limitAndSetNo(roles, type, limitCount, currLineId, tempRankData)
- local tobeStoreRoles = {}
- for i = 1, math.min(#roles, tonumber(limitCount)) do
- local role = roles[i]
- local actor = role["actor"]
- local condition = ConfigDataManager.getTableValue("cfg_rank", "rankcondition", "id", currLineId)
- if tonumber(type) == rankScriptConst.RANK_TYPES.levelType then
- local result = RankScript.checkCondition(actor, condition, type, { level = role["value"] })
- if result then
- table.insert(tobeStoreRoles, roles[i])
- end
- elseif tonumber(type) == rankScriptConst.RANK_TYPES.BraveTestType then
- local result = RankScript.checkCondition(actor, condition, type, { braveLevel = role["value"] })
- if result then
- table.insert(tobeStoreRoles, roles[i])
- end
- elseif tonumber(type) == rankScriptConst.RANK_TYPES.FightValueType then
- local result = RankScript.checkCondition(actor, condition, type, { fightValue = role["value"] })
- if result then
- table.insert(tobeStoreRoles, roles[i])
- end
- end
- end
- RankScript.setRankno(tobeStoreRoles, limitCount)
- tempRankData[currLineId] = tobeStoreRoles
- end
- -- ======================================等级榜排序============================================
- function RankScript.sortRolesByValueAndOnRankTime(roles)
- -- 这里上个排名只有五十个名额,可能发生之前上过榜,但上次没上榜,这里从上次排行榜中找不到自己
- -- 找不到自己,那同样的数值肯定别人比自己先上榜,这里也不影响排序
- table.sort(roles, function(a, b)
- if a["value"] == nil and b["value"] == nil then
- return false
- elseif a["value"] == nil then
- return false
- elseif b["value"] == nil then
- return true
- end
- -- 首先按照value降序排列
- if a["value"] > b["value"] then
- return true
- elseif a["value"] < b["value"] then
- return false
- else
- return RankScript.onRankTimeComparator(a, b)
- end
- end)
- end
- function RankScript.onRankTimeComparator(a, b)
- -- 两个人都上过榜,但两个人上次上榜数值可能不一样,不过走到这里表示现在两个人数值一样,按照上次上榜时间比较
- -- 如果a和b都有rankTime,应该都有上榜时间,则比较rankTime
- if a["rankTime"] and b["rankTime"] then
- if tonumber(a["rankTime"]) == tonumber(b["rankTime"]) then
- -- 比较id
- local reslut = RankScript.sortOnId(a, b)
- return reslut
- else
- return tonumber(a["rankTime"]) < tonumber(b["rankTime"])
- end
- end
- -- 如果只有一个有rankTime,那么有rankTime的排前面
- return a["rankTime"] ~= nil
- end
- function RankScript.sortOnId(a, b)
- local aId = a["actor"]:toString()
- local bId = b["actor"]:toString()
- return aId < bId
- end
- -- ========================================试炼榜排序==========================================
- function RankScript.sortRolesByValueAndBraveTime(roles)
- table.sort(roles, function(a, b)
- if a["value"] > b["value"] then
- return true
- elseif a["value"] < b["value"] then
- return false
- else
- return RankScript.onBraveTimeComparator(a, b)
- end
- end)
- end
- function RankScript.onBraveTimeComparator(a, b)
- if tonumber(a["braveTime"]) == tonumber(b["braveTime"]) then
- local reslut = RankScript.sortOnId(a, b)
- return reslut
- end
- return tonumber(a["braveTime"]) < tonumber(b["braveTime"])
- end
- -- =================战斗力榜排序=================
- function RankScript.sortRolesByFightValue(roles)
- table.sort(roles, function(a, b)
- if a["value"] > b["value"] then
- return true
- elseif a["value"] < b["value"] then
- return false
- else
- return a["actor"]:toString() < b["actor"]:toString()
- end
- end)
- end
- -- =========================给本次排行榜数据设置排名======================================
- function RankScript.setRankno(tobeStoreRoles, limitCount)
- -- 排行榜榜单容量
- local capacity = tonumber(limitCount)
- if capacity == nil then
- capacity = #tobeStoreRoles
- else
- capacity = math.min(capacity, #tobeStoreRoles)
- end
- -- 允许并列排名
- for i, roleInfo in ipairs(tobeStoreRoles) do
- if i == 1 then
- roleInfo["rankno"] = 1
- else
- -- 判断和前一个名次是否并列
- local equal = RankScript.rankNoIsEquals(tobeStoreRoles, i)
- if equal then
- roleInfo["rankno"] = tobeStoreRoles[i - 1]["rankno"]
- else
- roleInfo["rankno"] = i
- end
- end
- end
- end
- function RankScript.rankNoIsEquals(tobeStoreRoles, nowIndex)
- local preRole = tobeStoreRoles[nowIndex - 1]
- local currRole = tobeStoreRoles[nowIndex]
- return tonumber(currRole["value"]) == tonumber(preRole["value"])
- end
- function RankScript.getRankDataByPrimaryKey(actor, id, localOrCross)
- if localOrCross == rankScriptConst.LOCAL_RANK then
- local rankDatas = getsysvar(actor, "Q$rankData") or {}
- -- lg("排行榜数据", rankDatas)
- if next(rankDatas) == nil then
- return {}
- end
- return rankDatas[tostring(id)] or {}
- elseif localOrCross == rankScriptConst.CROSS_RANK then
- local serverType = getbaseinfo("servertype")
- local rankDatas = {}
- if serverType == 1 then
- rankDatas = getsysvar(actor, "Q$rankCrossData") or {}
- -- lg("跨服排行榜数据类型",serverType, rankDatas)
- elseif serverType == 2 then
- rankDatas = getsysvar("Q$rankCrossData", 1) or {}
- -- lg("跨服排行榜数据类型",serverType, rankDatas)
- end
- if next(rankDatas) == nil then
- return {}
- end
- return rankDatas[tostring(id)] or {}
- end
- end
- function RankScript.getMyRankDataByPrimaryKey(actor, id)
- -- 找到自己,但自己的职业可能不符合当前查询条件的职业
- local currTable = ConfigDataManager.getTable("cfg_rank", "id", id)
- if currTable == nil or next(currTable) == nil then
- return nil
- end
- local currCareer = currTable[1]["career"]
- local currType = currTable[1]["type"]
- local roleInfo = RankScript.buildOneRole(actor)
- if tonumber(currType) == rankScriptConst.RANK_TYPES.levelType then
- local level = getbaseinfo(actor, "level") or 1
- roleInfo["actor"] = actor:toString()
- roleInfo["value"] = level
- return roleInfo
- elseif tonumber(currType) == rankScriptConst.RANK_TYPES.BraveTestType then
- local braveTestInfo = getplaydef(actor, "T$braveTestInfos") or {}
- local braveLevel = braveTestInfo["currLevel"] or 0
- roleInfo["actor"] = actor:toString()
- roleInfo["value"] = braveLevel
- roleInfo["braveTime"] = braveTestInfo["braveTime"] or 0
- return roleInfo
- elseif tonumber(currType) == rankScriptConst.RANK_TYPES.FightValueType then
- local myCareer = roleInfo["career"]
- local attrValue
- if tonumber(myCareer) == 2 then
- attrValue = getattrinfo(actor, "maxmc")
- else
- attrValue = getattrinfo(actor, "maxdc")
- end
- local armor = getattrinfo(actor, "armor") or 0
- local fightValue = tonumber(attrValue or 0) + tonumber(armor)
- roleInfo["actor"] = actor:toString()
- roleInfo["value"] = fightValue
- return roleInfo
- end
- -- end
- end
- -- 更新勇者试炼关卡信息
- function RankScript.updateBraveTestInfos(actor, currLevel, braveTimeMillis)
- local braveTestInfo = getplaydef(actor, "T$braveTestInfos")
- if braveTestInfo == nil then
- braveTestInfo = {
- currLevel = tonumber(currLevel),
- braveTime = tonumber(braveTimeMillis)
- }
- else
- braveTestInfo.currLevel = tonumber(currLevel)
- braveTestInfo.braveTime = tonumber(braveTimeMillis)
- end
- setplaydef(actor, "T$braveTestInfos", braveTestInfo)
- end
- -- 根据类型检查条件
- function RankScript.checkCondition(actor, condition, type, param)
- if tonumber(type) == rankScriptConst.RANK_TYPES.levelType then
- local currLevel = param["level"]
- return currLevel >= tonumber(condition)
- elseif tonumber(type) == rankScriptConst.RANK_TYPES.BraveTestType then
- local braveLevel = param["braveLevel"]
- return braveLevel >= tonumber(condition)
- elseif tonumber(type) == rankScriptConst.RANK_TYPES.FightValueType then
- local fightVlue = param["fightValue"]
- return fightVlue >= tonumber(condition)
- end
- return true
- end
- function RankScript.buildOneRole(actor)
- local role = {}
- role["actor"] = actor
- role["career"] = getbaseinfo(actor, "getbasecareer")
- role["name"] = getbaseinfo(actor, "rolename")
- role["value"] = 0
- local serverId = getbaseinfo(actor, "originalserverid")
- role["serverid"] = serverId
- role["online"] = false
- return role
- end
- function RankScript.mergeAndUpdate()
- local roles = getallrolesummaryinfos()
- local allRoles = {}
- if roles then
- for _, role in ipairs(roles) do
- local actor = role["actor"]
- local buidRole = RankScript.buildOneRole(actor)
- table.insert(allRoles, buidRole)
- end
- info("合服后排行榜刷新全部角色信息成功, 角色数量:", #allRoles)
- setsysvar("Q$allRankRoles", allRoles)
- end
- RankScript.updateRankOnTimeOrNight(false)
- end
- -- ====================测试========================
- function updaterank(actor)
- -- lg("定时刷新排行榜数据")
- local curr1 = getbaseinfo("now")
- RankScript.updateRankOnTimeOrNight(true)
- local curr2 = getbaseinfo("now")
- local time = curr2 - curr1
- lg("耗时:", time)
- end
- function testnight()
- local curr1 = getbaseinfo("now")
- RankScript.updateRankOnTimeOrNight(false)
- local curr2 = getbaseinfo("now")
- local time = curr2 - curr1
- lg("耗时:", time)
- end
- function updaterole()
- RankScript.updateRoles()
- end
- function updaterole_data()
- local curr1 = getbaseinfo("now")
- gameDebug.debug(RankScript.updateAll)
- local curr2 = getbaseinfo("now")
- local time = curr2 - curr1
- lg("耗时:", time)
- end
- function crossupdate()
- local t1 = getbaseinfo("now")
- RankScript.crossUpdate()
- local t2 = getbaseinfo("now")
- local time = t2 - t1
- lg("耗时:", time)
- end
- function rankreward(actor)
- local serverType = getbaseinfo("servertype")
- local rankDatas = {}
- if serverType == 2 then
- RankScript.crossUpdate()
- rankDatas = getsysvar("Q$rankCrossData", 1) or {}
- else
- RankScript.updateRankOnTimeOrNight(false)
- rankDatas = getsysvar("Q$rankData") or {}
- end
- if next(rankDatas) ~= nil then
- RankScript.sendReward(rankDatas)
- end
- end
- function clearrank(actor)
- local serverType = getbaseinfo("servertype")
- if serverType == rankScriptConst.LOCAL_RANK then
- setsysvar(actor, "Q$rankData", {})
- elseif serverType == rankScriptConst.CROSS_RANK then
- setsysvar("Q$rankCrossData", {}, 1)
- end
- end
|