AreaBattleCS.lua 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925
  1. -- 战区争霸(跨服)
  2. local InnerMsg = require("core.InnerMsg")
  3. local Log = require("common.Log")
  4. local Timer = require("core.Timer")
  5. local Util = require("common.Util")
  6. local MiddleManager = require("middle.MiddleManager")
  7. local AreaBattleDB = require("areaBattle.AreaBattleDB")
  8. local AreaBattleDefine = require("areaBattle.AreaBattleDefine")
  9. local CombatVideo = require("combat.CombatVideo")
  10. local CombatDefine = require("combat.CombatDefine")
  11. local CombatLogicCS = require("combat.CombatLogicCS")
  12. local BattleDataCS = require("battleDataManager.BattleDataCS")
  13. -- 当天处于星期几(星期六为7, 星期天为1)
  14. local wDay
  15. -- 玩家战斗数据缓存表
  16. local battleDataCache = {}
  17. -- 请求序列表, 用于向普通获取玩家战斗数据
  18. local requestArr = {}
  19. local function updateWDay()
  20. wDay = Util.getWeekDay()
  21. end
  22. local function getTodayStartTime()
  23. local now = os.time()
  24. return Util.getDayStartTime(now)
  25. end
  26. local function isOpen()
  27. if not wDay then
  28. updateWDay()
  29. end
  30. if not table.find(AreaBattleDefine.OPEN_WDAY_AREA, wDay) then
  31. return false
  32. end
  33. local now = os.time()
  34. local toDayStartTime = getTodayStartTime()
  35. if wDay == AreaBattleDefine.OPEN_WDAY_AREA[1] and now < (toDayStartTime + AreaBattleDefine.PREPARE_STATE_START_SEC) then
  36. return false
  37. end
  38. if wDay == AreaBattleDefine.OPEN_WDAY_AREA[2] and now > (toDayStartTime + AreaBattleDefine.END_STATE_START_SEC) then
  39. return false
  40. end
  41. return true
  42. end
  43. -- 参战服务器日志格式: "serverId1, serverId2,serverId3"
  44. -- 服务器匹配列表日志格式: "serverId1-serverId2-serverId3-serverId4", 从一个serverId开始, 按顺序每两个serverId匹配到一起战斗
  45. -- 参战服务器信息日志个数: serverId | 本服战胜次数| 本服战败次数 | 战胜玩家uuid-战胜玩家uui
  46. local function writeLog(logStr)
  47. Log.write(Log.LOGID_OSS_AREABATTLE_BATTLE, logStr)
  48. end
  49. -- 计算一个服的总战力
  50. local function calcSrvPower(playerArray)
  51. local power = 0
  52. for _, v in ipairs(playerArray or {}) do
  53. power = power + (v.power or 0)
  54. end
  55. return power
  56. end
  57. -- 获取战斗对象的区服Id, uuid
  58. local function getBattleObjInfo(matchIdx, battleIdx, objIdentity)
  59. local matchSrvArr = AreaBattleDB.GetMatchSrvArr()
  60. local matchData = matchSrvArr[matchIdx]
  61. if not matchData then
  62. return
  63. end
  64. local targetSrvId = matchData[objIdentity]
  65. if not targetSrvId then
  66. return
  67. end
  68. local serverList = AreaBattleDB.GetServerList()
  69. if not serverList[targetSrvId] then
  70. return
  71. end
  72. local srvPlayerArr = serverList[targetSrvId].playerInfoArr
  73. local playerInfo = srvPlayerArr[battleIdx]
  74. return targetSrvId, playerInfo and playerInfo.uuid
  75. end
  76. -- 进入新一轮的处理
  77. local function newRoundHandle()
  78. local stateDB = AreaBattleDB.GetState()
  79. -- 上一轮奖励没有发放, 在新一轮开始时, 先发奖
  80. if stateDB == AreaBattleDefine.STATE_AWARD then
  81. AwardPrizesHandle()
  82. end
  83. -- 清除录像数据
  84. CombatVideo.ClearOutVideoByCombatType(CombatVideo.VIDEOTYPE_AREABATTLE)
  85. -- 重置录像缓存
  86. AreaBattleDB.ResetVideoShowCache()
  87. -- 重置战区争霸数据
  88. AreaBattleDB.ResetData()
  89. -- 更新状态
  90. AreaBattleDB.UpdateState(AreaBattleDefine.STATE_PREPARE)
  91. -- 通知普通服
  92. NotifySrvJoin()
  93. -- 重置缓存数据
  94. battleDataCache = {}
  95. requestArr = {}
  96. end
  97. -- 服务器分组算法
  98. local function matchAlgorithm(serverArr, len)
  99. local usedTb = {}
  100. local pairTb = {}
  101. local function getNextUnuseIdx(nowIdx)
  102. for i=nowIdx, len do
  103. if not usedTb[i] then
  104. return i
  105. end
  106. end
  107. end
  108. local function checkRandIdx(startIdx, endIdx)
  109. local tbl= {}
  110. for i= startIdx, endIdx do
  111. if i <= len and not usedTb[i] then
  112. table.insert(tbl, i)
  113. end
  114. end
  115. return tbl
  116. end
  117. local currentIdx = 1
  118. while currentIdx <= len do
  119. currentIdx = getNextUnuseIdx(currentIdx)
  120. if not currentIdx then
  121. break
  122. end
  123. local startIdx = currentIdx+1
  124. local endIdx = currentIdx+3
  125. local correctTb = checkRandIdx(startIdx, endIdx)
  126. local matchIdx = correctTb[math.random(1, #correctTb)]
  127. usedTb[currentIdx] = true
  128. usedTb[matchIdx] = true
  129. table.insert(pairTb, {serverArr[currentIdx], serverArr[matchIdx]})
  130. currentIdx = currentIdx + 1
  131. end
  132. return pairTb
  133. end
  134. -- 生成匹配列表
  135. local function genMacthArr()
  136. local joinSrvArr = AreaBattleDB.GetJoinSrvArr()
  137. local joinSrvArr_cp = Util.copyTable(joinSrvArr)
  138. if not joinSrvArr_cp or #joinSrvArr_cp <= 0 then
  139. return
  140. end
  141. local srvCnt = #joinSrvArr_cp
  142. if srvCnt > 1 then
  143. if srvCnt % 2 ~= 0 then
  144. local deleteSrvId = joinSrvArr_cp[srvCnt]
  145. joinSrvArr_cp[srvCnt] = nil
  146. srvCnt = srvCnt - 1
  147. -- 把被移除的服务器从服务器数据列表中移除
  148. local serverList = AreaBattleDB.GetServerList()
  149. serverList[deleteSrvId] = nil
  150. AreaBattleDB.UpdateServerList(serverList)
  151. -- 记录日志
  152. local logStr = "移除多余的区服, 区服Id: " .. deleteSrvId
  153. writeLog(logStr)
  154. end
  155. table.sort(joinSrvArr_cp)
  156. local matchArr = matchAlgorithm(joinSrvArr_cp, srvCnt)
  157. AreaBattleDB.UpdateMatchSrvArr(matchArr)
  158. end
  159. end
  160. -- 获取玩家的战斗数据
  161. local function getPlayerBattleData(serverId, playerUuid, extraArgs)
  162. extraArgs.serverId = serverId
  163. extraArgs.playerUuid = playerUuid
  164. BattleDataCS.GetPlayerCombatData(serverId, playerUuid, BattleDataCS.AREABTTLE_TAG, CombatDefine.COMBAT_TYPE33, extraArgs)
  165. end
  166. -- 分批请求玩家战斗数据
  167. function Timed_GetPlayerBattleData()
  168. if not requestArr or not next(requestArr) then
  169. return
  170. end
  171. local maxNum = math.min(#requestArr, AreaBattleDefine.GET_BATTLE_MAX_CNT_TIMES)
  172. for i=1, maxNum do
  173. local info = table.remove(requestArr)
  174. getPlayerBattleData(info[1], info[2], info[3])
  175. end
  176. if #requestArr > 0 then
  177. Timer.addLater(2, Timed_GetPlayerBattleData, requestArr)
  178. end
  179. end
  180. -- 向普通服请求战斗数据
  181. local function requestPlayerBattleData()
  182. local matchSrvArr = AreaBattleDB.GetMatchSrvArr()
  183. local serverList = AreaBattleDB.GetServerList()
  184. if not matchSrvArr or #matchSrvArr == 0 or not next(serverList) then
  185. return
  186. end
  187. for idx, matchSrvTb in ipairs(matchSrvArr) do
  188. local serverId1 = matchSrvTb[1]
  189. local serverId2 = matchSrvTb[2]
  190. local playerArr1 = serverList[serverId1] and serverList[serverId1].playerInfoArr or {}
  191. local playerArr2 = serverList[serverId2] and serverList[serverId2].playerInfoArr or {}
  192. local maxPlayerCnt = math.max(#playerArr1, #playerArr2)
  193. for i=1, maxPlayerCnt do
  194. local playerUuid1 = playerArr1[i] and playerArr1[i].uuid
  195. local playerUuid2 = playerArr2[i] and playerArr2[i].uuid
  196. if playerUuid1 then
  197. local args = {
  198. firstIdx = idx,
  199. secondIdx = i,
  200. identity = 1, --身份,1-进攻方, 2-防御方
  201. serverId = 0,
  202. playerUuid = "",
  203. }
  204. -- getPlayerBattleData(serverId1, playerUuid1, args)
  205. requestArr[#requestArr+1] = {serverId1, playerUuid1, args}
  206. end
  207. if playerUuid2 then
  208. local args = {
  209. firstIdx = idx,
  210. secondIdx = i,
  211. identity = 2, --身份,1-进攻方, 2-防御方
  212. serverId = 0,
  213. playerUuid = "",
  214. }
  215. -- getPlayerBattleData(serverId2, playerUuid2, args)
  216. requestArr[#requestArr+1] = {serverId2, playerUuid2, args}
  217. end
  218. end
  219. end
  220. local now = os.time()
  221. AreaBattleDB.UpdateUpLoadStartTi(now)
  222. Timed_GetPlayerBattleData()
  223. end
  224. -- 处于准备阶段处理, 给服务器进行匹配, 并通知普通服上传玩家战斗数据
  225. local function prepareHandle()
  226. local stateDB = AreaBattleDB.GetState()
  227. if stateDB ~= AreaBattleDefine.STATE_PREPARE then
  228. return
  229. end
  230. -- 服务器进行匹配
  231. genMacthArr()
  232. -- 让普通服上传战斗数据
  233. -- requestPlayerBattleData()
  234. end
  235. -- 上一轮 ~ 新一轮准备阶段的处理
  236. local function earlyHanle()
  237. local now = os.time()
  238. local stateDB = AreaBattleDB.GetState()
  239. local nowRoundStartTi = AreaBattleDB.GetNowRoundStartTi()
  240. local diffDays = Util.diffDay(nowRoundStartTi)
  241. -- 开启新一轮活动
  242. if nowRoundStartTi <= 0 or diffDays >= 2 then
  243. return newRoundHandle()
  244. end
  245. -- 处于准备阶段, 普通服上传完本服排名前15的玩家数据后,如果还没有对服务器进行分组, 则生成服务器匹配列表, 并通知这些服务器上传本服玩家战斗数据
  246. if diffDays < 2 and now - nowRoundStartTi >= AreaBattleDefine.SERVER_DATA_TIME and stateDB == AreaBattleDefine.STATE_PREPARE then
  247. local matchSrvArr = AreaBattleDB.GetMatchSrvArr()
  248. if not matchSrvArr or not next(matchSrvArr) then
  249. prepareHandle()
  250. end
  251. end
  252. end
  253. -- 进入战斗阶段的处理
  254. local function BattleStageHandle()
  255. local stateDB = AreaBattleDB.GetState()
  256. if stateDB ~= AreaBattleDefine.STATE_BATTLE then
  257. return
  258. end
  259. StartBattle()
  260. end
  261. -- 战斗结束, 把结果更新到DB
  262. local function updateDBBattleResult(battleInfo)
  263. local attackerServerId = battleInfo.attackerServerId
  264. local attackerUuid = battleInfo.attackerUuid
  265. local defenerServerId = battleInfo.defenerServerId
  266. local defenerUuid = battleInfo.defenerUuid
  267. local isWin = battleInfo.isWin
  268. local serverList = AreaBattleDB.GetServerList()
  269. local attackerSrvData = serverList[attackerServerId]
  270. if attackerSrvData then
  271. if isWin == 1 then
  272. attackerSrvData.winTimes = (attackerSrvData.winTimes or 0) + 1
  273. attackerSrvData.winPlayerArr = attackerSrvData.winPlayerArr or {}
  274. table.insert(attackerSrvData.winPlayerArr, attackerUuid)
  275. else
  276. attackerSrvData.defeatTimes = (attackerSrvData.defeatTimes or 0) + 1
  277. end
  278. end
  279. local defenerSrvData = serverList[defenerServerId]
  280. if defenerSrvData then
  281. if isWin == 0 then
  282. defenerSrvData.winTimes = (defenerSrvData.winTimes or 0) + 1
  283. defenerSrvData.winPlayerArr = defenerSrvData.winPlayerArr or {}
  284. table.insert(defenerSrvData.winPlayerArr, defenerUuid)
  285. else
  286. defenerSrvData.defeatTimes = (defenerSrvData.defeatTimes or 0) + 1
  287. end
  288. end
  289. AreaBattleDB.UpdateServerList(serverList)
  290. end
  291. -- 生成用于通知各个普通服发奖的数据
  292. local function genNotifyInfo(serverInfo)
  293. local info = {
  294. isWin = 0,
  295. winPlayerArr = {},
  296. defeatPlayerArr = {}
  297. }
  298. if (serverInfo.winTimes or 0) > (serverInfo.defeatTimes or 0) then
  299. info.isWin = 1
  300. end
  301. for _, playerInfo in ipairs(serverInfo.playerInfoArr) do
  302. if table.find(serverInfo.winPlayerArr, playerInfo.uuid) then
  303. table.insert(info.winPlayerArr, playerInfo.uuid)
  304. else
  305. table.insert(info.defeatPlayerArr, playerInfo.uuid)
  306. end
  307. end
  308. return info
  309. end
  310. -- 生成日志
  311. local function genLog()
  312. local t1, t2 = {}, {}
  313. local joinSrvArr = AreaBattleDB.GetJoinSrvArr()
  314. for idx, srvId in ipairs(joinSrvArr or {}) do
  315. t1[idx] = srvId
  316. end
  317. local str1 = table.concat(t1, ",")
  318. writeLog(str1)
  319. local len = 0
  320. local matchSrvArr = AreaBattleDB.GetMatchSrvArr()
  321. for _, srvTb in ipairs(matchSrvArr or {}) do
  322. for _, servrId in ipairs(srvTb) do
  323. len = len + 1
  324. t2[len] = servrId
  325. end
  326. end
  327. local str2 = table.concat(t2, "-")
  328. writeLog(str2)
  329. local serverList = AreaBattleDB.GetServerList()
  330. for serverId, srvInfo in pairs(serverList or {}) do
  331. local t = {serverId, srvInfo.winTimes or 0, srvInfo.defeatTimes or 0}
  332. if srvInfo.winPlayerArr and #srvInfo.winPlayerArr > 0 then
  333. local s = table.concat(Util.copyTable(srvInfo.winPlayerArr), "-")
  334. table.insert(t, s)
  335. end
  336. local str3 = table.concat(t, "|")
  337. writeLog(str3)
  338. end
  339. end
  340. -------------------------------------------C2N-------------------------------------------
  341. -- 通知普通服,争霸开始
  342. function NotifySrvJoin()
  343. local msgData = InnerMsg.wl.WL_AREABATTLE_OPEN
  344. local fdList = MiddleManager.MiddleManager_GetAllFD()
  345. for _, fd in pairs(fdList) do
  346. InnerMsg.sendMsg(fd, msgData)
  347. end
  348. end
  349. -- 通知普通服发奖
  350. function NotifySrvAwardPrizes(fd, args)
  351. local msgData = InnerMsg.wl.WL_AREABATTLE_SEND_REWARD
  352. msgData.srvBattleRes = args
  353. InnerMsg.sendMsg(fd, msgData)
  354. end
  355. -------------------------------------------N2C-----------------------------------------------
  356. -- 普通服加入战斗
  357. function N2C_JoinBattle(msg)
  358. local sourceServerId = msg.sourceServerId
  359. local joinBattleArray = msg.joinBattleArray
  360. local joinSrvArr = AreaBattleDB.GetJoinSrvArr()
  361. local serverList = AreaBattleDB.GetServerList()
  362. if not table.find(joinSrvArr, sourceServerId) and not serverList[sourceServerId] then
  363. -- 参战列表
  364. table.insert(joinSrvArr, sourceServerId)
  365. AreaBattleDB.UpdateJoinSrvArr(joinSrvArr)
  366. -- 服务器列表
  367. serverList[sourceServerId] = {
  368. winTimes = 0,
  369. defeatTimes = 0,
  370. winPlayerArr = {},
  371. playerInfoArr = joinBattleArray
  372. }
  373. AreaBattleDB.UpdateServerList(serverList)
  374. end
  375. end
  376. -- 普通服请求争霸活动的基本数据
  377. function N2C_GetBaseInfo(msg)
  378. local fd = MiddleManager.getFDBySvrIndex(msg.sourceServerId)
  379. local msgData = InnerMsg.wl.WL_AREABATTLE_BASEINFO_QUERY
  380. msgData.playerUuid = msg.playerUuid
  381. local state = AreaBattleDB.GetState()
  382. msgData.stage = state
  383. msgData.startTime, msgData.endTime = 0, 0
  384. local toDayStartTime = getTodayStartTime()
  385. if not wDay then
  386. updateWDay()
  387. end
  388. if wDay == AreaBattleDefine.OPEN_WDAY_AREA[1] then
  389. msgData.startTime = toDayStartTime + AreaBattleDefine.PREPARE_STATE_START_SEC
  390. msgData.endTime = toDayStartTime + 86400 + AreaBattleDefine.END_STATE_START_SEC
  391. elseif wDay == AreaBattleDefine.OPEN_WDAY_AREA[2] then
  392. msgData.startTime = toDayStartTime - 86400 + AreaBattleDefine.PREPARE_STATE_START_SEC
  393. msgData.endTime = toDayStartTime + AreaBattleDefine.END_STATE_START_SEC
  394. local now = os.time()
  395. if state == AreaBattleDefine.STATE_AWARD and now < toDayStartTime + AreaBattleDefine.END_STATE_START_SEC then
  396. msgData.stage = AreaBattleDefine.STATE_BATTLE
  397. end
  398. else
  399. local subDay = AreaBattleDefine.OPEN_WDAY_AREA[1] - wDay
  400. msgData.startTime = toDayStartTime + subDay * 86400 + AreaBattleDefine.PREPARE_STATE_START_SEC
  401. msgData.endTime = toDayStartTime + (subDay + 1) * 86400 + AreaBattleDefine.END_STATE_START_SEC
  402. end
  403. InnerMsg.sendMsg(fd, msgData)
  404. end
  405. -- 普通服请求本服参战玩家列表
  406. function N2C_GetJoinPlayerArr(msg)
  407. local sourceServerId = msg.sourceServerId
  408. local fd = MiddleManager.getFDBySvrIndex(sourceServerId)
  409. local msgData = InnerMsg.wl.WL_AREABATTLE_JOINPLAYER_QUERY
  410. msgData.errCode = 0
  411. msgData.playerArray = {}
  412. msgData.playerUuid = msg.playerUuid
  413. local joinSrvArr = AreaBattleDB.GetJoinSrvArr()
  414. local mathcList = AreaBattleDB.GetMatchSrvArr()
  415. -- 没有参加
  416. if not joinSrvArr or not table.find(joinSrvArr, sourceServerId) then
  417. msgData.errCode = -1
  418. return InnerMsg.sendMsg(fd, msgData)
  419. end
  420. -- 匹配列表还没生成
  421. if not mathcList or not next(mathcList) then
  422. msgData.errCode = -2
  423. return InnerMsg.sendMsg(fd, msgData)
  424. end
  425. local isInMathcArr = false
  426. for _, matchSrvTb in ipairs(mathcList) do
  427. if table.find(matchSrvTb, sourceServerId) then
  428. isInMathcArr = true
  429. break
  430. end
  431. end
  432. -- 参加了,但是被移除, 没有在本轮匹配列表中
  433. if not isInMathcArr then
  434. msgData.errCode = -3
  435. return InnerMsg.sendMsg(fd, msgData)
  436. end
  437. local serverList = AreaBattleDB.GetServerList()
  438. msgData.playerArray = serverList[sourceServerId] and serverList[sourceServerId].playerInfoArr or {}
  439. InnerMsg.sendMsg(fd, msgData)
  440. end
  441. -- 普通服请求本次参战的区服的匹配列表
  442. -- { { {server1, power1}, {server2, power2} }, }
  443. function N2C_GetMatchList(msg)
  444. local sourceServerId = msg.sourceServerId
  445. local fd = MiddleManager.getFDBySvrIndex(sourceServerId)
  446. local msgData = InnerMsg.wl.WL_AREABATTLE_MATCHLIST_QUERY
  447. msgData.playerUuid = msg.playerUuid
  448. msgData.matchList = {}
  449. local mathcList = AreaBattleDB.GetMatchSrvArr()
  450. local serverList = AreaBattleDB.GetServerList()
  451. for k, matchSrvTb in ipairs(mathcList) do
  452. msgData.matchList[k] = {}
  453. for idx, serverId in ipairs(matchSrvTb) do
  454. if serverList[serverId] then
  455. -- table.insert(msgData.matchList[k], serverId)
  456. local power = calcSrvPower(serverList[serverId].playerInfoArr)
  457. -- table.insert(msgData.matchList[k], power)
  458. msgData.matchList[k][idx] = {serverId, power}
  459. end
  460. end
  461. end
  462. InnerMsg.sendMsg(fd, msgData)
  463. end
  464. -- 普通服请求本服的战斗录像展示数据
  465. function N2C_GetVideoShowData(msg)
  466. local sourceServerId = msg.sourceServerId
  467. local fd = MiddleManager.getFDBySvrIndex(sourceServerId)
  468. local msgData = InnerMsg.wl.WL_AREABATTLE_VIDEOSHOW_QUERY
  469. msgData.errCode = 0
  470. msgData.playerUuid = msg.playerUuid
  471. msgData.videoShowData = {}
  472. msgData.srvInfo = {}
  473. local state = AreaBattleDB.GetState()
  474. if state ~= AreaBattleDefine.STATE_AWARD and state ~= AreaBattleDefine.STATE_END then
  475. msgData.errCode = -1
  476. return InnerMsg.sendMsg(fd, msgData)
  477. end
  478. local videoSecondIdx, leftSrvId, rightSrvId = 0, 0, 0
  479. local matchSrvArr = AreaBattleDB.GetMatchSrvArr()
  480. for k, srvTb in ipairs(matchSrvArr or {}) do
  481. if table.find(srvTb, sourceServerId) then
  482. videoSecondIdx = k
  483. leftSrvId = srvTb[1]
  484. rightSrvId = srvTb[2]
  485. break
  486. end
  487. end
  488. -- 本轮没有参加活动
  489. if videoSecondIdx == 0 then
  490. msgData.errCode = -3
  491. return InnerMsg.sendMsg(fd, msgData)
  492. end
  493. local serverList = AreaBattleDB.GetServerList()
  494. if serverList[leftSrvId] then
  495. msgData.srvInfo.leftSrvId = leftSrvId
  496. msgData.srvInfo.leftWinTimes = serverList[leftSrvId].winTimes or 0
  497. msgData.srvInfo.leftSrvPower = calcSrvPower(serverList[leftSrvId].playerInfoArr)
  498. end
  499. if serverList[rightSrvId] then
  500. msgData.srvInfo.rightSrvId = rightSrvId
  501. msgData.srvInfo.rightWinTimes = serverList[rightSrvId].winTimes or 0
  502. msgData.srvInfo.rightSrvPower = calcSrvPower(serverList[rightSrvId].playerInfoArr)
  503. end
  504. local videoArr = AreaBattleDB.GetSrvVideoShowData(videoSecondIdx)
  505. -- msgData.videoShowData = videoArr
  506. for _, v in ipairs(videoArr) do
  507. if (v.atkData and v.atkData.uuid == msg.playerUuid) or (v.defenerData and v.defenerData.uuid == msg.playerUuid) then
  508. table.insert(msgData.videoShowData, 1, v)
  509. else
  510. msgData.videoShowData[#msgData.videoShowData+1] = v
  511. end
  512. end
  513. InnerMsg.sendMsg(fd, msgData)
  514. end
  515. ---------------------------------------------------------------------------------------------
  516. function oneMin()
  517. if _G.is_middle ~= true then return end
  518. if not isOpen() then
  519. return
  520. end
  521. -- 与 onHour() 处理错开
  522. if Util.getMin() == 0 then
  523. return
  524. end
  525. local now = os.time()
  526. local toDayStartTime = getTodayStartTime()
  527. -- 活动第一天, 当前时间 >= 开启时间
  528. if wDay == AreaBattleDefine.OPEN_WDAY_AREA[1] then
  529. earlyHanle()
  530. end
  531. -- 活动最后一天, 当前时间 < 活动结束时间
  532. if wDay == AreaBattleDefine.OPEN_WDAY_AREA[2] then
  533. earlyHanle()
  534. local stateDB = AreaBattleDB.GetState()
  535. -- local nowRoundStartTi = AreaBattleDB.GetNowRoundStartTi()
  536. -- 当前处于准备阶段, 但是当前时间 >= 对战开始时间, 则进入对战阶段
  537. if now >= (toDayStartTime + AreaBattleDefine.BATTLE_STATE_START_SEC) and stateDB == AreaBattleDefine.STATE_PREPARE then
  538. -- 防止某些情况下,进入准备阶段后普通服数据还没上传完就进入对战阶段
  539. local upLoadStartTi = AreaBattleDB.GetUpLoadStartTi()
  540. if now - upLoadStartTi > AreaBattleDefine.BATTLE_DATA_TIME then
  541. -- 重启跨服后导致战斗数据缓存没了,则重新获取。 -- 新逻辑: 每次进入战斗阶段时才让普通服上传玩家战斗数据
  542. if not next(battleDataCache) then
  543. if #requestArr == 0 then
  544. return requestPlayerBattleData()
  545. end
  546. end
  547. -- 处于请求战斗数据过程中, 等请求完再进入战斗
  548. if #requestArr > 0 then
  549. return
  550. end
  551. AreaBattleDB.UpdateState(AreaBattleDefine.STATE_BATTLE)
  552. BattleStageHandle()
  553. return
  554. end
  555. end
  556. -- 当前时间 >= 发奖时间
  557. if now >= (toDayStartTime + AreaBattleDefine.END_STATE_START_SEC) and stateDB == AreaBattleDefine.STATE_AWARD then
  558. AwardPrizesHandle()
  559. AreaBattleDB.UpdateState(AreaBattleDefine.STATE_END)
  560. end
  561. end
  562. end
  563. function onHour(hour)
  564. if _G.is_middle ~= true then return end
  565. if hour == 0 or not wDay then
  566. updateWDay()
  567. end
  568. if not table.find(AreaBattleDefine.OPEN_WDAY_AREA, wDay) then
  569. return
  570. end
  571. -- 对战阶段
  572. if wDay == AreaBattleDefine.OPEN_WDAY_AREA[2] and hour >= 12 then
  573. local now = os.time()
  574. local stateDB = AreaBattleDB.GetState()
  575. -- local nowRoundStartTi = AreaBattleDB.GetNowRoundStartTi()
  576. local upLoadStartTi = AreaBattleDB.GetUpLoadStartTi()
  577. -- 防止某些情况下,进入准备阶段后,普通服数据还没上传完就进入对战阶段
  578. if stateDB == AreaBattleDefine.STATE_PREPARE and (now - upLoadStartTi > AreaBattleDefine.BATTLE_DATA_TIME) then
  579. -- 重启跨服后导致战斗数据缓存没了,则重新获取。-- 新逻辑: 每次进入战斗阶段时才让普通服上传玩家战斗数据
  580. if not next(battleDataCache) then
  581. -- 可能存在响应比较慢的情况,保证只执行一次 requestPlayerBattleData
  582. if #requestArr == 0 then
  583. return requestPlayerBattleData()
  584. end
  585. end
  586. -- 处于请求战斗数据过程中, 等请求完再进入战斗
  587. if #requestArr > 0 then
  588. return
  589. end
  590. AreaBattleDB.UpdateState(AreaBattleDefine.STATE_BATTLE)
  591. BattleStageHandle()
  592. end
  593. end
  594. -- 发奖阶段
  595. if wDay == AreaBattleDefine.OPEN_WDAY_AREA[2] and hour >= 22 then
  596. local stateDB = AreaBattleDB.GetState()
  597. if stateDB == AreaBattleDefine.STATE_AWARD then
  598. AwardPrizesHandle()
  599. AreaBattleDB.UpdateState(AreaBattleDefine.STATE_END)
  600. end
  601. end
  602. end
  603. -- 通知普通服发奖
  604. function BrocastServer(srvTb)
  605. for fd, notifyInfo in pairs(srvTb) do
  606. NotifySrvAwardPrizes(fd, notifyInfo)
  607. end
  608. end
  609. -- 分批次通知普通服
  610. function BatchServer()
  611. local matchSrvArr = AreaBattleDB.GetMatchSrvArr()
  612. if not matchSrvArr or not next(matchSrvArr) then
  613. return
  614. end
  615. local len, delay_sec = 0, 0
  616. local srvTb = {}
  617. local serverList = AreaBattleDB.GetServerList()
  618. for serverId, serverInfo in pairs(serverList or {}) do
  619. local fd = MiddleManager.getFDBySvrIndex(serverId)
  620. if fd then
  621. len = len + 1
  622. local notifyInfo = genNotifyInfo(serverInfo)
  623. srvTb[fd] = notifyInfo
  624. end
  625. if len >= AreaBattleDefine.BATCH_MAX_SRV_NUM then
  626. delay_sec = delay_sec + 5
  627. Timer.addLater(delay_sec, BrocastServer, srvTb)
  628. srvTb = {}
  629. len = 0
  630. end
  631. end
  632. if len > 0 then
  633. delay_sec = delay_sec + 5
  634. Timer.addLater(delay_sec, BrocastServer, srvTb)
  635. end
  636. end
  637. -- 发奖
  638. function AwardPrizesHandle()
  639. genLog()
  640. BatchServer()
  641. end
  642. -- 开始战斗
  643. function StartBattle()
  644. for firstIdx, battleDList in pairs(battleDataCache) do
  645. for secondIdx, playerBattleData in pairs(battleDList) do
  646. local attackerInfo = playerBattleData.attackerInfo
  647. local defenerInfo = playerBattleData.defenerInfo
  648. local args = {
  649. isWin = 0,
  650. attackerServerId = "",
  651. attackerUuid = "",
  652. defenerServerId = "",
  653. defenerUuid = ""
  654. }
  655. if attackerInfo and defenerInfo then -- 正常情况
  656. args.attackerServerId = attackerInfo.serverId
  657. args.attackerUuid = attackerInfo.playerUuid
  658. args.defenerServerId = defenerInfo.serverId
  659. args.defenerUuid = defenerInfo.playerUuid
  660. args.videoSecondIdx = firstIdx
  661. -- CombatLogicCS.combatBegin(attackerInfo.battleData, defenerInfo.battleData, CombatDefine.COMBAT_TYPE33, FightEnd, args)
  662. local ok, err = pcall(CombatLogicCS.combatBegin, attackerInfo.battleData, defenerInfo.battleData, CombatDefine.COMBAT_TYPE33, FightEnd, args)
  663. if not ok then
  664. local str = string.format("BattleErr, firstIdx: %d, secondIdx: %d, attackerSrvId: %d, defenerSrvId: %d, attackerUuid: %s, defenerUuid: %s, err: %s",
  665. firstIdx, secondIdx, args.attackerServerId, args.defenerServerId, args.attackerUuid, args.defenerUuid, err)
  666. writeLog(str)
  667. end
  668. elseif attackerInfo or defenerInfo then
  669. -- 有一方战斗数据异常, 则跳过战斗,有战斗数据的一方胜利
  670. local errPlayerIdx = 1
  671. if attackerInfo then
  672. args.isWin = 1
  673. args.attackerServerId = attackerInfo.serverId
  674. args.attackerUuid = attackerInfo.playerUuid
  675. local srvId, playerUuid = getBattleObjInfo(firstIdx, secondIdx, 2)
  676. args.defenerServerId = srvId
  677. args.defenerUuid = playerUuid
  678. errPlayerIdx = 2
  679. else
  680. local srvId, playerUuid = getBattleObjInfo(firstIdx, secondIdx, 1)
  681. args.attackerServerId = srvId
  682. args.attackerUuid = playerUuid
  683. args.isWin = 0
  684. args.defenerServerId = defenerInfo.serverId
  685. args.defenerUuid = defenerInfo.playerUuid
  686. end
  687. updateDBBattleResult(args)
  688. local str = string.format("BattleDataERR,Err Identity: %d, firstIdx: %d, secondIdx: %d", errPlayerIdx, firstIdx, secondIdx)
  689. writeLog(str)
  690. end
  691. end
  692. end
  693. AreaBattleDB.UpdateState(AreaBattleDefine.STATE_AWARD)
  694. battleDataCache = {}
  695. end
  696. -- 外部调用
  697. -- 收到玩家的战斗数据后, 进行缓存
  698. function BattleDataHanle(msg)
  699. if msg.errCode == 1 then
  700. local extraArgs = msg.extraArgs
  701. local firstIdx = extraArgs.firstIdx
  702. local secondIdx = extraArgs.secondIdx
  703. local identity = extraArgs.identity
  704. battleDataCache[firstIdx] = battleDataCache[firstIdx] or {}
  705. battleDataCache[firstIdx][secondIdx] = battleDataCache[firstIdx][secondIdx] or {}
  706. local targetTb = battleDataCache[firstIdx][secondIdx]
  707. local playerBattleData = nil
  708. if identity == 1 then
  709. if not targetTb.attackerInfo then
  710. targetTb.attackerInfo = {}
  711. playerBattleData = targetTb.attackerInfo
  712. end
  713. end
  714. if identity == 2 then
  715. if not targetTb.defenerInfo then
  716. targetTb.defenerInfo = {}
  717. playerBattleData = targetTb.defenerInfo
  718. end
  719. end
  720. if playerBattleData then
  721. -- playerBattleData.errCode = errCode
  722. playerBattleData.serverId = extraArgs.serverId
  723. playerBattleData.playerUuid = extraArgs.playerUuid
  724. playerBattleData.battleData = {
  725. objList = msg.objList,
  726. helpList = msg.helpList,
  727. roleBase = msg.roleBase,
  728. formation = msg.formation,
  729. jiBan = msg.jiBan,
  730. elfList = msg.elfList,
  731. }
  732. end
  733. end
  734. -- 开始进入战斗
  735. -- StartBattle()
  736. end
  737. -- 外部调用, 来自本模块的战斗结束后的回调函数
  738. function FightEnd(result, combatType, combatInfo, extraArgs)
  739. if result == CombatDefine.RESULT_WIN then
  740. extraArgs.isWin = 1
  741. end
  742. updateDBBattleResult(extraArgs)
  743. combatInfo.time = os.time()
  744. CombatVideo.SaveCombatVideo(CombatVideo.VIDEOTYPE_AREABATTLE, combatInfo, extraArgs.videoSecondIdx)
  745. end