| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504 |
- -- 诸神圣域(跨服)
- -- A 先挑战B, C跟着挑战B, 挑战都胜利, C先于A把结果发到跨服上。处理方式: C先与B交换排名, A再与C交换排名
- local InnerMsg = require("core.InnerMsg")
- local CombatVideo = require("combat.CombatVideo")
- local GodsAreaDB = require("godsArea.GodsAreaDB")
- local MiddleManager = require("middle.MiddleManager")
- local GodsAreaConfig = require("excel.godsArea")
- local Log = require("common.Log")
- local Timer = require("core.Timer")
- local Util = require("common.Util")
- -- 请求战斗到结束时间: 5s
- local MAX_CHALLENGE_TIME = 5
- -- 每天发奖时间, 晚上23:00
- local SEND_REWARD_HOUR = 23
- -- 正在被挑战的排名列表
- local challengeList = {}
- local function getSameIdx(heroList, targetUid)
- for k, v in pairs(heroList) do
- if v.heroUuid == targetUid then
- return k
- end
- end
- end
- -- 通过uid查找排名
- local function getRankInfoByUid(rankList, uid)
- local finalRank = 0
- for rank, rankData in ipairs(rankList) do
- if rankData.uid and rankData.uid == uid then
- return rank, rankData
- end
- end
- return finalRank
- end
- -- 获取某个服的在榜人数
- local function getRankListBySrvId(rankList, targetSrvId)
- local rankTb = {}
- for rank, rankData in ipairs(rankList) do
- if rankData.serverId and rankData.serverId == targetSrvId then
- rankTb[rankData.uid] = rank
- end
- end
- return rankTb
- end
- -- 清理超时的挑战数据
- local function clearChallengeList()
- if not next(challengeList) then
- return
- end
- local now = os.time()
- for k ,v in pairs(challengeList) do
- if v.startTime + MAX_CHALLENGE_TIME < now then
- challengeList[k] = nil
- end
- end
- end
- local function writeLog(logId ,logStr)
- -- Log.write(Log.LOGID_OSS_GODSAREA_CHALLENGE, logStr)
- Log.write(logId, logStr)
- end
- local function getAllSrvFd()
- local fdList = MiddleManager.MiddleManager_GetAllFD()
- local fdArray = {}
- local len = 0
- for srvId, fd in pairs(fdList) do
- len = len + 1
- fdArray[len] = {srvId, fd}
- end
- if len == 0 then
- return
- end
- return fdArray
- end
- --通知玩家
- local function notifyPlayer(playerUid, serverId)
- local fd = MiddleManager.getFDBySvrIndex(serverId)
- local msgData = InnerMsg.wl.WL_GODSATREA_UPDATE_PLAYER_INFO
- msgData.playerUid = playerUid
- InnerMsg.sendMsg(fd, msgData)
- end
- -- 通知玩家更新数据。新需求,兼容老数据。
- local function playerInfoCheck(rankList)
- for _, playerInfo in ipairs(rankList) do
- if playerInfo.uid and not playerInfo.power then
- notifyPlayer(playerInfo.uid, playerInfo.serverId)
- end
- end
- end
- -- 通知游戏服
- function BrocastServer(srvTb, rankList)
- for _, srvInfo in ipairs(srvTb) do
- local rankTb = getRankListBySrvId(rankList, srvInfo[1])
- CS_Send_Reward(srvInfo[2], rankTb)
- local logStr = string.format("跨服开始通知普通服, 普通服Id: %d", srvInfo[1])
- writeLog(Log.LOGID_OSS_GODSAREA_MAIL ,logStr)
- end
- end
- -- 把连接到本跨服的普通服进行分批
- function BatchServer()
- local cnt = 0
- local maxNum = 10
- local delay_sec = 0
- local srvTb = {}
- local fdArray = getAllSrvFd()
- if not fdArray then
- local logStr = "跨服获取不到普通服的fd, 通知普通服失败"
- writeLog(Log.LOGID_OSS_GODSAREA_MAIL ,logStr)
- return
- end
- local rankList = GodsAreaDB.GetRankList()
- for _, v in ipairs(fdArray) do
- cnt = cnt + 1
- srvTb[cnt] = v
- if cnt >= maxNum then
- delay_sec = delay_sec + 5
- Timer.addLater(delay_sec, BrocastServer, srvTb, rankList)
- -- Timer.addLater(2, BrocastServer, srvTb, rankList)
- cnt = 0
- srvTb = {}
- end
- end
- if cnt > 0 then
- Timer.addLater(2, BrocastServer, srvTb, rankList)
- end
- end
- function onHour(hour)
- if _G.is_middle ~= true then return end
- if hour == SEND_REWARD_HOUR then
- local delay_sec = math.random(1, 30)
- Timer.addLater(delay_sec, BatchServer)
- local logStr = string.format("[跨服]开始发奖, 当前时间: %s, 延迟: %d 秒通知", os.time(), delay_sec)
- writeLog(Log.LOGID_OSS_GODSAREA_MAIL ,logStr)
- end
- end
- -- 测试
- function oneMin()
- -- local delay_sec = math.random(3, 5)
- -- Timer.addLater(delay_sec, BatchServer)
- -- local logStr = string.format("[跨服]开始发奖, 当前时间: %s, 延迟: %d 秒通知", os.time(), delay_sec)
- -- writeLog(Log.LOGID_OSS_GODSAREA_MAIL ,logStr)
- end
- -- 普通服请求排行榜数据
- function CS_RankList_Query(sourceServerId, playerUid)
- local rankList = GodsAreaDB.GetRankList()
- local msgData = InnerMsg.wl.WL_GODSATREA_QUERY_RANKLIST
- msgData.myRank = 0
- msgData.playerUid = playerUid
- msgData.rankList = {}
- local msgRankList = msgData.rankList
- for rank, playerInfo in ipairs(rankList) do
- msgRankList[rank] = {
- body = playerInfo.body or 0,
- name = playerInfo.name or "",
- uid = playerInfo.uid,
- power = playerInfo.power,
- serverId = playerInfo.serverId,
- head = playerInfo.head,
- headFrame = playerInfo.headFrame,
- }
- if playerInfo.uid and playerInfo.uid == playerUid then
- msgData.myRank = rank
- end
- end
- local fd = MiddleManager.getFDBySvrIndex(sourceServerId)
- InnerMsg.sendMsg(fd, msgData)
- playerInfoCheck(rankList)
- end
- -- 普通服请求某个排名的玩家数据
- function CS_GetPlayerInfo(sourceServerId, targetRank, targetUid, playerUid)
- local fd = MiddleManager.getFDBySvrIndex(sourceServerId)
- local msgData = InnerMsg.wl.WL_GODSATREA_QUERY_PLAYER_INFO
- msgData.res = -1
- msgData.playerInfo = {}
- msgData.playerUid = playerUid
- local rankList = GodsAreaDB.GetRankList()
- local rankData = rankList[targetRank]
- -- 数据异常
- if not rankData then
- return InnerMsg.sendMsg(fd, msgData)
- end
- -- 客户端的数据不是最新数据
- if rankData.uid and rankData.uid ~= targetUid then
- msgData.res = -2
- return InnerMsg.sendMsg(fd, msgData)
- end
- msgData.res = 0
- msgData.playerInfo.name = rankData.name
- msgData.playerInfo.lv = rankData.level
- msgData.playerInfo.head = rankData.head
- msgData.playerInfo.headFrame = rankData.headFrame
- msgData.playerInfo.rank = targetRank
- if rankData.uid then
- msgData.playerInfo.uid = rankData.uid
- msgData.playerInfo.defendObjList = rankData.heroList
- end
- InnerMsg.sendMsg(fd, msgData)
- end
- -- 普通服查询是否可以挑战某个排名
- function CS_Challenge_Query(sourceServerId, defenseRank, defenseUid, attackerUid)
- local rankList = GodsAreaDB.GetRankList()
- local fd = MiddleManager.getFDBySvrIndex(sourceServerId)
- local msgData = InnerMsg.wl.WL_GODSATREA_CHALLENGE_QUERY
- msgData.res = 0
- msgData.attackerUid = attackerUid
- msgData.defenseRank = defenseRank
- msgData.defenseUid = defenseUid
- msgData.defenseServerId = 0
- local rankData = rankList[defenseRank]
- if not rankData then
- msgData.res = -1
- return InnerMsg.sendMsg(fd, msgData)
- end
- -- 客户端的排行数据不是最新数据
- if rankData.uid and defenseUid ~= rankData.uid then
- msgData.res = -2
- return InnerMsg.sendMsg(fd, msgData)
- end
- -- 不能挑战比自己排名低的
- local attackerRank = getRankInfoByUid(rankList, attackerUid)
- -- if attackerRank ~= 0 and attackerRank < defenseRank then
- -- msgData.res = -3
- -- return InnerMsg.sendMsg(fd, msgData)
- -- end
- clearChallengeList()
- -- 如果有一方处于挑战/被挑战中, 则提醒
- local now = os.time()
- local aChallengeInfo = challengeList[attackerRank]
- local dChallengeInfo = challengeList[defenseRank]
- if aChallengeInfo and (aChallengeInfo.startTime + MAX_CHALLENGE_TIME) > now then
- msgData.res = 1
- end
- if dChallengeInfo and (dChallengeInfo.startTime + MAX_CHALLENGE_TIME) > now then
- msgData.res = 2
- end
- -- 把被挑战方加入正在挑战列表
- challengeList[defenseRank] = {
- startTime = now,
- attackerUid = attackerUid,
- attackerRank = attackerRank,
- defenseUid = defenseUid,
- }
- -- 如果挑战方在排行榜上, 也加入挑战列表
- if attackerRank ~= 0 then
- challengeList[attackerRank] = {
- startTime = now,
- attackerUid = attackerUid,
- attackerRank = attackerRank,
- defenseUid = defenseUid,
- defenseRank = defenseRank,
- }
- end
- msgData.defenseServerId = rankData.serverId or 0
- msgData.defenseName = rankData.name or "匿名玩家"
- InnerMsg.sendMsg(fd, msgData)
- end
- -- 普通服通知跨服挑战胜利
- function CS_Challenge_Win(sourceServerId, defenseRank, defenseUid, attackerUid, attackInfo)
- local rankList = GodsAreaDB.GetRankList()
- local defenseRankData = rankList[defenseRank]
- local attackerRank, attackerRankData = getRankInfoByUid(rankList, attackerUid)
- local msgData = InnerMsg.wl.WL_GODSATREA_UPDATE_CHENGHAO
- local fd = MiddleManager.getFDBySvrIndex(defenseRankData.serverId)
- local attackData = attackInfo
- attackData._id = defenseRankData._id
- -- 挑战者在榜上则用榜上的展示数据
- if attackerRank ~= 0 then
- attackData = attackerRankData
- end
- -- 挑战方排名高于防守方排名则不做其他操作
- if attackData.rank and attackData.rank ~= 0 and attackData.rank < defenseRankData.rank then
- return
- end
- -- 防守方当前是玩家
- if defenseRankData.uid then
- -- 通知失败方更新称号
- msgData.targetUid = defenseRankData.uid
- msgData.newRank = attackerRank
- msgData.isWinner = 0
- msgData.enemyName = attackData.name or ""
- InnerMsg.sendMsg(fd, msgData)
- end
- -- 挑战者是榜上玩家
- if attackerRank ~= 0 then
- -- 失败方排名更新为胜利方原排名
- defenseRankData.rank = attackerRank
- GodsAreaDB.UpdateRankData(attackerRank, defenseRankData)
- end
- -- 胜利方排名更新为失败方原排名
- attackData.rank = defenseRank
- GodsAreaDB.UpdateRankData(defenseRank, attackData)
- -- 通知胜利方更新称号
- fd = MiddleManager.getFDBySvrIndex(sourceServerId)
- msgData.targetUid = attackerUid
- msgData.newRank = defenseRank
- msgData.isWinner = 1
- msgData.enemyName = defenseRankData.name or ""
- InnerMsg.sendMsg(fd, msgData)
- local logStr = string.format("挑战胜利, attackerUid: %s, attackerRank: %d, defenseRank: %d, defenseOldUid: %s, defenseNowUid: %s",
- attackerUid, attackerRank, defenseRank, defenseUid, defenseRankData.uid or defenseUid)
- writeLog(Log.LOGID_OSS_GODSAREA_CHALLENGE ,logStr)
- end
- local function getTargetVideo(videoArray, playerUid)
- local len = 0
- local tbl = {}
- -- if not playerUid or not videoArray then
- -- return tbl
- -- end
- for _, videoData in ipairs(videoArray) do
- if videoData.combatInfo.defender.uuid == playerUid then
- len = len + 1
- tbl[len] = videoData
- end
- end
- return tbl
- end
- -- 普通服请求战斗录像数据
- function CS_Query_CombatVideo(sourceServerId, playerUid, targetRank)
- local videoArray = CombatVideo.getCombatVideosByType(CombatVideo.VIDEOTYPE_GODSAREA, targetRank)
- local fd = MiddleManager.getFDBySvrIndex(sourceServerId)
- local msgData = InnerMsg.wl.WL_GODSATREA_QUERY_RANK_VIDEO
- local rankList = GodsAreaDB.GetRankList()
- local rankData = rankList[targetRank]
- local targetUuid = rankData.uid or ""
- -- if not targetUuid then
- -- local rankCfg = GodsAreaConfig.rankList[targetRank]
- -- targetUuid = rankCfg.monsterOutID
- -- end
- local targetVideoArray = getTargetVideo(videoArray, targetUuid)
- msgData.playerUid = playerUid
- msgData.isFinish = 0
- msgData.videoData = {}
- local videoCnt = #targetVideoArray
- if videoCnt <= 0 then
- msgData.isFinish = 1
- InnerMsg.sendMsg(fd, msgData)
- return
- end
- for k,v in ipairs(targetVideoArray) do
- if k > CombatVideo.GODSAREA_RECORD_MAX_CNT then
- break
- end
- msgData.videoData = v
- if k == videoCnt or k == CombatVideo.GODSAREA_RECORD_MAX_CNT then
- msgData.isFinish = 1
- end
- InnerMsg.sendMsg(fd, msgData)
- end
- end
- -- 更新玩家基础数据
- function CS_Update_PlayerInfo(playerUid, newPlayerInfo)
- local rankList = GodsAreaDB.GetRankList()
- local rank, rankData = getRankInfoByUid(rankList, playerUid)
- if rank == 0 then
- return
- end
- for k,v in pairs(newPlayerInfo) do
- rankData[k] = v
- end
- GodsAreaDB.UpdateRankData(rank, rankData)
- end
- -- 更新英雄数据
- function CS_Update_HeroInfo(playerUid, newHeroInfo)
- local rankList = GodsAreaDB.GetRankList()
- local rank, rankData = getRankInfoByUid(rankList, playerUid)
- if rank == 0 then
- return
- end
- local isChange = false
- if newHeroInfo.opType == 0 then
- local rmIdx = getSameIdx(rankData.heroList, newHeroInfo.removeHeroUuid)
- if rmIdx then
- isChange = true
- -- table.remove(rankData.heroList, rmIdx)
- rankData.heroList[rmIdx] = nil
- rankData.power = newHeroInfo.power
- end
- elseif newHeroInfo.opType == 1 then
- for _, v in pairs(newHeroInfo.heroList) do
- local targetIdx = getSameIdx(rankData.heroList, v.heroUuid)
- if targetIdx then
- isChange = true
- rankData.heroList[targetIdx] = v
- rankData.power = newHeroInfo.power
- break
- end
- end
- else
- if next(newHeroInfo.heroList) then
- rankData.heroList = newHeroInfo.heroList
- rankData.power = newHeroInfo.power
- isChange = true
- end
- end
- if isChange then
- GodsAreaDB.UpdateRankData(rank, rankData)
- end
- end
- -- 通知游戏服, 给玩家发奖
- function CS_Send_Reward(fd, rankTb)
- local msgData = InnerMsg.wl.WL_GODSATREA_BROCAST_REWARD
- msgData.uid2RankTb = rankTb or {}
- InnerMsg.sendMsg(fd, msgData)
- end
|