| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742 |
- -- 异界之战(DB)
- local LuaMongo = _G.lua_mongo
- local DB = require("common.DB")
- local AnotherWorldBattleDefine = require("anotherWorldBattle.AnotherWorldBattleDefine")
- local AnotherWorldBattleConfig = require("excel.anotherWorldBattle")
- local dbUpdate = {_id=nil}
- local dbUpdateField = {}
- -- db
- AnotherWorldBattleData = {
- -- lastRoundStartTime = 0, -- 上一轮活动开启时间。实际为当前轮活动开始时间, 已有正式数据, 变量名不改了.
- -- stage = 1, -- 当前阶段
- -- joinUnionArr = {
- -- { unionId = "", serverId = 123, power = 9999},
- -- },
- -- groupArray = {
- -- [1] = {unionId1, unionId2, unionId3, unionId4, unionId5, unionId6, unionId7, unionId8},
- -- [2] = {unionId9, unionId10,...},
- -- },
- -- unionList = {
- -- [unionId1] = {
- -- serverId = 123, -- 公会所在服务器Id
- -- power = 9999,
- -- name = "111",
- -- baseCityId = 123, -- 出生城池
- -- baseCityStartTime = nil, -- 出生城的开始占领时间
- -- occupCityList = { -- 城池列表(包括曾占领过, 当前成功占领, 当前只占领过一个或多个据点)
- -- [cityId1] = {
- -- isOccupy = false, --当前是否占领
- -- occupyPointList = { --占领本城池中的据点列表
- -- [pointId1] = { playerUuid = "", occupyTimeArr = { {startTime1, endTime1}, {startTime2, endTime2}}, },
- -- },
- -- },
- -- },
- -- gatherInfo = { --集结信息
- -- gatherTime = 0,
- -- gatherCity = 123,
- -- },
- -- },
- -- },
- -- playerList = {
- -- [playerUuid] = {
- -- name = "",
- -- lv = 200,
- -- head = 1234,
- -- headFrame = 1234,
- -- power = 999,
- -- challengeTimes = 10,
- -- lastTime = nil, -- 上一次更新的时间戳
- -- unionId = "",
- -- heroList = {
- -- [cityId] = {
- -- [pointIdx] = {
- -- {
- -- heroUuid = "sdgjdjdj",
- -- heroStar = 111,
- -- heroLevel = 111,
- -- heroCamp = 1,
- -- heroBody = 111,
- -- heroIcon = 111,
- -- heroPower = 11111,
- -- heroId = 111,
- -- heroQuality = 1,
- -- },
- -- },
- -- },
- -- }
- -- },
- -- }
- }
- -- 所有分组的城池信息, 启动服务器后生成, 用于快速获取城池信息
- Group_2_CityList = {
- -- [groupId] = {
- -- [cityId] = {
- -- occupyUnion = { -- 占领公会信息, 没有公会占领时为nil
- -- serverId = 124,
- -- unionId = "123",
- -- },
- -- pointArr = { -- 城池中所有据点信息, 没人占领时, unionId, playerUuid为nil
- -- {unionId = nil, playerUuid = nil, },
- -- {unionId = nil, playerUuid = nil, },
- -- }
- -- },
- -- },
- }
- -- 所有分组的公会排行榜, 启动服务器后生成
- Group_2_UnionRankList = {}
- -- 所有分组的玩家排行榜, 启动服务器后生成
- Group_2_PlayerRankList = {}
- -- 区服Id - 公会列表 映射表
- Server_2_UnionArr = {
- -- [serverId] = {unionId1, unionId2},
- }
- -- 公会 - 所属分组 映射表
- Union_2_Group = {
- -- [unionId] = groupId,
- }
- local function initData()
- AnotherWorldBattleData.lastRoundStartTime = 0
- AnotherWorldBattleData.stage = AnotherWorldBattleDefine.AB_STATE_END
- LuaMongo.insert(DB.db_anotherWorldBattle, AnotherWorldBattleData)
- end
- local function loadData()
- LuaMongo.find(DB.db_anotherWorldBattle)
- local data = {}
- if LuaMongo.next(data) then
- AnotherWorldBattleData = data
- else
- initData()
- end
- end
- -- 修改db单个字段
- local function updateValue(key, value)
- if not key then return end
- if value then
- dbUpdateField["$set"] = {[key]=value}
- dbUpdateField["$unset"] = nil
- else
- dbUpdateField["$set"] = nil
- dbUpdateField["$unset"] = {[key]=1}
- end
- dbUpdate._id = AnotherWorldBattleData._id
- LuaMongo.update(DB.db_anotherWorldBattle, dbUpdate, dbUpdateField)
- end
- -- 生成城池数据
- local function genCityList(net, unionIdArr)
- local function getUnionByCityId(targetCityId)
- for _, unionId in ipairs(unionIdArr) do
- local unionInfo = AnotherWorldBattleData.unionList[unionId]
- -- 其他城池
- if unionInfo and unionInfo.occupCityList then
- for occupyCityId, occupyCityinfo in pairs(unionInfo.occupCityList) do
- if occupyCityId == targetCityId and occupyCityinfo.isOccupy then
- return unionId
- end
- end
- end
- -- 出生城池
- if unionInfo and unionInfo.baseCityId == targetCityId then
- return unionId
- end
- end
- return nil
- end
- local function getPointOccupyPlayer(targetCityId, targetPointIdx)
- for _, unionId in ipairs(unionIdArr) do
- local unionInfo = AnotherWorldBattleData.unionList[unionId]
- if unionInfo and unionInfo.occupCityList and unionInfo.occupCityList[targetCityId] then
- local pointList = unionInfo.occupCityList[targetCityId].occupyPointList
- if pointList and pointList[targetPointIdx] and pointList[targetPointIdx].playerUuid then
- return unionId, pointList[targetPointIdx].playerUuid
- end
- end
- end
- return nil, nil
- end
- for cityId, cityCfg in ipairs(AnotherWorldBattleConfig.city) do
- local cityEntry = { pointArr = {} }
- net[cityId] = cityEntry
- local unionId = getUnionByCityId(cityId)
- if unionId then
- cityEntry.occupyUnion = unionId
- end
- local pointArr = cityEntry.pointArr
- for i=1, AnotherWorldBattleDefine.AB_POINT_MAX_NUM do
- local unionId1, playerUuid = getPointOccupyPlayer(cityId, i)
- if unionId1 and playerUuid then
- pointArr[i] = {
- unionId = unionId1,
- playerUuid = playerUuid
- }
- else
- pointArr[i] = {}
- end
- end
- end
- end
- -- 工会排行榜
- -- 目前最多8条
- local function createGuildRank()
- local guilds = {} -- id -> guildRec(永久表,不删)
- local rank = {} -- 1..#guilds 复用数组
- local dirty = true -- 脏标记:true表示rank需要重新计算
- local function cmp(a, b)
- if a.occupyCityNum ~= b.occupyCityNum then
- return a.occupyCityNum > b.occupyCityNum
- end
- if a.occupyPointNum ~= b.occupyPointNum then
- return a.occupyPointNum > b.occupyPointNum
- end
- return a.power > b.power
- end
- local function updateGuild(id, name, occupyCityNum, occupyPointNum, power)
- local g = guilds[id]
- if not g then
- g = { id = id, name = name or "",
- occupyCityNum = occupyCityNum or 0,
- occupyPointNum = occupyPointNum or 0,
- power = power or 0 }
- guilds[id] = g
- else
- -- 原地更新,保持table引用
- g.occupyCityNum = occupyCityNum or g.occupyCityNum
- g.occupyPointNum = occupyPointNum or g.occupyPointNum
- g.power = power or g.power
- if name then g.name = name end
- end
- -- 标记rank缓存失效(数据量小,但统一设计模式)
- dirty = true
- end
- -- 内部函数:按需重新排序
- local function sortIfNeeded()
- if not dirty then return end
- -- 全量收集到rank(复用数组)
- local n = 0
- for _, v in pairs(guilds) do
- n = n + 1
- rank[n] = v
- end
- -- 排序
- if n > 1 then
- table.sort(rank, cmp)
- end
- -- 清除尾部残留数据
- local rankMax = AnotherWorldBattleDefine.AB_RANK_MAX_NUM
- for i = rankMax + 1, #rank do
- rank[i] = nil
- end
- dirty = false
- end
- local function getRankList()
- -- 确保排行已更新
- sortIfNeeded()
- -- 构建返回列表
- local ret = {}
- for i = 1, #rank do
- local g = rank[i]
- ret[i] = {
- rank = i, guildId = g.id, name = g.name,
- occupyCityNum = g.occupyCityNum,
- occupyPointNum = g.occupyPointNum,
- power = g.power
- }
- end
- return ret
- end
- local function getGuildDetail(id)
- return guilds[id]
- end
- return {
- updateGuild = updateGuild,
- getRankList = getRankList,
- getGuildDetail = getGuildDetail
- }
- end
- -- 玩家排行榜
- -- 当前每个公会最多25人,8个公会为一组,最多200人
- local function createPlayerRank()
- local players = {} -- id -> rec(永久存在,不删)
- local rank = {} -- 已排序的前RANK_MAX名,复用
- local tmp = {} -- 临时排序数组,预分配
- local dirty = true -- 脏标记:true表示rank需要重新计算
- local function cmp(a, b)
- if a.pointNum ~= b.pointNum then return a.pointNum > b.pointNum end
- if a.pointAllWeight ~= b.pointAllWeight then return a.pointAllWeight > b.pointAllWeight end
- return a.power > b.power
- end
- -- 预分配tmp容量,避免运行时动态扩容
- for i = 1, 500 do tmp[i] = nil end
- local function updatePlayer(id, name, power, pNum, pWeight)
- -- 更新或创建玩家记录
- local rec = players[id]
- if not rec then
- rec = { id = id, name = name or "", power = power or 0,
- pointNum = pNum or 0, pointAllWeight = pWeight or 0 }
- players[id] = rec
- else
- -- 原地更新,保持table引用不变
- rec.power = power
- if pNum ~= nil then rec.pointNum = pNum end
- if pWeight ~= nil then rec.pointAllWeight = pWeight end
- if name then rec.name = name end
- end
- -- 标记rank缓存失效
- dirty = true
- end
- -- 内部函数:按需重新排序
- local function sortIfNeeded()
- if not dirty then return end
- -- 收集所有玩家记录到tmp(仅复制引用)
- local n = 0
- for _, v in pairs(players) do
- n = n + 1
- tmp[n] = v
- end
- -- 排序
- if n > 1 then
- table.sort(tmp, cmp)
- end
- -- 将前RANK_MAX名复制到rank(复用数组)
- local rankMax = AnotherWorldBattleDefine.AB_RANK_MAX_NUM
- local oldRankLen = #rank
- for i = 1, rankMax do
- rank[i] = tmp[i] -- 若i>n,则赋值为nil,自动缩小rank长度
- end
- -- 清除rank数组尾部残留的旧数据
- for i = rankMax + 1, oldRankLen do
- rank[i] = nil
- end
- dirty = false
- end
- local function getRankList()
- -- 确保排行已更新
- sortIfNeeded()
- -- 构建返回列表
- local ret = {}
- for i = 1, #rank do
- local p = rank[i]
- ret[i] = { rank = i, playerId = p.id, name = p.name, power = p.power,
- pointNum = p.pointNum, pointAllWeight = p.pointAllWeight }
- end
- return ret
- end
- local function getPlayerDetail(id)
- return players[id]
- end
- return {
- updatePlayer = updatePlayer,
- getRankList = getRankList,
- getPlayerDetail = getPlayerDetail,
- }
- end
- -- 生成公会排行榜
- local function genGroupUnionRankList(unionRank, unionIdArr)
- local function getUnionRankVal(union)
- local occupyCityNum, occupyPointNum, power = 0, 0, 0
- power = union.power or 0
- for _, v in pairs(union.occupCityList or {}) do
- if v.isOccupy then
- occupyCityNum = occupyCityNum + 1
- end
- for _, _ in pairs(v.occupyPointList or {}) do
- occupyPointNum = occupyPointNum + 1
- end
- end
- return occupyCityNum, occupyPointNum, power
- end
- for _, unionId in ipairs(unionIdArr) do
- local unionData = AnotherWorldBattleData.unionList[unionId]
- if unionData then
- local occupyCityNum, occupyPointNum, power = getUnionRankVal(unionData)
- unionRank.updateGuild(unionId, unionData.name, occupyCityNum, occupyPointNum, power)
- end
- end
- end
- -- 生成个人排行榜
- local function genGroupPlayerRankList(playerRank, unionIdArr, playerListData)
- local function insertPlayerRank(unionId)
- if not playerListData then
- return
- end
- for playerUuid, playerInfo in pairs(playerListData) do
- if playerInfo.unionId == unionId then
- local pointNum, pointAllWeight = 0, 0
- for cityId, pointList in pairs(playerInfo.heroList or {}) do
- for _, _ in pairs(pointList) do
- pointNum = pointNum + 1
- local cityCfg = AnotherWorldBattleConfig.city[cityId]
- pointAllWeight = pointAllWeight + (cityCfg and cityCfg.pointWeight or 0)
- end
- end
- playerRank.updatePlayer(playerUuid, playerInfo.name, playerInfo.power, pointNum, pointAllWeight)
- end
- end
- end
- for _, unionId in ipairs(unionIdArr) do
- insertPlayerRank(unionId)
- end
- end
- -- 生成 "公会-公会所属分组Id" 映射表
- local function genUnion2GroupList(groupId, unionIdArr)
- for _, unionId in ipairs(unionIdArr) do
- Union_2_Group[unionId] = groupId
- end
- end
- -- 生成 "serverId - 公会Array" 映射表
- local function genServer2UnionArr(unionRank)
- local rankList = unionRank.getRankList()
- for _, rankInfo in ipairs(rankList) do
- local unionId = rankInfo.guildId
- local unionInfo = AnotherWorldBattleData.unionList[unionId]
- if unionInfo then
- local serverId = unionInfo.serverId
- Server_2_UnionArr[serverId] = Server_2_UnionArr[serverId] or {}
- Server_2_UnionArr[serverId][#Server_2_UnionArr[serverId]+1] = unionId
- end
- end
- end
- -- 生成各组的缓存数据
- local function genGroupCache()
- if not AnotherWorldBattleData.groupArray then
- return
- end
- local playerListData = AnotherWorldBattleData.playerList
- for groupId, unionIdArr in ipairs(AnotherWorldBattleData.groupArray) do
- -- 城池
- Group_2_CityList[groupId] = {}
- genCityList(Group_2_CityList[groupId], unionIdArr)
- -- 公会排行榜
- Group_2_UnionRankList[groupId] = createGuildRank()
- genGroupUnionRankList(Group_2_UnionRankList[groupId], unionIdArr)
- -- "serverId -- unionIdArray" 映射表
- genServer2UnionArr(Group_2_UnionRankList[groupId])
- -- 个人排行榜
- Group_2_PlayerRankList[groupId] = createPlayerRank()
- genGroupPlayerRankList(Group_2_PlayerRankList[groupId], unionIdArr, playerListData)
- -- "公会-公会所属分组" 映射表
- genUnion2GroupList(groupId, unionIdArr)
- end
- end
- function initAfterStart()
- if _G.is_middle ~= true then return end
- loadData()
- genGroupCache()
- end
- -- 重置数据
- function ResetData()
- Group_2_CityList = {}
- Group_2_UnionRankList = {}
- Group_2_PlayerRankList = {}
- Union_2_Group = {}
- Server_2_UnionArr = {}
- AnotherWorldBattleData.lastRoundStartTime = os.time()
- -- AnotherWorldBattleData.stage = AnotherWorldBattleDefine.AB_STATE_JOIN
- AnotherWorldBattleData.joinUnionArr = nil
- AnotherWorldBattleData.groupArray = nil
- AnotherWorldBattleData.unionList = nil
- AnotherWorldBattleData.playerList = nil
- dbUpdate._id = AnotherWorldBattleData._id
- LuaMongo.update(DB.db_anotherWorldBattle, dbUpdate, AnotherWorldBattleData)
- end
- -- 获取公会所在分组的Id
- function GetUnionGroupId(unionId)
- return Union_2_Group[unionId]
- end
- -- 当自己公会没有参赛时, 获取本服第一个公会所在分组Id
- function GetGroupIdByServerId(serverId)
- local unionArr = Server_2_UnionArr[serverId]
- if unionArr and unionArr[1] then
- local unionId = unionArr[1]
- return GetUnionGroupId(unionId)
- end
- end
- -- 获取活动当前阶段
- function GetStage()
- return AnotherWorldBattleData.stage
- end
- -- 更新活动当前阶段
- function UpdateStage(newStage)
- AnotherWorldBattleData.stage = newStage
- updateValue("stage", newStage)
- if newStage == AnotherWorldBattleDefine.AB_STATE_BATTLE then
- genGroupCache()
- end
- end
- -- 获取活动上一轮的开始时间
- function GetLastRoundStartTime()
- return AnotherWorldBattleData.lastRoundStartTime
- end
- function UpdateLastRoundStartTime(newTime)
- AnotherWorldBattleData.lastRoundStartTime = newTime
- updateValue("lastRoundStartTime", newTime)
- end
- -- 获取参赛公会列表
- function GetJoinUnionArr()
- return AnotherWorldBattleData.joinUnionArr
- end
- -- 更新参赛公会列表
- function UpdateJoinUnionArr(newJoinUnionArr)
- AnotherWorldBattleData.joinUnionArr = newJoinUnionArr
- updateValue("joinUnionArr", newJoinUnionArr)
- end
- -- 获取分组列表
- function GetGroupArray()
- return AnotherWorldBattleData.groupArray
- end
- -- 更新分组列表
- function UpdateGroupArray(newGroupArray)
- AnotherWorldBattleData.groupArray = newGroupArray
- updateValue("groupArray", newGroupArray)
- end
- -- 获取公会名字
- function GetUnionName(unionId)
- return AnotherWorldBattleData.unionList and AnotherWorldBattleData.unionList[unionId].name or ""
- end
- -- 获取某个公会数据
- function GetUnionData(unionId)
- return AnotherWorldBattleData.unionList and AnotherWorldBattleData.unionList[unionId]
- end
- -- 更新某个公会数据
- function UpdateUnionData(unionId, newUnionData)
- if not AnotherWorldBattleData.unionList then
- AnotherWorldBattleData.unionList = {}
- -- updateValue("unionList", AnotherWorldBattleData.unionList)
- end
- AnotherWorldBattleData.unionList[unionId] = newUnionData
- updateValue("unionList"..".".. unionId, newUnionData)
- end
- -- 获取公会列表
- function GetUnionList()
- return AnotherWorldBattleData.unionList
- end
- -- 获取玩家名字
- function GetPlayerName(playerUuid)
- local playerListData = AnotherWorldBattleData.playerList
- if playerListData and playerListData[playerUuid] then
- return playerListData[playerUuid].name or ""
- end
- return ""
- end
- -- 获取玩家数据
- function GetPlayerData(playerUuid)
- return AnotherWorldBattleData.playerList and AnotherWorldBattleData.playerList[playerUuid]
- end
- -- 更新玩家数据
- function UpdatePlayerData(playerUuid, newPlayerData)
- if not AnotherWorldBattleData.playerList then
- AnotherWorldBattleData.playerList = {}
- -- updateValue("playerList", AnotherWorldBattleData.playerList)
- end
- AnotherWorldBattleData.playerList[playerUuid] = newPlayerData
- updateValue("playerList".. "." .. playerUuid, newPlayerData)
- end
- -- 获取公会列表
- function GetPlayerList()
- return AnotherWorldBattleData.playerList
- end
- -- 获取城池数据
- function GetCityData(groupId, cityId)
- if Group_2_CityList[groupId] then
- return Group_2_CityList[groupId][cityId]
- end
- end
- -- 更新城池数据
- function UpdateCityData(groupId, cityId, newCityData)
- if Group_2_CityList[groupId] then
- Group_2_CityList[groupId][cityId] = newCityData
- end
- end
- -- 获取所有城池数据
- function GetCityListByGroupId(groupId)
- return Group_2_CityList[groupId]
- end
- -- 更新所有城池数据
- function UpdateCityList(groupId, newCityList)
- Group_2_CityList[groupId] = newCityList
- end
- -- 获取公会排行数据
- function GetUnionRankList(groupId)
- local unionRank = Group_2_UnionRankList[groupId]
- if unionRank then
- return unionRank.getRankList()
- end
- end
- -- 更新公会的排行榜数据, cityVal, pointVal为变化的值
- function UpdateUnionRankList(groupId, unionId, cityVal, pointVal, newPower)
- local unionRank = Group_2_UnionRankList[groupId]
- if unionRank then
- local unionRankInfo = unionRank.getGuildDetail(unionId)
- unionRankInfo.occupyCityNum = unionRankInfo.occupyCityNum + cityVal
- unionRankInfo.occupyPointNum = unionRankInfo.occupyPointNum + pointVal
- if newPower then
- unionRankInfo.power = newPower
- end
- unionRank.updateGuild(unionId, unionRankInfo.name, unionRankInfo.occupyCityNum, unionRankInfo.occupyPointNum, unionRankInfo.power)
- end
- end
- -- 生成玩家用于排名的数据
- local function genPlayerRankVal(playerUuid)
- local playerListData = AnotherWorldBattleData.playerList
- local name, power, pointNum, pointAllWeight = "", 0, 0, 0
- if playerListData and playerListData[playerUuid] then
- power = playerListData[playerUuid].power or 0
- name = playerListData[playerUuid].name or ""
- for cityId, pointList in pairs(playerListData[playerUuid].heroList or {}) do
- for _, _ in pairs(pointList) do
- pointNum = pointNum + 1
- local cityCfg = AnotherWorldBattleConfig.city[cityId]
- pointAllWeight = pointAllWeight + (cityCfg and cityCfg.pointWeight or 0)
- end
- end
- end
- return name, power, pointNum, pointAllWeight
- end
- -- 获取玩家排行数据
- function GetPlayerRankList(groupId)
- local playerRank = Group_2_PlayerRankList[groupId]
- if playerRank then
- return playerRank.getRankList()
- end
- end
- -- 更新玩家排行数据, pointVal, pointWeightVal为变化的值
- function UpdatePlayerRankList(groupId, playerUuid, pointVal, pointWeightVal, newPower)
- local playerRank = Group_2_PlayerRankList[groupId]
- if playerRank then
- local playerRankData = playerRank.getPlayerDetail(playerUuid)
- if not playerRankData then
- playerRankData = {}
- local name, power, pointNum, pointAllWeight = genPlayerRankVal(playerUuid)
- playerRankData.name = name
- playerRankData.power = power
- playerRankData.pointNum = pointNum
- playerRankData.pointAllWeight = pointAllWeight
- else
- playerRankData.pointNum = playerRankData.pointNum + pointVal
- playerRankData.pointAllWeight = playerRankData.pointAllWeight + pointWeightVal
- if newPower then
- playerRankData.power = newPower
- end
- end
- playerRank.updatePlayer(playerUuid, playerRankData.name, playerRankData.power, playerRankData.pointNum, playerRankData.pointAllWeight)
- end
- end
|