ServerCommerceActBattleGroundCS.lua 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558
  1. -- 跨服商业活动-巅峰战场(跨服)
  2. local Msg = require("core.Msg")
  3. local Timer = require("core.Timer")
  4. local DB = require("common.DB")
  5. local CommonDB = require("common.CommonDB")
  6. local CommonDefine = require("common.CommonDefine")
  7. local Log = require("common.Log")
  8. local LuaMongo = _G.lua_mongo
  9. local Util = require("common.Util")
  10. local Grid = require("bag.Grid")
  11. local MiddleConnect = require("middle.MiddleConnect")
  12. local InnerMsg = require("core.InnerMsg")
  13. local MiddleManager = require("middle.MiddleManager")
  14. local NpcConfig = require("excel.jjc").skyladdernpc
  15. local CreateRole = require("role.CreateRole")
  16. local ServerCommerceActDefine = require("serverCommerce.ServerCommerceActDefine")
  17. local CombatDefine = require("combat.CombatDefine")
  18. local dbUpdate = {_id=nil}
  19. local dbUpdateField = {}
  20. local RANK_SHOW_NUM = 50 -- 排行榜显示的数量
  21. local repeateServerIdList = {}
  22. local battleGroundData = {
  23. -- allAreaRankList = { -- 各个战区排行榜, 榜上的都是真实玩家
  24. -- [WarZoneServerIdx] = {
  25. -- [rank] = {
  26. -- rank = rank,
  27. -- serverId = serverId,
  28. -- playerUuid = playerUuid,
  29. -- name = name,
  30. -- bodyId = bodyId,
  31. -- headId = headId,
  32. -- headFrameId = headFrameId,
  33. -- heroArr = {heroId1, heroId2},
  34. -- },
  35. -- },
  36. -- },
  37. -- generaRankList = { -- 通用排行榜(榜上都是机器人),各个战区排行榜上没有真实玩家或对应排名没有真实玩家时, 使用该排行榜
  38. -- [rank] = {
  39. -- rank = rank,
  40. -- serverId = serverId,
  41. -- playerUuid = playerUuid,
  42. -- name = name,
  43. -- bodyId = bodyId,
  44. -- headId = headId,
  45. -- headFrameId = headFrameId,
  46. -- monsterOutID = monsterOutID, -- 机器人才有
  47. -- heroArr = {heroId1, heroId2},
  48. -- },
  49. -- },
  50. -- },
  51. -- joinList = { -- 参加过该活动的玩家列表
  52. -- -- {serverId, playerUuid},
  53. -- -- {serverId2, playerUuid2},
  54. -- },
  55. }
  56. -- 生成一个排行榜列表
  57. local function genRankList(rankList)
  58. local function genPlayerData(player, tNpcConfig, rank)
  59. local r = math.random(1, #tNpcConfig.monsterOutID)
  60. player.rank = rank
  61. player.name = CreateRole.getRandomName()
  62. player.headId = CreateRole.getRandomHead()
  63. player.headFrameId = CreateRole.getRandomHeadFrame()
  64. player.bodyId = CreateRole.getRandomBody()
  65. player.playerUuid = tNpcConfig.monsterOutID[r]
  66. player.monsterOutID = tNpcConfig.monsterOutID[r]
  67. end
  68. local rank = 1
  69. for _, cfg in ipairs(NpcConfig) do
  70. for i = 1, cfg.cnt do
  71. rankList[rank] = {}
  72. genPlayerData(rankList[rank], cfg, rank)
  73. rank = rank + 1
  74. if rank > ServerCommerceActDefine.COMMERCEACT_NPC_CNT then
  75. break
  76. end
  77. end
  78. end
  79. end
  80. -- 插入数据
  81. local function insertData(data)
  82. LuaMongo.insert(DB.db_battleground, data)
  83. end
  84. -- 修改db单个字段
  85. local function updateValue(key, value)
  86. if not key then return end
  87. if value then
  88. dbUpdateField["$set"] = {[key]=value}
  89. dbUpdateField["$unset"] = nil
  90. else
  91. dbUpdateField["$set"] = nil
  92. dbUpdateField["$unset"] = {[key]=1}
  93. end
  94. dbUpdate._id = battleGroundData._id
  95. LuaMongo.update(DB.db_battleground, dbUpdate, dbUpdateField)
  96. end
  97. -- 保存所有数据
  98. local function saveAllData()
  99. dbUpdate._id = battleGroundData._id
  100. LuaMongo.update(DB.db_battleground, dbUpdate, battleGroundData)
  101. end
  102. local function loadData()
  103. LuaMongo.find(DB.db_battleground)
  104. local data = {}
  105. if LuaMongo.next(data) then
  106. battleGroundData = data
  107. end
  108. if battleGroundData.allAreaRankList and next(battleGroundData.allAreaRankList) then
  109. for areaIdx, rankList in pairs(battleGroundData.allAreaRankList) do
  110. battleGroundData.allAreaRankList[areaIdx] = {}
  111. for _, player in pairs(rankList) do
  112. battleGroundData.allAreaRankList[areaIdx][player.rank] = player
  113. end
  114. end
  115. end
  116. if not battleGroundData.generaRankList then
  117. battleGroundData.generaRankList = {}
  118. genRankList(battleGroundData.generaRankList)
  119. insertData(battleGroundData)
  120. end
  121. table.sort(battleGroundData.generaRankList, function (a, b)
  122. return a.rank < b.rank
  123. end)
  124. end
  125. function BattleGround_InitAfterStart()
  126. if _G.is_middle ~= true then
  127. return
  128. end
  129. loadData()
  130. end
  131. function onZero()
  132. if next(repeateServerIdList) then
  133. repeateServerIdList = {}
  134. end
  135. end
  136. -- 通过本服Id获取所在战区Id
  137. local function getWarZoneServerIdx(sourceServerId)
  138. local nServerKey = MiddleConnect.MiddleConnect_TrueServerID2ConfServerID(sourceServerId)
  139. nServerKey = MiddleConnect.MiddleConnect_GetWarZoneServer(nServerKey)
  140. return nServerKey
  141. end
  142. -- 通服务器Id获取所在战区Id的最小服务器Id,最大服务器Id
  143. local function getWarZoneServerArea(sourceServerId)
  144. local nServerKey = MiddleConnect.MiddleConnect_TrueServerID2ConfServerID(sourceServerId)
  145. return MiddleConnect.MiddleConnect_GetWarZoneServer(nServerKey)
  146. end
  147. -- 生成一个战区排行榜
  148. local function genWarZoneRankList(warZoneServerIdx)
  149. local isInsert = false
  150. if not next(battleGroundData) then
  151. isInsert = true
  152. end
  153. battleGroundData.allAreaRankList = battleGroundData.allAreaRankList or {}
  154. battleGroundData.allAreaRankList[warZoneServerIdx] = {}
  155. genRankList(battleGroundData.allAreaRankList[warZoneServerIdx])
  156. if isInsert then
  157. return insertData(battleGroundData)
  158. end
  159. updateValue("allAreaRankList".."."..warZoneServerIdx, battleGroundData.allAreaRankList[warZoneServerIdx])
  160. end
  161. -- 获取本服所在战区的排行榜
  162. local function getMyWarZoneRankList(sourceServerId)
  163. local warZoneServerIdx = getWarZoneServerIdx(sourceServerId)
  164. if not battleGroundData.allAreaRankList or not battleGroundData.allAreaRankList[warZoneServerIdx] then
  165. -- genWarZoneRankList(warZoneServerIdx)
  166. return
  167. end
  168. return battleGroundData.allAreaRankList[warZoneServerIdx]
  169. end
  170. -- 初始化本战区的排行榜
  171. local function initMyWarZoneRankList(sourceServerId)
  172. local warZoneServerIdx = getWarZoneServerIdx(sourceServerId)
  173. if not battleGroundData.allAreaRankList or not battleGroundData.allAreaRankList[warZoneServerIdx] then
  174. battleGroundData.allAreaRankList = battleGroundData.allAreaRankList or {}
  175. battleGroundData.allAreaRankList[warZoneServerIdx] = {}
  176. end
  177. end
  178. -- 获取通用排行榜
  179. local function getGeneraRankList()
  180. return battleGroundData.generaRankList
  181. end
  182. -- 通过玩家uuid获取排名
  183. local function getPlayerRankByUuid(rankList, targetPlayerUuid)
  184. local targetRank = ServerCommerceActDefine.COMMERCEACT_NPC_CNT + 1
  185. if not rankList then
  186. return targetRank
  187. end
  188. for rank, rankInfo in pairs(rankList) do
  189. if rankInfo.playerUuid == targetPlayerUuid then
  190. targetRank = rank
  191. break
  192. end
  193. end
  194. return targetRank
  195. end
  196. -- 遍历
  197. local function findVal(list, val)
  198. for k, info in pairs(list or {}) do
  199. if info[2] == val then
  200. return k
  201. end
  202. end
  203. end
  204. local function writeLog(logStr)
  205. Log.write(Log.LOGID_OSS_COMMON_ACT, logStr)
  206. end
  207. -- 发奖
  208. local function issueReward(fd, rankArr)
  209. local msgData = InnerMsg.wl.WL_BATTLEGROUND_NOTIFY_PRIZEAWARD
  210. msgData.playerArr = rankArr
  211. InnerMsg.sendMsg(fd, msgData)
  212. end
  213. -- 普通服请求玩家排名
  214. function BG_N2C_PlayerRank_Req(msg)
  215. local msgData = InnerMsg.wl.WL_BATTLEGROUND_PLAYER_RANK_QUERY
  216. msgData.playerRank = 0
  217. msgData.playerUuid = msg.playerUuid
  218. local myWarZoneRankList = getMyWarZoneRankList(msg.sourceServerId)
  219. msgData.playerRank = getPlayerRankByUuid(myWarZoneRankList, msg.playerUuid)
  220. local fd = MiddleManager.getFDBySvrIndex(msg.sourceServerId)
  221. InnerMsg.sendMsg(fd, msgData)
  222. end
  223. -- 普通服请求对手数据
  224. function BG_N2C_MatchList_Req(msg)
  225. local msgData = InnerMsg.wl.WL_BATTLEGROUND_MATCHLIST_QUERY
  226. msgData.playerUuid = msg.playerUuid
  227. msgData.playerInfoList = {}
  228. local myWarZoneRankList = getMyWarZoneRankList(msg.sourceServerId)
  229. local generaRankList = getGeneraRankList()
  230. for _, rank in ipairs(msg.matchList) do
  231. local rankInfo = myWarZoneRankList and myWarZoneRankList[rank] or generaRankList[rank]
  232. if rankInfo then
  233. msgData.playerInfoList[#msgData.playerInfoList+1] = {
  234. rank = rank,
  235. serverId = rankInfo.serverId,
  236. name = rankInfo.name,
  237. showBodyId = rankInfo.bodyId
  238. }
  239. end
  240. end
  241. local fd = MiddleManager.getFDBySvrIndex(msg.sourceServerId)
  242. InnerMsg.sendMsg(fd, msgData)
  243. end
  244. -- 普通服请求玩家数据
  245. function BG_N2C_PlayerData_Req(msg)
  246. local msgData = InnerMsg.wl.WL_BATTLEGROUND_PLAYER_DATA_QUERY
  247. msgData.playerUuid = msg.playerUuid
  248. msgData.playerInfo = {}
  249. local myWarZoneRankList = getMyWarZoneRankList(msg.sourceServerId)
  250. local generaRankList = getGeneraRankList()
  251. local rankInfo = myWarZoneRankList and myWarZoneRankList[msg.playerRank] or generaRankList[msg.playerRank]
  252. if rankInfo then
  253. msgData.playerInfo.serverId = rankInfo.serverId
  254. msgData.playerInfo.name = rankInfo.name
  255. msgData.playerInfo.heroHeadId = rankInfo.headId
  256. msgData.playerInfo.heroHeadFrameId = rankInfo.headFrameId
  257. msgData.playerInfo.monsteroutId = 0
  258. if rankInfo.serverId then -- 真实玩家
  259. msgData.playerInfo.heroArr = {}
  260. for _, heroId in ipairs(rankInfo.heroArr or {}) do
  261. msgData.playerInfo.heroArr[#msgData.playerInfo.heroArr+1] = heroId
  262. end
  263. else
  264. -- 机器人
  265. msgData.playerInfo.monsteroutId = rankInfo.monsterOutID
  266. end
  267. end
  268. local fd = MiddleManager.getFDBySvrIndex(msg.sourceServerId)
  269. InnerMsg.sendMsg(fd, msgData)
  270. end
  271. -- 普通服请求排行榜数据
  272. function BG_N2C_RankList_Req(msg)
  273. local msgData = InnerMsg.wl.WL_BATTLEGROUND_RANKLIST_QUERY
  274. msgData.playerUuid = msg.playerUuid
  275. msgData.rankList = {}
  276. local myWarZoneRankList = getMyWarZoneRankList(msg.sourceServerId)
  277. local generaRankList = getGeneraRankList()
  278. for rank=1, RANK_SHOW_NUM do
  279. local rankInfo = myWarZoneRankList and myWarZoneRankList[rank] or generaRankList[rank]
  280. msgData.rankList[rank] = {
  281. rank = rank,
  282. serverId = rankInfo.serverId,
  283. name = rankInfo.name,
  284. heroHeadId = rankInfo.headId,
  285. heroHeadFrameId = rankInfo.headFrameId,
  286. playerUuid = rankInfo.playerUuid,
  287. }
  288. end
  289. local fd = MiddleManager.getFDBySvrIndex(msg.sourceServerId)
  290. InnerMsg.sendMsg(fd, msgData)
  291. end
  292. -- 玩家请求挑战某个排名
  293. function BG_N2C_Challenge_Req(msg)
  294. local msgData = InnerMsg.wl.WL_BATTLEGROUND_CHALLENGE_QUERY
  295. msgData.playerUuid = msg.playerUuid
  296. msgData.playerInfo = {}
  297. msgData.errCode = 0
  298. local fd = MiddleManager.getFDBySvrIndex(msg.sourceServerId)
  299. local targetRank = msg.rank
  300. local myWarZoneRankList = getMyWarZoneRankList(msg.sourceServerId)
  301. local generaRankList = getGeneraRankList()
  302. local targetRanker = myWarZoneRankList and myWarZoneRankList[targetRank] or generaRankList[targetRank]
  303. if not targetRanker then
  304. msgData.errCode = -1
  305. return InnerMsg.sendMsg(fd, msgData)
  306. end
  307. msgData.playerInfo = {
  308. rank = targetRank,
  309. playerUuid = targetRanker.playerUuid,
  310. defServerId = targetRanker.serverId or 0
  311. }
  312. InnerMsg.sendMsg(fd, msgData)
  313. end
  314. -- 挑战结束
  315. function BG_N2C_Challenge_End(msg)
  316. local atkPlayerUuid = msg.playerUuid
  317. local atkRank = msg.atkRank
  318. local defRank = msg.defRank
  319. local challengeRes = msg.challengeRes
  320. -- 加入参与列表
  321. battleGroundData.joinList = battleGroundData.joinList or {}
  322. if not findVal(battleGroundData.joinList, atkPlayerUuid) then
  323. battleGroundData.joinList[#battleGroundData.joinList+1] = {msg.sourceServerId, atkPlayerUuid}
  324. updateValue("joinList", battleGroundData.joinList)
  325. end
  326. -- 挑战没有胜利
  327. if challengeRes ~= CombatDefine.RESULT_WIN then
  328. return
  329. end
  330. local myWarZoneRankList = getMyWarZoneRankList(msg.sourceServerId)
  331. if not myWarZoneRankList then
  332. initMyWarZoneRankList(msg.sourceServerId)
  333. myWarZoneRankList = getMyWarZoneRankList(msg.sourceServerId)
  334. end
  335. -- 如果挑战方在榜上, 则检查当前排名与挑战时排名是否一致, 如果不一致则获取最新排名
  336. local atkRanker = myWarZoneRankList[atkRank]
  337. if atkRanker and atkRanker.playerUuid ~= atkPlayerUuid then
  338. atkRank = getPlayerRankByUuid(myWarZoneRankList, msg.playerUuid)
  339. end
  340. local msgData = InnerMsg.wl.WL_BATTLEGROUND_NOTIFY_PLAYER
  341. local fd = MiddleManager.getFDBySvrIndex(msg.sourceServerId)
  342. msgData.playerUuid = msg.playerUuid
  343. msgData.newRank = atkRank
  344. msgData.atkeServerId = msg.sourceServerId
  345. msgData.atkName = atkRanker and atkRanker.name or msg.playerShowData.name or ""
  346. msgData.updateType = 0
  347. -- 如果挑战者排名高于被挑战者排名, 则只通知挑战者刷新匹配列表
  348. if atkRank < defRank then
  349. return InnerMsg.sendMsg(fd, msgData)
  350. end
  351. local defTemp = myWarZoneRankList[defRank]
  352. -- 如果挑战方在榜上, 则先把挑战方从排行榜上移除
  353. if atkRank <= ServerCommerceActDefine.COMMERCEACT_NPC_CNT then
  354. myWarZoneRankList[atkRank] = nil
  355. end
  356. -- 第一次挑战, 则使用生成的玩家数据
  357. if not atkRanker then
  358. atkRanker = msg.playerShowData
  359. end
  360. -- 把挑战方加入到排行榜上, 排名为防守方原排名
  361. atkRanker.rank = defRank
  362. myWarZoneRankList[defRank] = atkRanker
  363. -- 如果双方都在榜上, 则被挑战方排名下降为挑战方原排名
  364. if defTemp and atkRank <= ServerCommerceActDefine.COMMERCEACT_NPC_CNT then
  365. defTemp.rank = atkRank
  366. myWarZoneRankList[atkRank] = defTemp
  367. end
  368. -- 保存排行榜数据
  369. local warZoneServerIdx = getWarZoneServerIdx(msg.sourceServerId)
  370. updateValue("allAreaRankList".."."..warZoneServerIdx, battleGroundData.allAreaRankList[warZoneServerIdx])
  371. -- 通知挑战者排名提高
  372. fd = MiddleManager.getFDBySvrIndex(atkRanker.serverId)
  373. msgData.playerUuid = atkRanker.playerUuid
  374. msgData.newRank = atkRanker.rank
  375. msgData.atkeServerId = msg.sourceServerId
  376. msgData.atkName = atkRanker.name
  377. msgData.updateType = 1
  378. InnerMsg.sendMsg(fd, msgData)
  379. -- 如果被挑战方是真实玩家, 则通知
  380. if defTemp and defTemp.serverId and defTemp.serverId ~= 0 then
  381. msgData.playerUuid = defTemp.playerUuid
  382. msgData.newRank = defTemp.rank
  383. msgData.updateType = 2
  384. fd = MiddleManager.getFDBySvrIndex(defTemp.serverId)
  385. InnerMsg.sendMsg(fd, msgData)
  386. end
  387. end
  388. -- 更换战斗阵容
  389. function BG_N2C_Lineup_Update(msg)
  390. local myWarZoneRankList = getMyWarZoneRankList(msg.sourceServerId)
  391. local myRank = getPlayerRankByUuid(myWarZoneRankList, msg.playerUuid)
  392. if myRank > ServerCommerceActDefine.COMMERCEACT_NPC_CNT then
  393. return
  394. end
  395. myWarZoneRankList[myRank].heroArr = msg.heroArr
  396. local warZoneServerIdx = getWarZoneServerIdx(msg.sourceServerId)
  397. updateValue("allAreaRankList".."."..warZoneServerIdx, battleGroundData.allAreaRankList[warZoneServerIdx])
  398. end
  399. -- 活动结束
  400. function BG_N2C_Act_End(msg)
  401. local warZoneServerIdMin, warZoneServerIdMax = getWarZoneServerArea(msg.sourceServerId)
  402. if not warZoneServerIdMin or warZoneServerIdMin == 0 then
  403. return
  404. end
  405. if repeateServerIdList[warZoneServerIdMin] then
  406. return
  407. end
  408. -- 更新标识
  409. repeateServerIdList[warZoneServerIdMin] = true
  410. local fd_2_PlayerList = {}
  411. local joinList = battleGroundData.joinList
  412. local serverIdxMin = MiddleConnect.MiddleConnect_ConfServerID2TrueServerID(warZoneServerIdMin)
  413. local serverIdxMax = MiddleConnect.MiddleConnect_ConfServerID2TrueServerID(warZoneServerIdMax)
  414. -- 参与玩家(包括在榜玩家)
  415. for k = #joinList, 1, -1 do
  416. local playerInfo = joinList[k]
  417. local serverId = playerInfo[1]
  418. if serverId >= serverIdxMin and serverId <= serverIdxMax then
  419. local fd = MiddleManager.getFDBySvrIndex(serverId)
  420. if fd then
  421. fd_2_PlayerList[fd] = fd_2_PlayerList[fd] or {}
  422. fd_2_PlayerList[fd][#fd_2_PlayerList[fd]+1] = {ServerCommerceActDefine.COMMERCEACT_NPC_CNT, playerInfo[2]}
  423. end
  424. table.remove(joinList, k)
  425. end
  426. end
  427. -- 在榜玩家
  428. local myWarZoneRankList = getMyWarZoneRankList(msg.sourceServerId)
  429. for _, player in pairs(myWarZoneRankList or {}) do
  430. local fd = MiddleManager.getFDBySvrIndex(player.serverId)
  431. if fd then
  432. fd_2_PlayerList[fd] = fd_2_PlayerList[fd] or {}
  433. local idx = findVal(fd_2_PlayerList[fd], player.playerUuid)
  434. if idx then
  435. fd_2_PlayerList[fd][idx][1] = player.rank
  436. end
  437. end
  438. end
  439. if battleGroundData.allAreaRankList and battleGroundData.allAreaRankList[warZoneServerIdMin] then
  440. battleGroundData.allAreaRankList[warZoneServerIdMin] = nil
  441. end
  442. if next(fd_2_PlayerList) then
  443. -- 写日志
  444. local logTab2 = Util.serialize(fd_2_PlayerList)
  445. local logStr2 = table.concat(logTab2)
  446. Timer.addLater(45, writeLog, logStr2)
  447. local delay_sec = 0
  448. for fd, rankArr in pairs(fd_2_PlayerList) do
  449. delay_sec = delay_sec + 3
  450. Timer.addLater(delay_sec, issueReward, fd, rankArr)
  451. end
  452. -- 更新数据
  453. if not next(battleGroundData.joinList) then
  454. battleGroundData.joinList = nil
  455. end
  456. updateValue("joinList", battleGroundData.joinList)
  457. if not next(battleGroundData.allAreaRankList) then
  458. battleGroundData.allAreaRankList = nil
  459. end
  460. updateValue("allAreaRankList", battleGroundData.allAreaRankList)
  461. end
  462. end