AreaBattleCS.lua 29 KB

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