-- 跨服商业活动-巅峰战场(跨服) local Msg = require("core.Msg") local Timer = require("core.Timer") local DB = require("common.DB") local CommonDB = require("common.CommonDB") local CommonDefine = require("common.CommonDefine") local Log = require("common.Log") local LuaMongo = _G.lua_mongo local Util = require("common.Util") local Grid = require("bag.Grid") local MiddleConnect = require("middle.MiddleConnect") local InnerMsg = require("core.InnerMsg") local MiddleManager = require("middle.MiddleManager") local NpcConfig = require("excel.jjc").skyladdernpc local CreateRole = require("role.CreateRole") local ServerCommerceActDefine = require("serverCommerce.ServerCommerceActDefine") local CombatDefine = require("combat.CombatDefine") local dbUpdate = {_id=nil} local dbUpdateField = {} local RANK_SHOW_NUM = 50 -- 排行榜显示的数量 local notifyActEnd = false -- 是否收到活动结束通知的标识 local battleGroundData = { -- allAreaRankList = { -- 各个战区排行榜, 榜上的都是真实玩家 -- [WarZoneServerIdx] = { -- [rank] = { -- rank = rank, -- serverId = serverId, -- playerUuid = playerUuid, -- name = name, -- bodyId = bodyId, -- headId = headId, -- headFrameId = headFrameId, -- heroArr = {heroId1, heroId2}, -- }, -- }, -- }, -- generaRankList = { -- 通用排行榜(榜上都是机器人),各个战区排行榜上没有真实玩家或对应排名没有真实玩家时, 使用该排行榜 -- [rank] = { -- rank = rank, -- serverId = serverId, -- playerUuid = playerUuid, -- name = name, -- bodyId = bodyId, -- headId = headId, -- headFrameId = headFrameId, -- monsterOutID = monsterOutID, -- 机器人才有 -- heroArr = {heroId1, heroId2}, -- }, -- }, -- }, -- joinList = { -- 参加过该活动的玩家列表 -- -- {serverId, playerUuid}, -- -- {serverId2, playerUuid2}, -- }, } local function cmp(a, b) return a.rank < b.rank end -- 生成一个排行榜列表 local function genRankList(rankList) local function genPlayerData(player, tNpcConfig, rank) local r = math.random(1, #tNpcConfig.monsterOutID) player.rank = rank player.name = CreateRole.getRandomName() player.headId = CreateRole.getRandomHead() player.headFrameId = CreateRole.getRandomHeadFrame() player.bodyId = CreateRole.getRandomBody() player.playerUuid = tNpcConfig.monsterOutID[r] player.monsterOutID = tNpcConfig.monsterOutID[r] end local rank = 1 for _, cfg in ipairs(NpcConfig) do for i = 1, cfg.cnt do rankList[rank] = {} genPlayerData(rankList[rank], cfg, rank) rank = rank + 1 if rank > ServerCommerceActDefine.COMMERCEACT_NPC_CNT then break end end end end -- 插入数据 local function insertData(data) LuaMongo.insert(DB.db_battleground, data) 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 = battleGroundData._id LuaMongo.update(DB.db_battleground, dbUpdate, dbUpdateField) end -- 保存所有数据 local function saveAllData() dbUpdate._id = battleGroundData._id LuaMongo.update(DB.db_battleground, dbUpdate, battleGroundData) end local function loadData() LuaMongo.find(DB.db_battleground) local data = {} if LuaMongo.next(data) then battleGroundData = data end if battleGroundData.allAreaRankList and next(battleGroundData.allAreaRankList) then for areaIdx, rankList in pairs(battleGroundData.allAreaRankList) do table.sort(rankList, cmp) end end if not battleGroundData.generaRankList then battleGroundData.generaRankList = {} genRankList(battleGroundData.generaRankList) insertData(battleGroundData) end table.sort(battleGroundData.generaRankList, cmp) end function BattleGround_InitAfterStart() if _G.is_middle ~= true then return end loadData() end -- 通过本服Id获取所在战区Id local function getWarZoneServerIdx(sourceServerId) local nServerKey = MiddleConnect.MiddleConnect_TrueServerID2ConfServerID(sourceServerId) nServerKey = MiddleConnect.MiddleConnect_GetWarZoneServer(nServerKey) return nServerKey end -- 生成一个战区排行榜 local function genWarZoneRankList(warZoneServerIdx) local isInsert = false if not next(battleGroundData) then isInsert = true end battleGroundData.allAreaRankList = battleGroundData.allAreaRankList or {} battleGroundData.allAreaRankList[warZoneServerIdx] = {} genRankList(battleGroundData.allAreaRankList[warZoneServerIdx]) if isInsert then return insertData(battleGroundData) end updateValue("allAreaRankList".."."..warZoneServerIdx, battleGroundData.allAreaRankList[warZoneServerIdx]) end -- 获取本服所在战区的排行榜 local function getMyWarZoneRankList(sourceServerId) local warZoneServerIdx = getWarZoneServerIdx(sourceServerId) if not battleGroundData.allAreaRankList or not battleGroundData.allAreaRankList[warZoneServerIdx] then -- genWarZoneRankList(warZoneServerIdx) return end return battleGroundData.allAreaRankList[warZoneServerIdx] end -- 初始化本战区的排行榜 local function initMyWarZoneRankList(sourceServerId) local warZoneServerIdx = getWarZoneServerIdx(sourceServerId) if not battleGroundData.allAreaRankList or not battleGroundData.allAreaRankList[warZoneServerIdx] then battleGroundData.allAreaRankList = battleGroundData.allAreaRankList or {} battleGroundData.allAreaRankList[warZoneServerIdx] = {} end end -- 获取通用排行榜 local function getGeneraRankList() return battleGroundData.generaRankList end -- 通过玩家uuid获取排名 local function getPlayerRankByUuid(rankList, targetPlayerUuid) local targetRank = ServerCommerceActDefine.COMMERCEACT_NPC_CNT + 1 if not rankList then return targetRank end for rank, rankInfo in ipairs(rankList) do if rankInfo.playerUuid == targetPlayerUuid then targetRank = rank break end end return targetRank end -- 遍历 local function findVal(list, val) for k, info in pairs(list or {}) do if info[2] == val then return k end end end -- 发奖 local function issueReward(fd, rankArr) local msgData = InnerMsg.wl.WL_BATTLEGROUND_NOTIFY_PLAYER msgData.playerArr = rankArr InnerMsg.sendMsg(fd, msgData) end -- 普通服请求玩家排名 function BG_N2C_PlayerRank_Req(msg) local msgData = InnerMsg.wl.WL_BATTLEGROUND_PLAYER_RANK_QUERY msgData.playerRank = 0 msgData.playerUuid = msg.playerUuid local myWarZoneRankList = getMyWarZoneRankList(msg.sourceServerId) msgData.playerRank = getPlayerRankByUuid(myWarZoneRankList, msg.playerUuid) local fd = MiddleManager.getFDBySvrIndex(msg.sourceServerId) InnerMsg.sendMsg(fd, msgData) end -- 普通服请求对手数据 function BG_N2C_MatchList_Req(msg) local msgData = InnerMsg.wl.WL_BATTLEGROUND_MATCHLIST_QUERY msgData.playerUuid = msg.playerUuid msgData.playerInfoList = {} local myWarZoneRankList = getMyWarZoneRankList(msg.sourceServerId) local generaRankList = getGeneraRankList() for _, rank in ipairs(msg.matchList) do local rankInfo = myWarZoneRankList and myWarZoneRankList[rank] or generaRankList[rank] if rankInfo then msgData.playerInfoList[#msgData.playerInfoList+1] = { rank = rank, serverId = rankInfo.serverId, name = rankInfo.name, showBodyId = rankInfo.bodyId } end end local fd = MiddleManager.getFDBySvrIndex(msg.sourceServerId) InnerMsg.sendMsg(fd, msgData) end -- 普通服请求玩家数据 function BG_N2C_PlayerData_Req(msg) local msgData = InnerMsg.wl.WL_BATTLEGROUND_PLAYER_DATA_QUERY msgData.playerUuid = msg.playerUuid msgData.playerInfo = {} local myWarZoneRankList = getMyWarZoneRankList(msg.sourceServerId) local generaRankList = getGeneraRankList() local rankInfo = myWarZoneRankList and myWarZoneRankList[rank] or generaRankList[rank] if rankInfo then msgData.playerInfo.serverId = rankInfo.serverId msgData.playerInfo.name = rankInfo.name msgData.playerInfo.heroHeadId = rankInfo.headId msgData.playerInfo.heroHeadFrameId = rankInfo.headFrameId msgData.playerInfo.monsteroutId = 0 if rankInfo.serverId then -- 真实玩家 msgData.playerInfo.heroArr = {} for _, heroId in ipairs(rankInfo.heroArr or {}) do msgData.playerInfo.heroArr[#msgData.playerInfo.heroArr+1] = heroId end else -- 机器人 msgData.playerInfo.monsteroutId = rankInfo.monsterOutID end end local fd = MiddleManager.getFDBySvrIndex(msg.sourceServerId) InnerMsg.sendMsg(fd, msgData) end -- 普通服请求排行榜数据 function BG_N2C_RankList_Req(msg) local msgData = InnerMsg.wl.WL_BATTLEGROUND_RANKLIST_QUERY msgData.playerUuid = msg.playerUuid msgData.rankList = {} local myWarZoneRankList = getMyWarZoneRankList(msg.sourceServerId) local generaRankList = getGeneraRankList() for rank=1, RANK_SHOW_NUM do local rankInfo = myWarZoneRankList and myWarZoneRankList[rank] or generaRankList[rank] msgData.rankList[rank] = { rank = rank, serverId = rankInfo.serverId, name = rankInfo.name, heroHeadId = rankInfo.headId, heroHeadFrameId = rankInfo.headFrameId, } end local fd = MiddleManager.getFDBySvrIndex(msg.sourceServerId) InnerMsg.sendMsg(fd, msgData) end -- 玩家请求挑战某个排名 function BG_N2C_Challenge_Req(msg) local msgData = InnerMsg.wl.WL_BATTLEGROUND_CHALLENGE_QUERY msgData.playerUuid = msg.playerUuid msgData.playerInfo = {} msgData.errCode = 0 local fd = MiddleManager.getFDBySvrIndex(msg.sourceServerId) local targetRank = msg.rank local myWarZoneRankList = getMyWarZoneRankList(msg.sourceServerId) local generaRankList = getGeneraRankList() local targetRanker = myWarZoneRankList and myWarZoneRankList[rank] or generaRankList[rank] if not targetRanker then msgData.errCode = -1 return InnerMsg.sendMsg(fd, msgData) end msgData.playerInfo = { rank = targetRank, playerUuid = targetRanker.playerUuid, defServerId = targetRanker.serverId or 0 } InnerMsg.sendMsg(fd, msgData) end -- 挑战结束 function BG_N2C_Challenge_End(msg) local atkPlayerUuid = msg.playerUuid local atkRank = msg.atkRank local defRank = msg.defRank local challengeRes = msg.challengeRes -- 加入参与列表 battleGroundData.joinList = battleGroundData.joinList or {} if not findVal(battleGroundData.joinList, atkPlayerUuid) then battleGroundData.joinList[#battleGroundData.joinList+1] = {msg.sourceServerId, atkPlayerUuid} updateValue("joinList", battleGroundData.joinList) end -- 挑战没有胜利 if challengeRes ~= CombatDefine.RESULT_WIN then return end local myWarZoneRankList = getMyWarZoneRankList(msg.sourceServerId) if not myWarZoneRankList then initMyWarZoneRankList(msg.sourceServerId) myWarZoneRankList = getMyWarZoneRankList(msg.sourceServerId) end -- 检查挑战方当前排名与挑战时排名是否一致 local atkRanker = myWarZoneRankList[atkRank] if atkRanker and atkRanker.playerUuid ~= atkPlayerUuid then atkRank = getPlayerRankByUuid(myWarZoneRankList, msg.playerUuid) end local defTemp = myWarZoneRankList[defRank] -- 第一次挑战 if not atkRanker then atkRanker = msg.playerShowData end -- 挑战方排名提升为被挑战方原排名 atkRanker.rank = defRank myWarZoneRankList[defRank] = atkRanker -- 如果双方都在本战区排行榜上, 被挑战方排名下降为原挑战方排名 if defTemp and atkRank <= ServerCommerceActDefine.COMMERCEACT_NPC_CNT then defTemp.rank = atkRank myWarZoneRankList[atkRank] = defTemp end -- 如果被挑战方是真实玩家, 则通知 if defTemp and defTemp.serverId ~= 0 then local msgData = InnerMsg.wl.WL_BATTLEGROUND_NOTIFY_PLAYER msgData.playerUuid = defTemp.playerUuid msgData.newRank = defTemp.rank msgData.atkeServerId = msg.sourceServerId msgData.atkName = atkRanker.name local fd = MiddleManager.getFDBySvrIndex(defTemp.serverId) InnerMsg.sendMsg(fd, msgData) end local warZoneServerIdx = getWarZoneServerIdx(msg.sourceServerId) updateValue("allAreaRankList".."."..warZoneServerIdx, battleGroundData.allAreaRankList[warZoneServerIdx]) end -- 更换战斗阵容 function BG_N2C_Lineup_Update(msg) local myWarZoneRankList = getMyWarZoneRankList(msg.sourceServerId) local myRank = getPlayerRankByUuid(myWarZoneRankList, msg.playerUuid) if myRank > ServerCommerceActDefine.COMMERCEACT_NPC_CNT then return end myWarZoneRankList[myRank].heroArr = msg.heroArr local warZoneServerIdx = getWarZoneServerIdx(msg.sourceServerId) updateValue("allAreaRankList".."."..warZoneServerIdx, battleGroundData.allAreaRankList[warZoneServerIdx]) end -- 活动结束 function BG_N2C_Act_End(msg) if notifyActEnd then return end local fd_2_Rank = {} local joinList = battleGroundData.joinList local allAreaRankList = battleGroundData.allAreaRankList -- 参与玩家(包括在榜玩家) for _, playerInfo in ipairs(joinList) do local serverId = playerInfo[1] local fd = MiddleManager.getFDBySvrIndex(serverId) fd_2_Rank[fd] = fd_2_Rank[fd] or {} fd_2_Rank[fd][#fd_2_Rank[fd]+1] = {ServerCommerceActDefine.COMMERCEACT_NPC_CNT, playerInfo[2]} end -- 在榜玩家 for _, rankList in pairs(allAreaRankList or {}) do for _, player in ipairs(rankList) do local fd = MiddleManager.getFDBySvrIndex(player.serverId) fd_2_Rank[fd] = fd_2_Rank[fd] or {} local idx = findVal(fd_2_Rank[fd], player.playerUuid) if idx then fd_2_Rank[fd][idx][1] = player.rank end end end if next(fd_2_Rank) then local delay_sec = 0 for fd, rankArr in pairs(fd_2_Rank) do delay_sec = delay_sec + 3 Timer.addLater(delay_sec, issueReward, fd, rankArr) end -- 重置排行榜数据 battleGroundData = {} saveAllData() -- 更新标识 notifyActEnd = true end end