ServerCommerceActBattleGroundCS.lua 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479
  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 notifyActEnd = false -- 是否收到活动结束通知的标识
  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. local function cmp(a, b)
  57. return a.rank < b.rank
  58. end
  59. -- 生成一个排行榜列表
  60. local function genRankList(rankList)
  61. local function genPlayerData(player, tNpcConfig, rank)
  62. local r = math.random(1, #tNpcConfig.monsterOutID)
  63. player.rank = rank
  64. player.name = CreateRole.getRandomName()
  65. player.headId = CreateRole.getRandomHead()
  66. player.headFrameId = CreateRole.getRandomHeadFrame()
  67. player.bodyId = CreateRole.getRandomBody()
  68. player.playerUuid = tNpcConfig.monsterOutID[r]
  69. player.monsterOutID = tNpcConfig.monsterOutID[r]
  70. end
  71. local rank = 1
  72. for _, cfg in ipairs(NpcConfig) do
  73. for i = 1, cfg.cnt do
  74. rankList[rank] = {}
  75. genPlayerData(rankList[rank], cfg, rank)
  76. rank = rank + 1
  77. if rank > ServerCommerceActDefine.COMMERCEACT_NPC_CNT then
  78. break
  79. end
  80. end
  81. end
  82. end
  83. -- 插入数据
  84. local function insertData(data)
  85. LuaMongo.insert(DB.db_battleground, data)
  86. end
  87. -- 修改db单个字段
  88. local function updateValue(key, value)
  89. if not key then return end
  90. if value then
  91. dbUpdateField["$set"] = {[key]=value}
  92. dbUpdateField["$unset"] = nil
  93. else
  94. dbUpdateField["$set"] = nil
  95. dbUpdateField["$unset"] = {[key]=1}
  96. end
  97. dbUpdate._id = battleGroundData._id
  98. LuaMongo.update(DB.db_battleground, dbUpdate, dbUpdateField)
  99. end
  100. -- 保存所有数据
  101. local function saveAllData()
  102. dbUpdate._id = battleGroundData._id
  103. LuaMongo.update(DB.db_battleground, dbUpdate, battleGroundData)
  104. end
  105. local function loadData()
  106. LuaMongo.find(DB.db_battleground)
  107. local data = {}
  108. if LuaMongo.next(data) then
  109. battleGroundData = data
  110. end
  111. if battleGroundData.allAreaRankList and next(battleGroundData.allAreaRankList) then
  112. for areaIdx, rankList in pairs(battleGroundData.allAreaRankList) do
  113. table.sort(rankList, cmp)
  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, cmp)
  122. end
  123. function BattleGround_InitAfterStart()
  124. if _G.is_middle ~= true then
  125. return
  126. end
  127. loadData()
  128. end
  129. -- 通过本服Id获取所在战区Id
  130. local function getWarZoneServerIdx(sourceServerId)
  131. local nServerKey = MiddleConnect.MiddleConnect_TrueServerID2ConfServerID(sourceServerId)
  132. nServerKey = MiddleConnect.MiddleConnect_GetWarZoneServer(nServerKey)
  133. return nServerKey
  134. end
  135. -- 生成一个战区排行榜
  136. local function genWarZoneRankList(warZoneServerIdx)
  137. local isInsert = false
  138. if not next(battleGroundData) then
  139. isInsert = true
  140. end
  141. battleGroundData.allAreaRankList = battleGroundData.allAreaRankList or {}
  142. battleGroundData.allAreaRankList[warZoneServerIdx] = {}
  143. genRankList(battleGroundData.allAreaRankList[warZoneServerIdx])
  144. if isInsert then
  145. return insertData(battleGroundData)
  146. end
  147. updateValue("allAreaRankList".."."..warZoneServerIdx, battleGroundData.allAreaRankList[warZoneServerIdx])
  148. end
  149. -- 获取本服所在战区的排行榜
  150. local function getMyWarZoneRankList(sourceServerId)
  151. local warZoneServerIdx = getWarZoneServerIdx(sourceServerId)
  152. if not battleGroundData.allAreaRankList or not battleGroundData.allAreaRankList[warZoneServerIdx] then
  153. -- genWarZoneRankList(warZoneServerIdx)
  154. return
  155. end
  156. return battleGroundData.allAreaRankList[warZoneServerIdx]
  157. end
  158. -- 初始化本战区的排行榜
  159. local function initMyWarZoneRankList(sourceServerId)
  160. local warZoneServerIdx = getWarZoneServerIdx(sourceServerId)
  161. if not battleGroundData.allAreaRankList or not battleGroundData.allAreaRankList[warZoneServerIdx] then
  162. battleGroundData.allAreaRankList = battleGroundData.allAreaRankList or {}
  163. battleGroundData.allAreaRankList[warZoneServerIdx] = {}
  164. end
  165. end
  166. -- 获取通用排行榜
  167. local function getGeneraRankList()
  168. return battleGroundData.generaRankList
  169. end
  170. -- 通过玩家uuid获取排名
  171. local function getPlayerRankByUuid(rankList, targetPlayerUuid)
  172. local targetRank = ServerCommerceActDefine.COMMERCEACT_NPC_CNT + 1
  173. if not rankList then
  174. return targetRank
  175. end
  176. for rank, rankInfo in ipairs(rankList) do
  177. if rankInfo.playerUuid == targetPlayerUuid then
  178. targetRank = rank
  179. break
  180. end
  181. end
  182. return targetRank
  183. end
  184. -- 遍历
  185. local function findVal(list, val)
  186. for k, info in pairs(list or {}) do
  187. if info[2] == val then
  188. return k
  189. end
  190. end
  191. end
  192. -- 发奖
  193. local function issueReward(fd, rankArr)
  194. local msgData = InnerMsg.wl.WL_BATTLEGROUND_NOTIFY_PLAYER
  195. msgData.playerArr = rankArr
  196. InnerMsg.sendMsg(fd, msgData)
  197. end
  198. -- 普通服请求玩家排名
  199. function BG_N2C_PlayerRank_Req(msg)
  200. local msgData = InnerMsg.wl.WL_BATTLEGROUND_PLAYER_RANK_QUERY
  201. msgData.playerRank = 0
  202. msgData.playerUuid = msg.playerUuid
  203. local myWarZoneRankList = getMyWarZoneRankList(msg.sourceServerId)
  204. msgData.playerRank = getPlayerRankByUuid(myWarZoneRankList, msg.playerUuid)
  205. local fd = MiddleManager.getFDBySvrIndex(msg.sourceServerId)
  206. InnerMsg.sendMsg(fd, msgData)
  207. end
  208. -- 普通服请求对手数据
  209. function BG_N2C_MatchList_Req(msg)
  210. local msgData = InnerMsg.wl.WL_BATTLEGROUND_MATCHLIST_QUERY
  211. msgData.playerUuid = msg.playerUuid
  212. msgData.playerInfoList = {}
  213. local myWarZoneRankList = getMyWarZoneRankList(msg.sourceServerId)
  214. local generaRankList = getGeneraRankList()
  215. for _, rank in ipairs(msg.matchList) do
  216. local rankInfo = myWarZoneRankList and myWarZoneRankList[rank] or generaRankList[rank]
  217. if rankInfo then
  218. msgData.playerInfoList[#msgData.playerInfoList+1] = {
  219. rank = rank,
  220. serverId = rankInfo.serverId,
  221. name = rankInfo.name,
  222. showBodyId = rankInfo.bodyId
  223. }
  224. end
  225. end
  226. local fd = MiddleManager.getFDBySvrIndex(msg.sourceServerId)
  227. InnerMsg.sendMsg(fd, msgData)
  228. end
  229. -- 普通服请求玩家数据
  230. function BG_N2C_PlayerData_Req(msg)
  231. local msgData = InnerMsg.wl.WL_BATTLEGROUND_PLAYER_DATA_QUERY
  232. msgData.playerUuid = msg.playerUuid
  233. msgData.playerInfo = {}
  234. local myWarZoneRankList = getMyWarZoneRankList(msg.sourceServerId)
  235. local generaRankList = getGeneraRankList()
  236. local rankInfo = myWarZoneRankList and myWarZoneRankList[rank] or generaRankList[rank]
  237. if rankInfo then
  238. msgData.playerInfo.serverId = rankInfo.serverId
  239. msgData.playerInfo.name = rankInfo.name
  240. msgData.playerInfo.heroHeadId = rankInfo.headId
  241. msgData.playerInfo.heroHeadFrameId = rankInfo.headFrameId
  242. msgData.playerInfo.monsteroutId = 0
  243. if rankInfo.serverId then -- 真实玩家
  244. msgData.playerInfo.heroArr = {}
  245. for _, heroId in ipairs(rankInfo.heroArr or {}) do
  246. msgData.playerInfo.heroArr[#msgData.playerInfo.heroArr+1] = heroId
  247. end
  248. else
  249. -- 机器人
  250. msgData.playerInfo.monsteroutId = rankInfo.monsterOutID
  251. end
  252. end
  253. local fd = MiddleManager.getFDBySvrIndex(msg.sourceServerId)
  254. InnerMsg.sendMsg(fd, msgData)
  255. end
  256. -- 普通服请求排行榜数据
  257. function BG_N2C_RankList_Req(msg)
  258. local msgData = InnerMsg.wl.WL_BATTLEGROUND_RANKLIST_QUERY
  259. msgData.playerUuid = msg.playerUuid
  260. msgData.rankList = {}
  261. local myWarZoneRankList = getMyWarZoneRankList(msg.sourceServerId)
  262. local generaRankList = getGeneraRankList()
  263. for rank=1, RANK_SHOW_NUM do
  264. local rankInfo = myWarZoneRankList and myWarZoneRankList[rank] or generaRankList[rank]
  265. msgData.rankList[rank] = {
  266. rank = rank,
  267. serverId = rankInfo.serverId,
  268. name = rankInfo.name,
  269. heroHeadId = rankInfo.headId,
  270. heroHeadFrameId = rankInfo.headFrameId,
  271. }
  272. end
  273. local fd = MiddleManager.getFDBySvrIndex(msg.sourceServerId)
  274. InnerMsg.sendMsg(fd, msgData)
  275. end
  276. -- 玩家请求挑战某个排名
  277. function BG_N2C_Challenge_Req(msg)
  278. local msgData = InnerMsg.wl.WL_BATTLEGROUND_CHALLENGE_QUERY
  279. msgData.playerUuid = msg.playerUuid
  280. msgData.playerInfo = {}
  281. msgData.errCode = 0
  282. local fd = MiddleManager.getFDBySvrIndex(msg.sourceServerId)
  283. local targetRank = msg.rank
  284. local myWarZoneRankList = getMyWarZoneRankList(msg.sourceServerId)
  285. local generaRankList = getGeneraRankList()
  286. local targetRanker = myWarZoneRankList and myWarZoneRankList[rank] or generaRankList[rank]
  287. if not targetRanker then
  288. msgData.errCode = -1
  289. return InnerMsg.sendMsg(fd, msgData)
  290. end
  291. msgData.playerInfo = {
  292. rank = targetRank,
  293. playerUuid = targetRanker.playerUuid,
  294. defServerId = targetRanker.serverId or 0
  295. }
  296. InnerMsg.sendMsg(fd, msgData)
  297. end
  298. -- 挑战结束
  299. function BG_N2C_Challenge_End(msg)
  300. local atkPlayerUuid = msg.playerUuid
  301. local atkRank = msg.atkRank
  302. local defRank = msg.defRank
  303. local challengeRes = msg.challengeRes
  304. -- 加入参与列表
  305. battleGroundData.joinList = battleGroundData.joinList or {}
  306. if not findVal(battleGroundData.joinList, atkPlayerUuid) then
  307. battleGroundData.joinList[#battleGroundData.joinList+1] = {msg.sourceServerId, atkPlayerUuid}
  308. updateValue("joinList", battleGroundData.joinList)
  309. end
  310. -- 挑战没有胜利
  311. if challengeRes ~= CombatDefine.RESULT_WIN then
  312. return
  313. end
  314. local myWarZoneRankList = getMyWarZoneRankList(msg.sourceServerId)
  315. if not myWarZoneRankList then
  316. initMyWarZoneRankList(msg.sourceServerId)
  317. myWarZoneRankList = getMyWarZoneRankList(msg.sourceServerId)
  318. end
  319. -- 检查挑战方当前排名与挑战时排名是否一致
  320. local atkRanker = myWarZoneRankList[atkRank]
  321. if atkRanker and atkRanker.playerUuid ~= atkPlayerUuid then
  322. atkRank = getPlayerRankByUuid(myWarZoneRankList, msg.playerUuid)
  323. end
  324. local defTemp = myWarZoneRankList[defRank]
  325. -- 第一次挑战
  326. if not atkRanker then
  327. atkRanker = msg.playerShowData
  328. end
  329. -- 挑战方排名提升为被挑战方原排名
  330. atkRanker.rank = defRank
  331. myWarZoneRankList[defRank] = atkRanker
  332. -- 如果双方都在本战区排行榜上, 被挑战方排名下降为原挑战方排名
  333. if defTemp and atkRank <= ServerCommerceActDefine.COMMERCEACT_NPC_CNT then
  334. defTemp.rank = atkRank
  335. myWarZoneRankList[atkRank] = defTemp
  336. end
  337. -- 如果被挑战方是真实玩家, 则通知
  338. if defTemp and defTemp.serverId ~= 0 then
  339. local msgData = InnerMsg.wl.WL_BATTLEGROUND_NOTIFY_PLAYER
  340. msgData.playerUuid = defTemp.playerUuid
  341. msgData.newRank = defTemp.rank
  342. msgData.atkeServerId = msg.sourceServerId
  343. msgData.atkName = atkRanker.name
  344. local fd = MiddleManager.getFDBySvrIndex(defTemp.serverId)
  345. InnerMsg.sendMsg(fd, msgData)
  346. end
  347. local warZoneServerIdx = getWarZoneServerIdx(msg.sourceServerId)
  348. updateValue("allAreaRankList".."."..warZoneServerIdx, battleGroundData.allAreaRankList[warZoneServerIdx])
  349. end
  350. -- 更换战斗阵容
  351. function BG_N2C_Lineup_Update(msg)
  352. local myWarZoneRankList = getMyWarZoneRankList(msg.sourceServerId)
  353. local myRank = getPlayerRankByUuid(myWarZoneRankList, msg.playerUuid)
  354. if myRank > ServerCommerceActDefine.COMMERCEACT_NPC_CNT then
  355. return
  356. end
  357. myWarZoneRankList[myRank].heroArr = msg.heroArr
  358. local warZoneServerIdx = getWarZoneServerIdx(msg.sourceServerId)
  359. updateValue("allAreaRankList".."."..warZoneServerIdx, battleGroundData.allAreaRankList[warZoneServerIdx])
  360. end
  361. -- 活动结束
  362. function BG_N2C_Act_End(msg)
  363. if notifyActEnd then
  364. return
  365. end
  366. local fd_2_Rank = {}
  367. local joinList = battleGroundData.joinList
  368. local allAreaRankList = battleGroundData.allAreaRankList
  369. -- 参与玩家(包括在榜玩家)
  370. for _, playerInfo in ipairs(joinList) do
  371. local serverId = playerInfo[1]
  372. local fd = MiddleManager.getFDBySvrIndex(serverId)
  373. fd_2_Rank[fd] = fd_2_Rank[fd] or {}
  374. fd_2_Rank[fd][#fd_2_Rank[fd]+1] = {ServerCommerceActDefine.COMMERCEACT_NPC_CNT, playerInfo[2]}
  375. end
  376. -- 在榜玩家
  377. for _, rankList in pairs(allAreaRankList or {}) do
  378. for _, player in ipairs(rankList) do
  379. local fd = MiddleManager.getFDBySvrIndex(player.serverId)
  380. fd_2_Rank[fd] = fd_2_Rank[fd] or {}
  381. local idx = findVal(fd_2_Rank[fd], player.playerUuid)
  382. if idx then
  383. fd_2_Rank[fd][idx][1] = player.rank
  384. end
  385. end
  386. end
  387. if next(fd_2_Rank) then
  388. local delay_sec = 0
  389. for fd, rankArr in pairs(fd_2_Rank) do
  390. delay_sec = delay_sec + 3
  391. Timer.addLater(delay_sec, issueReward, fd, rankArr)
  392. end
  393. -- 重置排行榜数据
  394. battleGroundData = {}
  395. saveAllData()
  396. -- 更新标识
  397. notifyActEnd = true
  398. end
  399. end