GodsAreaCS.lua 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417
  1. -- 诸神圣域(跨服)
  2. -- A 先挑战B, C跟着挑战B, 挑战都胜利, C先于A把结果发到跨服上。处理方式: C先与B交换排名, A再与C交换排名
  3. local InnerMsg = require("core.InnerMsg")
  4. local CombatVideo = require("combat.CombatVideo")
  5. local GodsAreaDB = require("godsArea.GodsAreaDB")
  6. local MiddleManager = require("middle.MiddleManager")
  7. local GodsAreaConfig = require("excel.godsArea")
  8. local Log = require("common.Log")
  9. local Timer = require("core.Timer")
  10. local Util = require("common.Util")
  11. -- 请求战斗到结束时间: 5s
  12. local MAX_CHALLENGE_TIME = 5
  13. -- 每天发奖时间, 晚上23:00
  14. local SEND_REWARD_HOUR = 23
  15. -- 正在被挑战的排名列表
  16. local challengeList = {}
  17. -- 通过uid查找排名
  18. local function getRankInfoByUid(rankList, uid)
  19. local finalRank = 0
  20. for rank, rankData in ipairs(rankList) do
  21. if rankData.uid and rankData.uid == uid then
  22. return rank, rankData
  23. end
  24. end
  25. return finalRank
  26. end
  27. -- 获取某个服的在榜人数
  28. local function getRankListBySrvId(rankList, targetSrvId)
  29. local rankTb = {}
  30. for rank, rankData in ipairs(rankList) do
  31. if rankData.serverId and rankData.serverId == targetSrvId then
  32. rankTb[rankData.uid] = rank
  33. end
  34. end
  35. return rankTb
  36. end
  37. local function getSanmeIdx(heroArr, targetUid)
  38. for k, v in ipairs(heroArr) do
  39. if v.heroUuid == targetUid then
  40. return k
  41. end
  42. end
  43. end
  44. local function writeLog(logId ,logStr)
  45. -- Log.write(Log.LOGID_OSS_GODSAREA_CHALLENGE, logStr)
  46. Log.write(logId, logStr)
  47. end
  48. local function getAllSrvFd()
  49. local fdList = MiddleManager.MiddleManager_GetAllFD()
  50. local fdArray = {}
  51. local len = 0
  52. for srvId, fd in pairs(fdList) do
  53. len = len + 1
  54. fdArray[len] = {srvId, fd}
  55. end
  56. if len == 0 then
  57. return
  58. end
  59. return fdArray
  60. end
  61. -- 通知游戏服
  62. function BrocastServer(srvTb, rankList)
  63. for _, srvInfo in ipairs(srvTb) do
  64. local rankTb = getRankListBySrvId(rankList, srvInfo[1])
  65. CS_Send_Reward(srvInfo[2], rankTb)
  66. local logStr = string.format("跨服开始通知普通服, 普通服Id: %d", srvInfo[1])
  67. writeLog(Log.LOGID_OSS_GODSAREA_MAIL ,logStr)
  68. end
  69. end
  70. -- 把连接到本跨服的普通服进行分批
  71. function BatchServer()
  72. local cnt = 0
  73. local maxNum = 10
  74. local delay_sec = 0
  75. local srvTb = {}
  76. local fdArray = getAllSrvFd()
  77. if not fdArray then
  78. local logStr = "跨服获取不到普通服的fd, 通知普通服失败"
  79. writeLog(Log.LOGID_OSS_GODSAREA_MAIL ,logStr)
  80. return
  81. end
  82. local rankList = GodsAreaDB.GetRankList()
  83. for _, v in ipairs(fdArray) do
  84. cnt = cnt + 1
  85. srvTb[cnt] = v
  86. if cnt >= maxNum then
  87. delay_sec = delay_sec + 5
  88. Timer.addLater(delay_sec, BrocastServer, srvTb, rankList)
  89. -- Timer.addLater(2, BrocastServer, srvTb, rankList)
  90. cnt = 0
  91. srvTb = {}
  92. end
  93. end
  94. if cnt > 0 then
  95. Timer.addLater(2, BrocastServer, srvTb, rankList)
  96. end
  97. end
  98. function onHour(hour)
  99. if _G.is_middle ~= true then return end
  100. if hour == SEND_REWARD_HOUR then
  101. local delay_sec = math.random(1, 30)
  102. Timer.addLater(delay_sec, BatchServer)
  103. local logStr = string.format("[跨服]开始发奖, 当前时间: %s, 延迟: %d 秒通知", os.time(), delay_sec)
  104. writeLog(Log.LOGID_OSS_GODSAREA_MAIL ,logStr)
  105. end
  106. end
  107. -- 测试
  108. function oneMin()
  109. -- local delay_sec = math.random(3, 5)
  110. -- Timer.addLater(delay_sec, BatchServer)
  111. -- local logStr = string.format("[跨服]开始发奖, 当前时间: %s, 延迟: %d 秒通知", os.time(), delay_sec)
  112. -- writeLog(Log.LOGID_OSS_GODSAREA_MAIL ,logStr)
  113. end
  114. -- 普通服请求排行榜数据
  115. function CS_RankList_Query(sourceServerId, playerUid)
  116. local rankList = GodsAreaDB.GetRankList()
  117. local msgData = InnerMsg.wl.WL_GODSATREA_QUERY_RANKLIST
  118. msgData.myRank = 0
  119. msgData.playerUid = playerUid
  120. msgData.rankList = {}
  121. local msgRankList = msgData.rankList
  122. for rank, playerInfo in ipairs(rankList) do
  123. msgRankList[rank] = {
  124. body = playerInfo.body or 0,
  125. name = playerInfo.name or "",
  126. uid = playerInfo.uid,
  127. }
  128. if playerInfo.uid and playerInfo.uid == playerUid then
  129. msgData.myRank = rank
  130. end
  131. end
  132. local fd = MiddleManager.getFDBySvrIndex(sourceServerId)
  133. InnerMsg.sendMsg(fd, msgData)
  134. end
  135. -- 普通服请求某个排名的玩家数据
  136. function CS_GetPlayerInfo(sourceServerId, targetRank, targetUid, playerUid)
  137. local fd = MiddleManager.getFDBySvrIndex(sourceServerId)
  138. local msgData = InnerMsg.wl.WL_GODSATREA_QUERY_PLAYER_INFO
  139. msgData.res = -1
  140. msgData.playerInfo = {}
  141. msgData.playerUid = playerUid
  142. local rankList = GodsAreaDB.GetRankList()
  143. local rankData = rankList[targetRank]
  144. -- 数据异常
  145. if not rankData then
  146. return InnerMsg.sendMsg(fd, msgData)
  147. end
  148. -- 客户端的数据不是最新数据
  149. if rankData.uid and rankData.uid ~= targetUid then
  150. msgData.res = -2
  151. return InnerMsg.sendMsg(fd, msgData)
  152. end
  153. msgData.res = 0
  154. msgData.playerInfo.name = rankData.name
  155. msgData.playerInfo.lv = rankData.level
  156. msgData.playerInfo.head = rankData.head
  157. msgData.playerInfo.headFrame = rankData.headFrame
  158. msgData.playerInfo.rank = targetRank
  159. if rankData.uid then
  160. msgData.playerInfo.uid = rankData.uid
  161. msgData.playerInfo.defendObjList = rankData.heroList
  162. end
  163. InnerMsg.sendMsg(fd, msgData)
  164. end
  165. -- 普通服查询是否可以挑战某个排名
  166. function CS_Challenge_Query(sourceServerId, defenseRank, defenseUid, attackerUid)
  167. local rankList = GodsAreaDB.GetRankList()
  168. local fd = MiddleManager.getFDBySvrIndex(sourceServerId)
  169. local msgData = InnerMsg.wl.WL_GODSATREA_CHALLENGE_QUERY
  170. msgData.res = 0
  171. msgData.attackerUid = attackerUid
  172. msgData.defenseRank = defenseRank
  173. msgData.defenseUid = defenseUid
  174. msgData.defenseServerId = 0
  175. local rankData = rankList[defenseRank]
  176. if not rankData then
  177. msgData.res = -1
  178. return InnerMsg.sendMsg(fd, msgData)
  179. end
  180. -- 客户端的排行数据不是最新数据
  181. if rankData.uid and defenseUid ~= rankData.uid then
  182. msgData.res = -2
  183. return InnerMsg.sendMsg(fd, msgData)
  184. end
  185. -- 不能挑战比自己排名低的
  186. local attackerRank = getRankInfoByUid(rankList, attackerUid)
  187. if attackerRank ~= 0 and attackerRank < defenseRank then
  188. msgData.res = -3
  189. return InnerMsg.sendMsg(fd, msgData)
  190. end
  191. -- 如果有一方处于挑战/被挑战中, 则提醒
  192. local now = os.time()
  193. local aChallengeInfo = challengeList[attackerRank]
  194. local dChallengeInfo = challengeList[defenseRank]
  195. if aChallengeInfo and (aChallengeInfo.startTime + MAX_CHALLENGE_TIME) > now then
  196. msgData.res = 1
  197. end
  198. if dChallengeInfo and (dChallengeInfo.startTime + MAX_CHALLENGE_TIME) > now then
  199. msgData.res = 2
  200. end
  201. -- 把被挑战方加入正在挑战列表
  202. challengeList[defenseRank] = {
  203. startTime = now,
  204. attackerUid = attackerUid,
  205. attackerRank = attackerRank,
  206. defenseUid = defenseUid,
  207. }
  208. -- 如果挑战方在排行榜上, 也加入挑战列表
  209. if attackerRank ~= 0 then
  210. challengeList[attackerRank] = {
  211. startTime = now,
  212. attackerUid = attackerUid,
  213. attackerRank = attackerRank,
  214. defenseUid = defenseUid,
  215. defenseRank = defenseRank,
  216. }
  217. end
  218. msgData.defenseServerId = rankData.serverId or 0
  219. msgData.defenseName = rankData.name or "匿名玩家"
  220. InnerMsg.sendMsg(fd, msgData)
  221. end
  222. -- 普通服通知跨服挑战胜利
  223. function CS_Challenge_Win(sourceServerId, defenseRank, defenseUid, attackerUid, attackInfo)
  224. local rankList = GodsAreaDB.GetRankList()
  225. local defenseRankData = rankList[defenseRank]
  226. local attackerRank, attackerRankData = getRankInfoByUid(rankList, attackerUid)
  227. local msgData = InnerMsg.wl.WL_GODSATREA_UPDATE_CHENGHAO
  228. local fd = MiddleManager.getFDBySvrIndex(defenseRankData.serverId)
  229. local attackData = attackInfo
  230. attackData._id = defenseRankData._id
  231. -- 挑战者在榜上则用榜上的展示数据
  232. if attackerRank ~= 0 then
  233. attackData = attackerRankData
  234. end
  235. -- 防守方当前是玩家
  236. if defenseRankData.uid then
  237. -- 通知失败方更新称号
  238. msgData.targetUid = defenseRankData.uid
  239. msgData.newRank = attackerRank
  240. msgData.isWinner = 0
  241. msgData.enemyName = attackData.name or ""
  242. InnerMsg.sendMsg(fd, msgData)
  243. end
  244. -- 挑战者是榜上玩家
  245. if attackerRank ~= 0 then
  246. -- 失败方排名更新为胜利方原排名
  247. defenseRankData.rank = attackerRank
  248. GodsAreaDB.UpdateRankData(attackerRank, defenseRankData)
  249. end
  250. -- 胜利方排名更新为失败方原排名
  251. attackData.rank = defenseRank
  252. GodsAreaDB.UpdateRankData(defenseRank, attackData)
  253. -- 通知胜利方更新称号
  254. fd = MiddleManager.getFDBySvrIndex(sourceServerId)
  255. msgData.targetUid = attackerUid
  256. msgData.newRank = defenseRank
  257. msgData.isWinner = 1
  258. msgData.enemyName = defenseRankData.name or ""
  259. InnerMsg.sendMsg(fd, msgData)
  260. local logStr = string.format("挑战胜利, attackerUid: %s, attackerRank: %d, defenseRank: %d, defenseOldUid: %s, defenseNowUid: %s",
  261. attackerUid, attackerRank, defenseRank, defenseUid, defenseRankData.uid or defenseUid)
  262. writeLog(Log.LOGID_OSS_GODSAREA_CHALLENGE ,logStr)
  263. end
  264. -- 普通服请求战斗录像数据
  265. function CS_Query_CombatVideo(sourceServerId, playerUid, targetRank)
  266. local videoList = CombatVideo.getCombatVideosByType(CombatVideo.VIDEOTYPE_GODSAREA, targetRank)
  267. local msgData = InnerMsg.wl.WL_GODSATREA_QUERY_RANK_VIDEO
  268. msgData.playerUid = playerUid
  269. msgData.videoData = {}
  270. for k,v in ipairs(videoList) do
  271. -- if k > CombatVideo.GODSAREA_RECORD_MAX_CNT then
  272. -- break
  273. -- end
  274. if k > 1 then
  275. break
  276. end
  277. msgData.videoData[k] = v
  278. end
  279. local fd = MiddleManager.getFDBySvrIndex(sourceServerId)
  280. InnerMsg.sendMsg(fd, msgData)
  281. end
  282. -- 更新玩家数据
  283. function CS_Update_PlayerInfo(playerUid, newPlayerInfo)
  284. local rankList = GodsAreaDB.GetRankList()
  285. local rank, rankData = getRankInfoByUid(rankList, playerUid)
  286. if rank == 0 then
  287. return
  288. end
  289. for k,v in pairs(newPlayerInfo) do
  290. rankData[k] = v
  291. end
  292. GodsAreaDB.UpdateRankData(rank, rankData)
  293. end
  294. -- 更新英雄数据
  295. function CS_Update_HeroInfo(playerUid, newHeroInfo)
  296. local rankList = GodsAreaDB.GetRankList()
  297. local rank, rankData = getRankInfoByUid(rankList, playerUid)
  298. if rank == 0 then
  299. return
  300. end
  301. local isChange = false
  302. if newHeroInfo.opType == 0 then
  303. local rmIdx = 0
  304. for k, v in ipairs(rankData.heroList) do
  305. if v.heroUuid == newHeroInfo.heroUuid then
  306. rmIdx = k
  307. break
  308. end
  309. end
  310. if rmIdx ~= 0 then
  311. isChange = true
  312. table.remove(rankData.heroList, rmIdx)
  313. end
  314. else
  315. for _, v in ipairs(newHeroInfo.heroList) do
  316. local targetIdx = getSanmeIdx(rankData.heroList, v.heroUuid)
  317. if targetIdx then
  318. isChange = true
  319. rankData.heroList[targetIdx] = v
  320. end
  321. end
  322. end
  323. if isChange then
  324. GodsAreaDB.UpdateRankData(rank, rankData)
  325. end
  326. end
  327. -- 通知游戏服, 给玩家发奖
  328. function CS_Send_Reward(fd, rankTb)
  329. local msgData = InnerMsg.wl.WL_GODSATREA_BROCAST_REWARD
  330. msgData.uid2RankTb = rankTb or {}
  331. InnerMsg.sendMsg(fd, msgData)
  332. end