|
|
@@ -0,0 +1,925 @@
|
|
|
+-- 战区争霸(跨服)
|
|
|
+local InnerMsg = require("core.InnerMsg")
|
|
|
+local Log = require("common.Log")
|
|
|
+local Timer = require("core.Timer")
|
|
|
+local Util = require("common.Util")
|
|
|
+local MiddleManager = require("middle.MiddleManager")
|
|
|
+local AreaBattleDB = require("areaBattle.AreaBattleDB")
|
|
|
+local AreaBattleDefine = require("areaBattle.AreaBattleDefine")
|
|
|
+local CombatVideo = require("combat.CombatVideo")
|
|
|
+local CombatDefine = require("combat.CombatDefine")
|
|
|
+local CombatLogicCS = require("combat.CombatLogicCS")
|
|
|
+local BattleDataCS = require("battleDataManager.BattleDataCS")
|
|
|
+
|
|
|
+-- 当天处于星期几(星期六为7, 星期天为1)
|
|
|
+local wDay
|
|
|
+
|
|
|
+-- 玩家战斗数据缓存表
|
|
|
+local battleDataCache = {}
|
|
|
+
|
|
|
+-- 请求序列表, 用于向普通获取玩家战斗数据
|
|
|
+local requestArr = {}
|
|
|
+
|
|
|
+
|
|
|
+local function updateWDay()
|
|
|
+ wDay = Util.getWeekDay()
|
|
|
+end
|
|
|
+
|
|
|
+local function getTodayStartTime()
|
|
|
+ local now = os.time()
|
|
|
+ return Util.getDayStartTime(now)
|
|
|
+end
|
|
|
+
|
|
|
+local function isOpen()
|
|
|
+ if not wDay then
|
|
|
+ updateWDay()
|
|
|
+ end
|
|
|
+
|
|
|
+ if not table.find(AreaBattleDefine.OPEN_WDAY_AREA, wDay) then
|
|
|
+ return false
|
|
|
+ end
|
|
|
+
|
|
|
+ local now = os.time()
|
|
|
+ local toDayStartTime = getTodayStartTime()
|
|
|
+
|
|
|
+ if wDay == AreaBattleDefine.OPEN_WDAY_AREA[1] and now < (toDayStartTime + AreaBattleDefine.PREPARE_STATE_START_SEC) then
|
|
|
+ return false
|
|
|
+ end
|
|
|
+
|
|
|
+ if wDay == AreaBattleDefine.OPEN_WDAY_AREA[2] and now > (toDayStartTime + AreaBattleDefine.END_STATE_START_SEC) then
|
|
|
+ return false
|
|
|
+ end
|
|
|
+
|
|
|
+ return true
|
|
|
+end
|
|
|
+
|
|
|
+-- 参战服务器日志格式: "serverId1, serverId2,serverId3"
|
|
|
+-- 服务器匹配列表日志格式: "serverId1-serverId2-serverId3-serverId4", 从一个serverId开始, 按顺序每两个serverId匹配到一起战斗
|
|
|
+-- 参战服务器信息日志个数: serverId | 本服战胜次数| 本服战败次数 | 战胜玩家uuid-战胜玩家uui
|
|
|
+local function writeLog(logStr)
|
|
|
+ Log.write(Log.LOGID_OSS_AREABATTLE_BATTLE, logStr)
|
|
|
+end
|
|
|
+
|
|
|
+
|
|
|
+-- 计算一个服的总战力
|
|
|
+local function calcSrvPower(playerArray)
|
|
|
+ local power = 0
|
|
|
+ for _, v in ipairs(playerArray or {}) do
|
|
|
+ power = power + (v.power or 0)
|
|
|
+ end
|
|
|
+ return power
|
|
|
+end
|
|
|
+
|
|
|
+-- 获取战斗对象的区服Id, uuid
|
|
|
+local function getBattleObjInfo(matchIdx, battleIdx, objIdentity)
|
|
|
+ local matchSrvArr = AreaBattleDB.GetMatchSrvArr()
|
|
|
+
|
|
|
+ local matchData = matchSrvArr[matchIdx]
|
|
|
+ if not matchData then
|
|
|
+ return
|
|
|
+ end
|
|
|
+
|
|
|
+ local targetSrvId = matchData[objIdentity]
|
|
|
+ if not targetSrvId then
|
|
|
+ return
|
|
|
+ end
|
|
|
+
|
|
|
+ local serverList = AreaBattleDB.GetServerList()
|
|
|
+ if not serverList[targetSrvId] then
|
|
|
+ return
|
|
|
+ end
|
|
|
+
|
|
|
+ local srvPlayerArr = serverList[targetSrvId].playerInfoArr
|
|
|
+ local playerInfo = srvPlayerArr[battleIdx]
|
|
|
+
|
|
|
+ return targetSrvId, playerInfo and playerInfo.uuid
|
|
|
+end
|
|
|
+
|
|
|
+
|
|
|
+-- 进入新一轮的处理
|
|
|
+local function newRoundHandle()
|
|
|
+ local stateDB = AreaBattleDB.GetState()
|
|
|
+
|
|
|
+ -- 上一轮奖励没有发放, 在新一轮开始时, 先发奖
|
|
|
+ if stateDB == AreaBattleDefine.STATE_AWARD then
|
|
|
+ AwardPrizesHandle()
|
|
|
+ end
|
|
|
+
|
|
|
+ -- 清除录像数据
|
|
|
+ CombatVideo.ClearOutVideoByCombatType(CombatVideo.VIDEOTYPE_AREABATTLE)
|
|
|
+
|
|
|
+ -- 重置录像缓存
|
|
|
+ AreaBattleDB.ResetVideoShowCache()
|
|
|
+
|
|
|
+ -- 重置战区争霸数据
|
|
|
+ AreaBattleDB.ResetData()
|
|
|
+
|
|
|
+ -- 更新状态
|
|
|
+ AreaBattleDB.UpdateState(AreaBattleDefine.STATE_PREPARE)
|
|
|
+
|
|
|
+ -- 通知普通服
|
|
|
+ NotifySrvJoin()
|
|
|
+
|
|
|
+
|
|
|
+ -- 重置缓存数据
|
|
|
+ battleDataCache = {}
|
|
|
+ requestArr = {}
|
|
|
+end
|
|
|
+
|
|
|
+-- 服务器分组算法
|
|
|
+local function matchAlgorithm(serverArr, len)
|
|
|
+ local usedTb = {}
|
|
|
+ local pairTb = {}
|
|
|
+
|
|
|
+ local function getNextUnuseIdx(nowIdx)
|
|
|
+ for i=nowIdx, len do
|
|
|
+ if not usedTb[i] then
|
|
|
+ return i
|
|
|
+ end
|
|
|
+ end
|
|
|
+ end
|
|
|
+
|
|
|
+ local function checkRandIdx(startIdx, endIdx)
|
|
|
+ local tbl= {}
|
|
|
+ for i= startIdx, endIdx do
|
|
|
+ if i <= len and not usedTb[i] then
|
|
|
+ table.insert(tbl, i)
|
|
|
+ end
|
|
|
+ end
|
|
|
+ return tbl
|
|
|
+ end
|
|
|
+
|
|
|
+ local currentIdx = 1
|
|
|
+ while currentIdx <= len do
|
|
|
+ currentIdx = getNextUnuseIdx(currentIdx)
|
|
|
+ if not currentIdx then
|
|
|
+ break
|
|
|
+ end
|
|
|
+
|
|
|
+ local startIdx = currentIdx+1
|
|
|
+ local endIdx = currentIdx+3
|
|
|
+ local correctTb = checkRandIdx(startIdx, endIdx)
|
|
|
+ local matchIdx = correctTb[math.random(1, #correctTb)]
|
|
|
+
|
|
|
+ usedTb[currentIdx] = true
|
|
|
+ usedTb[matchIdx] = true
|
|
|
+ table.insert(pairTb, {serverArr[currentIdx], serverArr[matchIdx]})
|
|
|
+ currentIdx = currentIdx + 1
|
|
|
+ end
|
|
|
+
|
|
|
+ return pairTb
|
|
|
+end
|
|
|
+
|
|
|
+-- 生成匹配列表
|
|
|
+local function genMacthArr()
|
|
|
+ local joinSrvArr = AreaBattleDB.GetJoinSrvArr()
|
|
|
+ local joinSrvArr_cp = Util.copyTable(joinSrvArr)
|
|
|
+ if not joinSrvArr_cp or #joinSrvArr_cp <= 0 then
|
|
|
+ return
|
|
|
+ end
|
|
|
+
|
|
|
+ local srvCnt = #joinSrvArr_cp
|
|
|
+ if srvCnt > 1 then
|
|
|
+ if srvCnt % 2 ~= 0 then
|
|
|
+ local deleteSrvId = joinSrvArr_cp[srvCnt]
|
|
|
+ joinSrvArr_cp[srvCnt] = nil
|
|
|
+ srvCnt = srvCnt - 1
|
|
|
+
|
|
|
+ -- 把被移除的服务器从服务器数据列表中移除
|
|
|
+ local serverList = AreaBattleDB.GetServerList()
|
|
|
+ serverList[deleteSrvId] = nil
|
|
|
+ AreaBattleDB.UpdateServerList(serverList)
|
|
|
+
|
|
|
+ -- 记录日志
|
|
|
+ local logStr = "移除多余的区服, 区服Id: " .. deleteSrvId
|
|
|
+ writeLog(logStr)
|
|
|
+ end
|
|
|
+
|
|
|
+ table.sort(joinSrvArr_cp)
|
|
|
+ local matchArr = matchAlgorithm(joinSrvArr_cp, srvCnt)
|
|
|
+ AreaBattleDB.UpdateMatchSrvArr(matchArr)
|
|
|
+ end
|
|
|
+end
|
|
|
+
|
|
|
+-- 获取玩家的战斗数据
|
|
|
+local function getPlayerBattleData(serverId, playerUuid, extraArgs)
|
|
|
+ extraArgs.serverId = serverId
|
|
|
+ extraArgs.playerUuid = playerUuid
|
|
|
+ BattleDataCS.GetPlayerCombatData(serverId, playerUuid, BattleDataCS.AREABTTLE_TAG, CombatDefine.COMBAT_TYPE33, extraArgs)
|
|
|
+end
|
|
|
+
|
|
|
+-- 分批请求玩家战斗数据
|
|
|
+function Timed_GetPlayerBattleData()
|
|
|
+ if not requestArr or not next(requestArr) then
|
|
|
+ return
|
|
|
+ end
|
|
|
+
|
|
|
+ local maxNum = math.min(#requestArr, AreaBattleDefine.GET_BATTLE_MAX_CNT_TIMES)
|
|
|
+ for i=1, maxNum do
|
|
|
+ local info = table.remove(requestArr)
|
|
|
+ getPlayerBattleData(info[1], info[2], info[3])
|
|
|
+ end
|
|
|
+
|
|
|
+ if #requestArr > 0 then
|
|
|
+ Timer.addLater(2, Timed_GetPlayerBattleData, requestArr)
|
|
|
+ end
|
|
|
+end
|
|
|
+
|
|
|
+-- 向普通服请求战斗数据
|
|
|
+local function requestPlayerBattleData()
|
|
|
+ local matchSrvArr = AreaBattleDB.GetMatchSrvArr()
|
|
|
+ local serverList = AreaBattleDB.GetServerList()
|
|
|
+ if not matchSrvArr or #matchSrvArr == 0 or not next(serverList) then
|
|
|
+ return
|
|
|
+ end
|
|
|
+
|
|
|
+ for idx, matchSrvTb in ipairs(matchSrvArr) do
|
|
|
+ local serverId1 = matchSrvTb[1]
|
|
|
+ local serverId2 = matchSrvTb[2]
|
|
|
+ local playerArr1 = serverList[serverId1] and serverList[serverId1].playerInfoArr or {}
|
|
|
+ local playerArr2 = serverList[serverId2] and serverList[serverId2].playerInfoArr or {}
|
|
|
+ local maxPlayerCnt = math.max(#playerArr1, #playerArr2)
|
|
|
+
|
|
|
+ for i=1, maxPlayerCnt do
|
|
|
+ local playerUuid1 = playerArr1[i] and playerArr1[i].uuid
|
|
|
+ local playerUuid2 = playerArr2[i] and playerArr2[i].uuid
|
|
|
+
|
|
|
+ if playerUuid1 then
|
|
|
+ local args = {
|
|
|
+ firstIdx = idx,
|
|
|
+ secondIdx = i,
|
|
|
+ identity = 1, --身份,1-进攻方, 2-防御方
|
|
|
+ serverId = 0,
|
|
|
+ playerUuid = "",
|
|
|
+ }
|
|
|
+ -- getPlayerBattleData(serverId1, playerUuid1, args)
|
|
|
+ requestArr[#requestArr+1] = {serverId1, playerUuid1, args}
|
|
|
+ end
|
|
|
+
|
|
|
+ if playerUuid2 then
|
|
|
+ local args = {
|
|
|
+ firstIdx = idx,
|
|
|
+ secondIdx = i,
|
|
|
+ identity = 2, --身份,1-进攻方, 2-防御方
|
|
|
+ serverId = 0,
|
|
|
+ playerUuid = "",
|
|
|
+ }
|
|
|
+ -- getPlayerBattleData(serverId2, playerUuid2, args)
|
|
|
+ requestArr[#requestArr+1] = {serverId2, playerUuid2, args}
|
|
|
+ end
|
|
|
+ end
|
|
|
+ end
|
|
|
+
|
|
|
+ local now = os.time()
|
|
|
+ AreaBattleDB.UpdateUpLoadStartTi(now)
|
|
|
+
|
|
|
+ Timed_GetPlayerBattleData()
|
|
|
+end
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+-- 处于准备阶段处理, 给服务器进行匹配, 并通知普通服上传玩家战斗数据
|
|
|
+local function prepareHandle()
|
|
|
+ local stateDB = AreaBattleDB.GetState()
|
|
|
+ if stateDB ~= AreaBattleDefine.STATE_PREPARE then
|
|
|
+ return
|
|
|
+ end
|
|
|
+
|
|
|
+ -- 服务器进行匹配
|
|
|
+ genMacthArr()
|
|
|
+
|
|
|
+ -- 让普通服上传战斗数据
|
|
|
+ -- requestPlayerBattleData()
|
|
|
+end
|
|
|
+
|
|
|
+-- 上一轮 ~ 新一轮准备阶段的处理
|
|
|
+local function earlyHanle()
|
|
|
+ local now = os.time()
|
|
|
+ local stateDB = AreaBattleDB.GetState()
|
|
|
+ local nowRoundStartTi = AreaBattleDB.GetNowRoundStartTi()
|
|
|
+ local diffDays = Util.diffDay(nowRoundStartTi)
|
|
|
+
|
|
|
+ -- 开启新一轮活动
|
|
|
+ if nowRoundStartTi <= 0 or diffDays >= 2 then
|
|
|
+ return newRoundHandle()
|
|
|
+ end
|
|
|
+
|
|
|
+ -- 处于准备阶段, 普通服上传完本服排名前15的玩家数据后,如果还没有对服务器进行分组, 则生成服务器匹配列表, 并通知这些服务器上传本服玩家战斗数据
|
|
|
+ if diffDays < 2 and now - nowRoundStartTi >= AreaBattleDefine.SERVER_DATA_TIME and stateDB == AreaBattleDefine.STATE_PREPARE then
|
|
|
+ local matchSrvArr = AreaBattleDB.GetMatchSrvArr()
|
|
|
+ if not matchSrvArr or not next(matchSrvArr) then
|
|
|
+ prepareHandle()
|
|
|
+ end
|
|
|
+ end
|
|
|
+end
|
|
|
+
|
|
|
+
|
|
|
+-- 进入战斗阶段的处理
|
|
|
+local function BattleStageHandle()
|
|
|
+ local stateDB = AreaBattleDB.GetState()
|
|
|
+ if stateDB ~= AreaBattleDefine.STATE_BATTLE then
|
|
|
+ return
|
|
|
+ end
|
|
|
+
|
|
|
+ StartBattle()
|
|
|
+end
|
|
|
+
|
|
|
+-- 战斗结束, 把结果更新到DB
|
|
|
+local function updateDBBattleResult(battleInfo)
|
|
|
+ local attackerServerId = battleInfo.attackerServerId
|
|
|
+ local attackerUuid = battleInfo.attackerUuid
|
|
|
+ local defenerServerId = battleInfo.defenerServerId
|
|
|
+ local defenerUuid = battleInfo.defenerUuid
|
|
|
+ local isWin = battleInfo.isWin
|
|
|
+ local serverList = AreaBattleDB.GetServerList()
|
|
|
+
|
|
|
+ local attackerSrvData = serverList[attackerServerId]
|
|
|
+ if attackerSrvData then
|
|
|
+ if isWin == 1 then
|
|
|
+ attackerSrvData.winTimes = (attackerSrvData.winTimes or 0) + 1
|
|
|
+ attackerSrvData.winPlayerArr = attackerSrvData.winPlayerArr or {}
|
|
|
+ table.insert(attackerSrvData.winPlayerArr, attackerUuid)
|
|
|
+ else
|
|
|
+ attackerSrvData.defeatTimes = (attackerSrvData.defeatTimes or 0) + 1
|
|
|
+ end
|
|
|
+ end
|
|
|
+
|
|
|
+ local defenerSrvData = serverList[defenerServerId]
|
|
|
+ if defenerSrvData then
|
|
|
+ if isWin == 0 then
|
|
|
+ defenerSrvData.winTimes = (defenerSrvData.winTimes or 0) + 1
|
|
|
+ defenerSrvData.winPlayerArr = defenerSrvData.winPlayerArr or {}
|
|
|
+ table.insert(defenerSrvData.winPlayerArr, defenerUuid)
|
|
|
+ else
|
|
|
+ defenerSrvData.defeatTimes = (defenerSrvData.defeatTimes or 0) + 1
|
|
|
+ end
|
|
|
+ end
|
|
|
+
|
|
|
+ AreaBattleDB.UpdateServerList(serverList)
|
|
|
+end
|
|
|
+
|
|
|
+
|
|
|
+-- 生成用于通知各个普通服发奖的数据
|
|
|
+local function genNotifyInfo(serverInfo)
|
|
|
+ local info = {
|
|
|
+ isWin = 0,
|
|
|
+ winPlayerArr = {},
|
|
|
+ defeatPlayerArr = {}
|
|
|
+ }
|
|
|
+
|
|
|
+ if (serverInfo.winTimes or 0) > (serverInfo.defeatTimes or 0) then
|
|
|
+ info.isWin = 1
|
|
|
+ end
|
|
|
+
|
|
|
+ for _, playerInfo in ipairs(serverInfo.playerInfoArr) do
|
|
|
+ if table.find(serverInfo.winPlayerArr, playerInfo.uuid) then
|
|
|
+ table.insert(info.winPlayerArr, playerInfo.uuid)
|
|
|
+ else
|
|
|
+ table.insert(info.defeatPlayerArr, playerInfo.uuid)
|
|
|
+ end
|
|
|
+ end
|
|
|
+
|
|
|
+ return info
|
|
|
+end
|
|
|
+
|
|
|
+-- 生成日志
|
|
|
+local function genLog()
|
|
|
+ local t1, t2 = {}, {}
|
|
|
+
|
|
|
+ local joinSrvArr = AreaBattleDB.GetJoinSrvArr()
|
|
|
+ for idx, srvId in ipairs(joinSrvArr or {}) do
|
|
|
+ t1[idx] = srvId
|
|
|
+ end
|
|
|
+ local str1 = table.concat(t1, ",")
|
|
|
+ writeLog(str1)
|
|
|
+
|
|
|
+
|
|
|
+ local len = 0
|
|
|
+ local matchSrvArr = AreaBattleDB.GetMatchSrvArr()
|
|
|
+ for _, srvTb in ipairs(matchSrvArr or {}) do
|
|
|
+ for _, servrId in ipairs(srvTb) do
|
|
|
+ len = len + 1
|
|
|
+ t2[len] = servrId
|
|
|
+ end
|
|
|
+ end
|
|
|
+
|
|
|
+ local str2 = table.concat(t2, "-")
|
|
|
+ writeLog(str2)
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ local serverList = AreaBattleDB.GetServerList()
|
|
|
+ for serverId, srvInfo in pairs(serverList or {}) do
|
|
|
+ local t = {serverId, srvInfo.winTimes or 0, srvInfo.defeatTimes or 0}
|
|
|
+ if srvInfo.winPlayerArr and #srvInfo.winPlayerArr > 0 then
|
|
|
+ local s = table.concat(Util.copyTable(srvInfo.winPlayerArr), "-")
|
|
|
+ table.insert(t, s)
|
|
|
+ end
|
|
|
+
|
|
|
+ local str3 = table.concat(t, "|")
|
|
|
+ writeLog(str3)
|
|
|
+ end
|
|
|
+end
|
|
|
+
|
|
|
+
|
|
|
+-------------------------------------------C2N-------------------------------------------
|
|
|
+
|
|
|
+-- 通知普通服,争霸开始
|
|
|
+function NotifySrvJoin()
|
|
|
+ local msgData = InnerMsg.wl.WL_AREABATTLE_OPEN
|
|
|
+ local fdList = MiddleManager.MiddleManager_GetAllFD()
|
|
|
+ for _, fd in pairs(fdList) do
|
|
|
+ InnerMsg.sendMsg(fd, msgData)
|
|
|
+ end
|
|
|
+end
|
|
|
+
|
|
|
+-- 通知普通服发奖
|
|
|
+function NotifySrvAwardPrizes(fd, args)
|
|
|
+ local msgData = InnerMsg.wl.WL_AREABATTLE_SEND_REWARD
|
|
|
+ msgData.srvBattleRes = args
|
|
|
+ InnerMsg.sendMsg(fd, msgData)
|
|
|
+end
|
|
|
+
|
|
|
+-------------------------------------------N2C-----------------------------------------------
|
|
|
+
|
|
|
+-- 普通服加入战斗
|
|
|
+function N2C_JoinBattle(msg)
|
|
|
+ local sourceServerId = msg.sourceServerId
|
|
|
+ local joinBattleArray = msg.joinBattleArray
|
|
|
+
|
|
|
+ local joinSrvArr = AreaBattleDB.GetJoinSrvArr()
|
|
|
+ local serverList = AreaBattleDB.GetServerList()
|
|
|
+
|
|
|
+ if not table.find(joinSrvArr, sourceServerId) and not serverList[sourceServerId] then
|
|
|
+ -- 参战列表
|
|
|
+ table.insert(joinSrvArr, sourceServerId)
|
|
|
+ AreaBattleDB.UpdateJoinSrvArr(joinSrvArr)
|
|
|
+
|
|
|
+ -- 服务器列表
|
|
|
+ serverList[sourceServerId] = {
|
|
|
+ winTimes = 0,
|
|
|
+ defeatTimes = 0,
|
|
|
+ winPlayerArr = {},
|
|
|
+ playerInfoArr = joinBattleArray
|
|
|
+ }
|
|
|
+ AreaBattleDB.UpdateServerList(serverList)
|
|
|
+ end
|
|
|
+end
|
|
|
+
|
|
|
+-- 普通服请求争霸活动的基本数据
|
|
|
+function N2C_GetBaseInfo(msg)
|
|
|
+ local fd = MiddleManager.getFDBySvrIndex(msg.sourceServerId)
|
|
|
+ local msgData = InnerMsg.wl.WL_AREABATTLE_BASEINFO_QUERY
|
|
|
+ msgData.playerUuid = msg.playerUuid
|
|
|
+
|
|
|
+ local state = AreaBattleDB.GetState()
|
|
|
+ msgData.stage = state
|
|
|
+ msgData.startTime, msgData.endTime = 0, 0
|
|
|
+ local toDayStartTime = getTodayStartTime()
|
|
|
+
|
|
|
+ if not wDay then
|
|
|
+ updateWDay()
|
|
|
+ end
|
|
|
+
|
|
|
+ if wDay == AreaBattleDefine.OPEN_WDAY_AREA[1] then
|
|
|
+ msgData.startTime = toDayStartTime + AreaBattleDefine.PREPARE_STATE_START_SEC
|
|
|
+ msgData.endTime = toDayStartTime + 86400 + AreaBattleDefine.END_STATE_START_SEC
|
|
|
+
|
|
|
+ elseif wDay == AreaBattleDefine.OPEN_WDAY_AREA[2] then
|
|
|
+ msgData.startTime = toDayStartTime - 86400 + AreaBattleDefine.PREPARE_STATE_START_SEC
|
|
|
+ msgData.endTime = toDayStartTime + AreaBattleDefine.END_STATE_START_SEC
|
|
|
+
|
|
|
+ local now = os.time()
|
|
|
+ if state == AreaBattleDefine.STATE_AWARD and now < toDayStartTime + AreaBattleDefine.END_STATE_START_SEC then
|
|
|
+ msgData.stage = AreaBattleDefine.STATE_BATTLE
|
|
|
+ end
|
|
|
+ else
|
|
|
+ local subDay = AreaBattleDefine.OPEN_WDAY_AREA[1] - wDay
|
|
|
+ msgData.startTime = toDayStartTime + subDay * 86400 + AreaBattleDefine.PREPARE_STATE_START_SEC
|
|
|
+ msgData.endTime = toDayStartTime + (subDay + 1) * 86400 + AreaBattleDefine.END_STATE_START_SEC
|
|
|
+ end
|
|
|
+
|
|
|
+ InnerMsg.sendMsg(fd, msgData)
|
|
|
+end
|
|
|
+
|
|
|
+-- 普通服请求本服参战玩家列表
|
|
|
+function N2C_GetJoinPlayerArr(msg)
|
|
|
+ local sourceServerId = msg.sourceServerId
|
|
|
+ local fd = MiddleManager.getFDBySvrIndex(sourceServerId)
|
|
|
+ local msgData = InnerMsg.wl.WL_AREABATTLE_JOINPLAYER_QUERY
|
|
|
+ msgData.errCode = 0
|
|
|
+ msgData.playerArray = {}
|
|
|
+ msgData.playerUuid = msg.playerUuid
|
|
|
+
|
|
|
+ local joinSrvArr = AreaBattleDB.GetJoinSrvArr()
|
|
|
+ local mathcList = AreaBattleDB.GetMatchSrvArr()
|
|
|
+
|
|
|
+ -- 没有参加
|
|
|
+ if not joinSrvArr or not table.find(joinSrvArr, sourceServerId) then
|
|
|
+ msgData.errCode = -1
|
|
|
+ return InnerMsg.sendMsg(fd, msgData)
|
|
|
+ end
|
|
|
+
|
|
|
+ -- 匹配列表还没生成
|
|
|
+ if not mathcList or not next(mathcList) then
|
|
|
+ msgData.errCode = -2
|
|
|
+ return InnerMsg.sendMsg(fd, msgData)
|
|
|
+ end
|
|
|
+
|
|
|
+
|
|
|
+ local isInMathcArr = false
|
|
|
+ for _, matchSrvTb in ipairs(mathcList) do
|
|
|
+ if table.find(matchSrvTb, sourceServerId) then
|
|
|
+ isInMathcArr = true
|
|
|
+ break
|
|
|
+ end
|
|
|
+ end
|
|
|
+ -- 参加了,但是被移除, 没有在本轮匹配列表中
|
|
|
+ if not isInMathcArr then
|
|
|
+ msgData.errCode = -3
|
|
|
+ return InnerMsg.sendMsg(fd, msgData)
|
|
|
+ end
|
|
|
+
|
|
|
+ local serverList = AreaBattleDB.GetServerList()
|
|
|
+ msgData.playerArray = serverList[sourceServerId] and serverList[sourceServerId].playerInfoArr or {}
|
|
|
+ InnerMsg.sendMsg(fd, msgData)
|
|
|
+end
|
|
|
+
|
|
|
+
|
|
|
+-- 普通服请求本次参战的区服的匹配列表
|
|
|
+-- { { {server1, power1}, {server2, power2} }, }
|
|
|
+function N2C_GetMatchList(msg)
|
|
|
+ local sourceServerId = msg.sourceServerId
|
|
|
+ local fd = MiddleManager.getFDBySvrIndex(sourceServerId)
|
|
|
+ local msgData = InnerMsg.wl.WL_AREABATTLE_MATCHLIST_QUERY
|
|
|
+ msgData.playerUuid = msg.playerUuid
|
|
|
+ msgData.matchList = {}
|
|
|
+
|
|
|
+ local mathcList = AreaBattleDB.GetMatchSrvArr()
|
|
|
+ local serverList = AreaBattleDB.GetServerList()
|
|
|
+
|
|
|
+ for k, matchSrvTb in ipairs(mathcList) do
|
|
|
+ msgData.matchList[k] = {}
|
|
|
+
|
|
|
+ for idx, serverId in ipairs(matchSrvTb) do
|
|
|
+ if serverList[serverId] then
|
|
|
+ -- table.insert(msgData.matchList[k], serverId)
|
|
|
+ local power = calcSrvPower(serverList[serverId].playerInfoArr)
|
|
|
+ -- table.insert(msgData.matchList[k], power)
|
|
|
+ msgData.matchList[k][idx] = {serverId, power}
|
|
|
+ end
|
|
|
+ end
|
|
|
+
|
|
|
+ end
|
|
|
+
|
|
|
+ InnerMsg.sendMsg(fd, msgData)
|
|
|
+end
|
|
|
+
|
|
|
+-- 普通服请求本服的战斗录像展示数据
|
|
|
+function N2C_GetVideoShowData(msg)
|
|
|
+ local sourceServerId = msg.sourceServerId
|
|
|
+ local fd = MiddleManager.getFDBySvrIndex(sourceServerId)
|
|
|
+
|
|
|
+ local msgData = InnerMsg.wl.WL_AREABATTLE_VIDEOSHOW_QUERY
|
|
|
+ msgData.errCode = 0
|
|
|
+ msgData.playerUuid = msg.playerUuid
|
|
|
+ msgData.videoShowData = {}
|
|
|
+ msgData.srvInfo = {}
|
|
|
+
|
|
|
+ local state = AreaBattleDB.GetState()
|
|
|
+ if state ~= AreaBattleDefine.STATE_AWARD and state ~= AreaBattleDefine.STATE_END then
|
|
|
+ msgData.errCode = -1
|
|
|
+ return InnerMsg.sendMsg(fd, msgData)
|
|
|
+ end
|
|
|
+
|
|
|
+ local videoSecondIdx, leftSrvId, rightSrvId = 0, 0, 0
|
|
|
+ local matchSrvArr = AreaBattleDB.GetMatchSrvArr()
|
|
|
+ for k, srvTb in ipairs(matchSrvArr or {}) do
|
|
|
+ if table.find(srvTb, sourceServerId) then
|
|
|
+ videoSecondIdx = k
|
|
|
+ leftSrvId = srvTb[1]
|
|
|
+ rightSrvId = srvTb[2]
|
|
|
+ break
|
|
|
+ end
|
|
|
+ end
|
|
|
+
|
|
|
+ -- 本轮没有参加活动
|
|
|
+ if videoSecondIdx == 0 then
|
|
|
+ msgData.errCode = -3
|
|
|
+ return InnerMsg.sendMsg(fd, msgData)
|
|
|
+ end
|
|
|
+
|
|
|
+
|
|
|
+ local serverList = AreaBattleDB.GetServerList()
|
|
|
+ if serverList[leftSrvId] then
|
|
|
+ msgData.srvInfo.leftSrvId = leftSrvId
|
|
|
+ msgData.srvInfo.leftWinTimes = serverList[leftSrvId].winTimes or 0
|
|
|
+ msgData.srvInfo.leftSrvPower = calcSrvPower(serverList[leftSrvId].playerInfoArr)
|
|
|
+ end
|
|
|
+
|
|
|
+ if serverList[rightSrvId] then
|
|
|
+ msgData.srvInfo.rightSrvId = rightSrvId
|
|
|
+ msgData.srvInfo.rightWinTimes = serverList[rightSrvId].winTimes or 0
|
|
|
+ msgData.srvInfo.rightSrvPower = calcSrvPower(serverList[rightSrvId].playerInfoArr)
|
|
|
+ end
|
|
|
+
|
|
|
+
|
|
|
+ local videoArr = AreaBattleDB.GetSrvVideoShowData(videoSecondIdx)
|
|
|
+ -- msgData.videoShowData = videoArr
|
|
|
+
|
|
|
+ for _, v in ipairs(videoArr) do
|
|
|
+ if (v.atkData and v.atkData.uuid == msg.playerUuid) or (v.defenerData and v.defenerData.uuid == msg.playerUuid) then
|
|
|
+ table.insert(msgData.videoShowData, 1, v)
|
|
|
+ else
|
|
|
+ msgData.videoShowData[#msgData.videoShowData+1] = v
|
|
|
+ end
|
|
|
+
|
|
|
+ end
|
|
|
+
|
|
|
+ InnerMsg.sendMsg(fd, msgData)
|
|
|
+end
|
|
|
+
|
|
|
+---------------------------------------------------------------------------------------------
|
|
|
+
|
|
|
+
|
|
|
+function oneMin()
|
|
|
+ if _G.is_middle ~= true then return end
|
|
|
+
|
|
|
+ if not isOpen() then
|
|
|
+ return
|
|
|
+ end
|
|
|
+
|
|
|
+ -- 与 onHour() 处理错开
|
|
|
+ if Util.getMin() == 0 then
|
|
|
+ return
|
|
|
+ end
|
|
|
+
|
|
|
+ local now = os.time()
|
|
|
+ local toDayStartTime = getTodayStartTime()
|
|
|
+
|
|
|
+ -- 活动第一天, 当前时间 >= 开启时间
|
|
|
+ if wDay == AreaBattleDefine.OPEN_WDAY_AREA[1] then
|
|
|
+ earlyHanle()
|
|
|
+ end
|
|
|
+
|
|
|
+ -- 活动最后一天, 当前时间 < 活动结束时间
|
|
|
+ if wDay == AreaBattleDefine.OPEN_WDAY_AREA[2] then
|
|
|
+
|
|
|
+ earlyHanle()
|
|
|
+
|
|
|
+ local stateDB = AreaBattleDB.GetState()
|
|
|
+ -- local nowRoundStartTi = AreaBattleDB.GetNowRoundStartTi()
|
|
|
+
|
|
|
+ -- 当前处于准备阶段, 但是当前时间 >= 对战开始时间, 则进入对战阶段
|
|
|
+ if now >= (toDayStartTime + AreaBattleDefine.BATTLE_STATE_START_SEC) and stateDB == AreaBattleDefine.STATE_PREPARE then
|
|
|
+ -- 防止某些情况下,进入准备阶段后普通服数据还没上传完就进入对战阶段
|
|
|
+ local upLoadStartTi = AreaBattleDB.GetUpLoadStartTi()
|
|
|
+ if now - upLoadStartTi > AreaBattleDefine.BATTLE_DATA_TIME then
|
|
|
+
|
|
|
+ -- 重启跨服后导致战斗数据缓存没了,则重新获取。 -- 新逻辑: 每次进入战斗阶段时才让普通服上传玩家战斗数据
|
|
|
+ if not next(battleDataCache) then
|
|
|
+ if #requestArr == 0 then
|
|
|
+ return requestPlayerBattleData()
|
|
|
+ end
|
|
|
+ end
|
|
|
+
|
|
|
+ -- 处于请求战斗数据过程中, 等请求完再进入战斗
|
|
|
+ if #requestArr > 0 then
|
|
|
+ return
|
|
|
+ end
|
|
|
+
|
|
|
+ AreaBattleDB.UpdateState(AreaBattleDefine.STATE_BATTLE)
|
|
|
+ BattleStageHandle()
|
|
|
+ return
|
|
|
+ end
|
|
|
+ end
|
|
|
+
|
|
|
+ -- 当前时间 >= 发奖时间
|
|
|
+ if now >= (toDayStartTime + AreaBattleDefine.END_STATE_START_SEC) and stateDB == AreaBattleDefine.STATE_AWARD then
|
|
|
+ AwardPrizesHandle()
|
|
|
+ AreaBattleDB.UpdateState(AreaBattleDefine.STATE_END)
|
|
|
+ end
|
|
|
+ end
|
|
|
+end
|
|
|
+
|
|
|
+function onHour(hour)
|
|
|
+ if _G.is_middle ~= true then return end
|
|
|
+
|
|
|
+ if hour == 0 or not wDay then
|
|
|
+ updateWDay()
|
|
|
+ end
|
|
|
+
|
|
|
+ if not table.find(AreaBattleDefine.OPEN_WDAY_AREA, wDay) then
|
|
|
+ return
|
|
|
+ end
|
|
|
+
|
|
|
+ -- 对战阶段
|
|
|
+ if wDay == AreaBattleDefine.OPEN_WDAY_AREA[2] and hour >= 12 then
|
|
|
+ local now = os.time()
|
|
|
+ local stateDB = AreaBattleDB.GetState()
|
|
|
+ -- local nowRoundStartTi = AreaBattleDB.GetNowRoundStartTi()
|
|
|
+ local upLoadStartTi = AreaBattleDB.GetUpLoadStartTi()
|
|
|
+
|
|
|
+ -- 防止某些情况下,进入准备阶段后,普通服数据还没上传完就进入对战阶段
|
|
|
+ if stateDB == AreaBattleDefine.STATE_PREPARE and (now - upLoadStartTi > AreaBattleDefine.BATTLE_DATA_TIME) then
|
|
|
+
|
|
|
+ -- 重启跨服后导致战斗数据缓存没了,则重新获取。-- 新逻辑: 每次进入战斗阶段时才让普通服上传玩家战斗数据
|
|
|
+ if not next(battleDataCache) then
|
|
|
+ -- 可能存在响应比较慢的情况,保证只执行一次 requestPlayerBattleData
|
|
|
+ if #requestArr == 0 then
|
|
|
+ return requestPlayerBattleData()
|
|
|
+ end
|
|
|
+ end
|
|
|
+
|
|
|
+ -- 处于请求战斗数据过程中, 等请求完再进入战斗
|
|
|
+ if #requestArr > 0 then
|
|
|
+ return
|
|
|
+ end
|
|
|
+
|
|
|
+ AreaBattleDB.UpdateState(AreaBattleDefine.STATE_BATTLE)
|
|
|
+ BattleStageHandle()
|
|
|
+ end
|
|
|
+ end
|
|
|
+
|
|
|
+ -- 发奖阶段
|
|
|
+ if wDay == AreaBattleDefine.OPEN_WDAY_AREA[2] and hour >= 22 then
|
|
|
+ local stateDB = AreaBattleDB.GetState()
|
|
|
+ if stateDB == AreaBattleDefine.STATE_AWARD then
|
|
|
+ AwardPrizesHandle()
|
|
|
+ AreaBattleDB.UpdateState(AreaBattleDefine.STATE_END)
|
|
|
+ end
|
|
|
+ end
|
|
|
+end
|
|
|
+
|
|
|
+
|
|
|
+-- 通知普通服发奖
|
|
|
+function BrocastServer(srvTb)
|
|
|
+ for fd, notifyInfo in pairs(srvTb) do
|
|
|
+ NotifySrvAwardPrizes(fd, notifyInfo)
|
|
|
+ end
|
|
|
+end
|
|
|
+
|
|
|
+-- 分批次通知普通服
|
|
|
+function BatchServer()
|
|
|
+ local matchSrvArr = AreaBattleDB.GetMatchSrvArr()
|
|
|
+ if not matchSrvArr or not next(matchSrvArr) then
|
|
|
+ return
|
|
|
+ end
|
|
|
+
|
|
|
+ local len, delay_sec = 0, 0
|
|
|
+ local srvTb = {}
|
|
|
+ local serverList = AreaBattleDB.GetServerList()
|
|
|
+ for serverId, serverInfo in pairs(serverList or {}) do
|
|
|
+ local fd = MiddleManager.getFDBySvrIndex(serverId)
|
|
|
+ if fd then
|
|
|
+ len = len + 1
|
|
|
+ local notifyInfo = genNotifyInfo(serverInfo)
|
|
|
+ srvTb[fd] = notifyInfo
|
|
|
+ end
|
|
|
+
|
|
|
+ if len >= AreaBattleDefine.BATCH_MAX_SRV_NUM then
|
|
|
+ delay_sec = delay_sec + 5
|
|
|
+ Timer.addLater(delay_sec, BrocastServer, srvTb)
|
|
|
+ srvTb = {}
|
|
|
+ len = 0
|
|
|
+ end
|
|
|
+ end
|
|
|
+
|
|
|
+ if len > 0 then
|
|
|
+ delay_sec = delay_sec + 5
|
|
|
+ Timer.addLater(delay_sec, BrocastServer, srvTb)
|
|
|
+ end
|
|
|
+end
|
|
|
+
|
|
|
+-- 发奖
|
|
|
+function AwardPrizesHandle()
|
|
|
+ genLog()
|
|
|
+ BatchServer()
|
|
|
+end
|
|
|
+
|
|
|
+
|
|
|
+-- 开始战斗
|
|
|
+function StartBattle()
|
|
|
+ for firstIdx, battleDList in pairs(battleDataCache) do
|
|
|
+ for secondIdx, playerBattleData in pairs(battleDList) do
|
|
|
+ local attackerInfo = playerBattleData.attackerInfo
|
|
|
+ local defenerInfo = playerBattleData.defenerInfo
|
|
|
+
|
|
|
+ local args = {
|
|
|
+ isWin = 0,
|
|
|
+ attackerServerId = "",
|
|
|
+ attackerUuid = "",
|
|
|
+ defenerServerId = "",
|
|
|
+ defenerUuid = ""
|
|
|
+ }
|
|
|
+
|
|
|
+ if attackerInfo and defenerInfo then -- 正常情况
|
|
|
+ args.attackerServerId = attackerInfo.serverId
|
|
|
+ args.attackerUuid = attackerInfo.playerUuid
|
|
|
+ args.defenerServerId = defenerInfo.serverId
|
|
|
+ args.defenerUuid = defenerInfo.playerUuid
|
|
|
+ args.videoSecondIdx = firstIdx
|
|
|
+
|
|
|
+ -- CombatLogicCS.combatBegin(attackerInfo.battleData, defenerInfo.battleData, CombatDefine.COMBAT_TYPE33, FightEnd, args)
|
|
|
+ local ok, err = pcall(CombatLogicCS.combatBegin, attackerInfo.battleData, defenerInfo.battleData, CombatDefine.COMBAT_TYPE33, FightEnd, args)
|
|
|
+ if not ok then
|
|
|
+ local str = string.format("BattleErr, firstIdx: %d, secondIdx: %d, attackerSrvId: %d, defenerSrvId: %d, attackerUuid: %s, defenerUuid: %s, err: %s",
|
|
|
+ firstIdx, secondIdx, args.attackerServerId, args.defenerServerId, args.attackerUuid, args.defenerUuid, err)
|
|
|
+ writeLog(str)
|
|
|
+ end
|
|
|
+
|
|
|
+ elseif attackerInfo or defenerInfo then
|
|
|
+ -- 有一方战斗数据异常, 则跳过战斗,有战斗数据的一方胜利
|
|
|
+ local errPlayerIdx = 1
|
|
|
+ if attackerInfo then
|
|
|
+ args.isWin = 1
|
|
|
+ args.attackerServerId = attackerInfo.serverId
|
|
|
+ args.attackerUuid = attackerInfo.playerUuid
|
|
|
+
|
|
|
+ local srvId, playerUuid = getBattleObjInfo(firstIdx, secondIdx, 2)
|
|
|
+ args.defenerServerId = srvId
|
|
|
+ args.defenerUuid = playerUuid
|
|
|
+
|
|
|
+ errPlayerIdx = 2
|
|
|
+ else
|
|
|
+ local srvId, playerUuid = getBattleObjInfo(firstIdx, secondIdx, 1)
|
|
|
+ args.attackerServerId = srvId
|
|
|
+ args.attackerUuid = playerUuid
|
|
|
+
|
|
|
+ args.isWin = 0
|
|
|
+ args.defenerServerId = defenerInfo.serverId
|
|
|
+ args.defenerUuid = defenerInfo.playerUuid
|
|
|
+ end
|
|
|
+
|
|
|
+ updateDBBattleResult(args)
|
|
|
+
|
|
|
+ local str = string.format("BattleDataERR,Err Identity: %d, firstIdx: %d, secondIdx: %d", errPlayerIdx, firstIdx, secondIdx)
|
|
|
+ writeLog(str)
|
|
|
+ end
|
|
|
+ end
|
|
|
+ end
|
|
|
+
|
|
|
+ AreaBattleDB.UpdateState(AreaBattleDefine.STATE_AWARD)
|
|
|
+
|
|
|
+ battleDataCache = {}
|
|
|
+end
|
|
|
+
|
|
|
+-- 外部调用
|
|
|
+-- 收到玩家的战斗数据后, 进行缓存
|
|
|
+function BattleDataHanle(msg)
|
|
|
+ if msg.errCode == 1 then
|
|
|
+ local extraArgs = msg.extraArgs
|
|
|
+ local firstIdx = extraArgs.firstIdx
|
|
|
+ local secondIdx = extraArgs.secondIdx
|
|
|
+ local identity = extraArgs.identity
|
|
|
+
|
|
|
+ battleDataCache[firstIdx] = battleDataCache[firstIdx] or {}
|
|
|
+ battleDataCache[firstIdx][secondIdx] = battleDataCache[firstIdx][secondIdx] or {}
|
|
|
+ local targetTb = battleDataCache[firstIdx][secondIdx]
|
|
|
+
|
|
|
+
|
|
|
+ local playerBattleData = nil
|
|
|
+ if identity == 1 then
|
|
|
+ if not targetTb.attackerInfo then
|
|
|
+ targetTb.attackerInfo = {}
|
|
|
+ playerBattleData = targetTb.attackerInfo
|
|
|
+ end
|
|
|
+ end
|
|
|
+
|
|
|
+ if identity == 2 then
|
|
|
+ if not targetTb.defenerInfo then
|
|
|
+ targetTb.defenerInfo = {}
|
|
|
+ playerBattleData = targetTb.defenerInfo
|
|
|
+ end
|
|
|
+ end
|
|
|
+
|
|
|
+ if playerBattleData then
|
|
|
+ -- playerBattleData.errCode = errCode
|
|
|
+ playerBattleData.serverId = extraArgs.serverId
|
|
|
+ playerBattleData.playerUuid = extraArgs.playerUuid
|
|
|
+ playerBattleData.battleData = {
|
|
|
+ objList = msg.objList,
|
|
|
+ helpList = msg.helpList,
|
|
|
+ roleBase = msg.roleBase,
|
|
|
+ formation = msg.formation,
|
|
|
+ jiBan = msg.jiBan,
|
|
|
+ elfList = msg.elfList,
|
|
|
+ }
|
|
|
+ end
|
|
|
+ end
|
|
|
+
|
|
|
+ -- 开始进入战斗
|
|
|
+ -- StartBattle()
|
|
|
+end
|
|
|
+
|
|
|
+-- 外部调用, 来自本模块的战斗结束后的回调函数
|
|
|
+function FightEnd(result, combatType, combatInfo, extraArgs)
|
|
|
+ if result == CombatDefine.RESULT_WIN then
|
|
|
+ extraArgs.isWin = 1
|
|
|
+ end
|
|
|
+
|
|
|
+ updateDBBattleResult(extraArgs)
|
|
|
+
|
|
|
+ combatInfo.time = os.time()
|
|
|
+ CombatVideo.SaveCombatVideo(CombatVideo.VIDEOTYPE_AREABATTLE, combatInfo, extraArgs.videoSecondIdx)
|
|
|
+end
|