AreaBattleCS.lua 25 KB

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