-- 百战成神(跨服 CS) -- -- 职责: -- 1) 活动周期: Timer.oneMin/onHour -> timedStageHandle 开/关轮、发奖 -- 2) 玩家数据: 积分、排行、匹配、REGISTER/UPDATE_SHOW -- 3) 协议: 处理普通服 LW_* , 回 WL_* 到对应 logic fd -- 4) 断连补偿: 逻辑服 LW_HELLO -> onLogicServerConnect 补 ACT_START/待发奖 -- -- 对外导出: -- oneMin, onHour, onLogicServerConnect, syncActStateToAllConnected -- N2C_* (InnerHandler 注册) local InnerMsg = require("core.InnerMsg") local Util = require("common.Util") local Timer = require("core.Timer") local MiddleManager = require("middle.MiddleManager") local CommonDB = require("common.CommonDB") local BaiZhanChengShenDB = require("baiZhanChengShen.BaiZhanChengShenDB") local BaiZhanChengShenDefine = require("baiZhanChengShen.BaiZhanChengShenDefine") local BzcsLog = require("baiZhanChengShen.BaiZhanChengShenLog") ------------------------------------ 活动周期调度 ------------------------------------ local wDay -- 本轮发奖 Timer 已调度(进程内防重; rewardIssued 在调度前落库防 oneMin 重复触发) local rewardIssueInProgress = false -- 上一 tick 是否处于可挑战窗口(用于 0:10 到点补广播, 跨服重启后首次 tick 也会触发一次) local prevIsRunning = false -- 刷新缓存的当前星期 local function updateWDay() wDay = Util.getWeekDay() end -- 今日 0 点时间戳 local function getTodayStartTime() return Util.getDayStartTime(os.time()) end -- 将 baseTime 对齐到所在周开放首日 0:10 (getWeekDay: 1=周日, 7=周六) local function alignRoundStart(baseTime) local startW = BaiZhanChengShenDefine.BZCS_OPEN_WDAY_AREA[1] local endW = BaiZhanChengShenDefine.BZCS_OPEN_WDAY_AREA[2] local w = Util.getWeekDay(baseTime) local sub if startW <= endW then if w >= startW and w <= endW then sub = w - startW elseif w < startW then sub = w + 7 - startW else sub = w - startW end elseif w >= startW then sub = w - startW else sub = w + 7 - startW end local dayStart = Util.getDayStartTime(baseTime) return dayStart - sub * 86400 + BaiZhanChengShenDefine.BZCS_START_SEC end -- 由开局时间推算结束日(周日) 23:00 时间戳 local function calcRoundEnd(startTime) local openStart = alignRoundStart(startTime) local endDayOffset = BaiZhanChengShenDefine.GetOpenEndDayOffset() local endDayStart = Util.getDayStartTime(openStart) + endDayOffset * 86400 return endDayStart + BaiZhanChengShenDefine.BZCS_END_SEC end -- 当前是否在周六~周日开放日 local function isInOpenWday() if not wDay then updateWDay() end local startW = BaiZhanChengShenDefine.BZCS_OPEN_WDAY_AREA[1] local endW = BaiZhanChengShenDefine.BZCS_OPEN_WDAY_AREA[2] if startW <= endW then return wDay >= startW and wDay <= endW end return wDay >= startW or wDay <= endW end -- 本轮在 DB 中仍有效(未过 endTime 且处于开放周), 含 startTime 前待开启时段 local function hasActiveRound(now) now = now or os.time() local startTime, endTime = BaiZhanChengShenDB.GetActivityTimes() if startTime <= 0 or endTime <= 0 then return false end if now >= endTime then return false end return isInOpenWday() end -- 活动是否处于可挑战窗口(已过本轮 startTime) local function isRunning() local now = os.time() local startTime, endTime = BaiZhanChengShenDB.GetActivityTimes() if startTime == 0 or endTime == 0 then return false end if now < startTime or now > endTime then return false end return isInOpenWday() end -- 首轮开启前置: 跨服基准开服天数达到阈值(最老服) local function isFirstRoundOpenEligible() local openDay = CommonDB.getServerOpenDay() or 0 return openDay >= BaiZhanChengShenDefine.BZCS_OPEN_SVR_DAY end -- 严格判断当前是否可开启新一轮: -- 周末开放日 + 已过本轮周六 0:10 + 未超过本轮周日 23:00 -- 首轮还需满足跨服开服天数>=45; 非首轮需满足周期间隔且上轮已结束 local function canOpenNewRoundNow(now, lastReset, startTime, endTime) now = now or os.time() if not isInOpenWday() then return false end local roundStart = alignRoundStart(now) if now < roundStart then return false end local roundEnd = calcRoundEnd(roundStart) if now > roundEnd then return false end if lastReset == 0 then if not isFirstRoundOpenEligible() then return false end return true end if Util.diffDay(lastReset) < BaiZhanChengShenDefine.BZCS_CYCLE_DAYS then return false end if startTime > 0 and now < endTime then return false end return true end -- 汇总本次 WL 广播已通知的逻辑服 serverId(MiddleManager_GetAllFD 返回 SVRINDEX_2_FD, key 即 serverId) local function formatNotifyServerIds(svrIndex2Fd) local seen, serverIds = {}, {} for serverId, _ in pairs(svrIndex2Fd or {}) do if serverId and not seen[serverId] then seen[serverId] = true serverIds[#serverIds + 1] = serverId end end -- 合服扩展连接(仅 MERGE 表有登记时补充) for serverId, _ in pairs(SVRINDEX_2_FD_MERGE or {}) do if serverId and not seen[serverId] then seen[serverId] = true serverIds[#serverIds + 1] = serverId end end table.sort(serverIds) return table.concat(serverIds, ",") end -- 向单个逻辑服 fd 推送当前活动状态(重连/跨服重启后补偿, 避免错过广播) local function sendActStateToFd(fd) if not fd then return end local serverId = MiddleManager.FD_2_SVRINDEX[fd] or 0 local startTime, endTime = BaiZhanChengShenDB.GetActivityTimes() if hasActiveRound() then local msgData = InnerMsg.wl.WL_BZCS_ACT_START msgData.startTime = startTime msgData.endTime = endTime InnerMsg.sendMsg(fd, msgData) BzcsLog.logAction("act_open", string.format( "tag=sync_fd serverId=%s fd=%s start=%s end=%s running=%s", serverId, fd, startTime, endTime, isRunning() and 1 or 0 )) else local msgData = InnerMsg.wl.WL_BZCS_ACT_END InnerMsg.sendMsg(fd, msgData) BzcsLog.logAction("act_close", string.format( "tag=sync_fd serverId=%s fd=%s start=%s end=%s running=0", serverId, fd, startTime, endTime )) end end -- 逻辑服连上跨服时: 同步活动状态 + 补发断连期间缓存的周期奖励 function onLogicServerConnect(fd) if _G.is_middle ~= true or not fd then return end sendActStateToFd(fd) local serverId = MiddleManager.FD_2_SVRINDEX[fd] if not serverId then return end local pending = BaiZhanChengShenDB.TakePendingRewards(serverId) if #pending > 0 then local msgData = InnerMsg.wl.WL_BZCS_ISSUE_REWARD msgData.rewardList = pending InnerMsg.sendMsg(fd, msgData) BzcsLog.logAction("reward_reissue", string.format("serverId=%s cnt=%s", serverId, #pending)) end end -- 跨服启动后向已连接逻辑服同步活动状态 function syncActStateToAllConnected() if _G.is_middle ~= true then return end local fdList = MiddleManager.MiddleManager_GetAllFD() for _, fd in pairs(fdList) do sendActStateToFd(fd) end end -- 广播活动开启, 普通服写入 KEY_BZCS_START_TIME; tag 用于区分开轮/时间修正等场景 function ActOpen(startTime, tag) tag = tag or "broadcast" local msgData = InnerMsg.wl.WL_BZCS_ACT_START msgData.startTime = startTime or os.time() local _, endTime = BaiZhanChengShenDB.GetActivityTimes() msgData.endTime = endTime local svrIndex2Fd = MiddleManager.MiddleManager_GetAllFD() local fdCnt = 0 for serverId, fd in pairs(svrIndex2Fd) do InnerMsg.sendMsg(fd, msgData) fdCnt = fdCnt + 1 end BzcsLog.logAction("act_open", string.format( "tag=%s start=%s end=%s fdCnt=%s running=%s servers=%s", tag, msgData.startTime, msgData.endTime or 0, fdCnt, isRunning() and 1 or 0, formatNotifyServerIds(svrIndex2Fd) )) end -- 广播活动结束; tag 用于区分正常结算/放弃上轮等场景 function ActEnd(tag) tag = tag or "broadcast" local startTime, endTime = BaiZhanChengShenDB.GetActivityTimes() local msgData = InnerMsg.wl.WL_BZCS_ACT_END local svrIndex2Fd = MiddleManager.MiddleManager_GetAllFD() local fdCnt = 0 for serverId, fd in pairs(svrIndex2Fd) do InnerMsg.sendMsg(fd, msgData) fdCnt = fdCnt + 1 end BzcsLog.logAction("act_close", string.format( "tag=%s start=%s end=%s fdCnt=%s rewardIssued=%s servers=%s", tag, startTime or 0, endTime or 0, fdCnt, BaiZhanChengShenDB.IsRewardIssued() and 1 or 0, formatNotifyServerIds(svrIndex2Fd) )) end -- 按 serverId 汇总待发奖 {{uuid,rank},...} local function groupRewardsByServer(playerList) local byServer = {} for _, info in ipairs(playerList) do local uuid, rank, serverId = info[1], info[2], info[3] if serverId then local list = byServer[serverId] if not list then list = {} byServer[serverId] = list end list[#list + 1] = {uuid, rank} end end return byServer end -- 向指定逻辑服批量下发排名奖励(每服一次 WL); 未连接则整批入 pending local function issueRewardBatch(serverId, rewardList) if not rewardList or #rewardList == 0 then return end local fd = MiddleManager.getFDBySvrIndex(serverId) if fd then local msgData = InnerMsg.wl.WL_BZCS_ISSUE_REWARD msgData.rewardList = rewardList InnerMsg.sendMsg(fd, msgData) BzcsLog.logAction("reward_issue_send", string.format("serverId=%s cnt=%s", serverId, #rewardList)) else BaiZhanChengShenDB.AddPendingRewards(serverId, rewardList) BzcsLog.logAction("reward_issue_offline", string.format("serverId=%s cnt=%s", serverId, #rewardList)) end end -- 活动结束发奖: 按逻辑服批量 WL_BZCS_ISSUE_REWARD(服与服之间 2s 节流) function IssueRewardManager() if BaiZhanChengShenDB.IsRewardIssued() or rewardIssueInProgress then return end local rewardPlayers = BaiZhanChengShenDB.GetAllPlayersForReward() local byServer = groupRewardsByServer(rewardPlayers) local serverList = {} for serverId, rewardList in pairs(byServer) do serverList[#serverList + 1] = {serverId, rewardList} end if #serverList == 0 then BaiZhanChengShenDB.SetRewardIssued(true) return end rewardIssueInProgress = true -- 先落库标记, 避免异步 Timer 完成前 timedStageHandle/oneMin 重复调度 BaiZhanChengShenDB.SetRewardIssued(true) BzcsLog.logAction("reward_issue", string.format("playerCnt=%s serverCnt=%s", #rewardPlayers, #serverList)) local delay = 0 local onlineCnt, pendingCnt = 0, 0 for _, entry in ipairs(serverList) do local serverId, rewardList = entry[1], entry[2] local fd = MiddleManager.getFDBySvrIndex(serverId) if not fd then BaiZhanChengShenDB.AddPendingRewards(serverId, rewardList) pendingCnt = pendingCnt + 1 else delay = delay + 2 onlineCnt = onlineCnt + 1 Timer.addLater(delay, issueRewardBatch, serverId, rewardList) end end rewardIssueInProgress = false BzcsLog.logAction("reward_issue_scheduled", string.format( "onlineCnt=%s pendingCnt=%s delaySec=%s", onlineCnt, pendingCnt, delay )) end -- 开启新周期: 重置 DB 并 ActOpen local function newRoundHandle(now) now = now or os.time() local startTime = alignRoundStart(now) local endTime = calcRoundEnd(startTime) BaiZhanChengShenDB.ResetForNewRound(startTime, endTime) ActOpen(startTime, "new_round") end -- 结束当前周期: 发奖 + ActEnd local function endRoundHandle() if BaiZhanChengShenDB.IsRewardIssued() or rewardIssueInProgress then return end BzcsLog.logAction("act_settle", "begin_issue_reward") IssueRewardManager() ActEnd("end_round") end -- 放弃上轮未完成的周期发奖(满21天开新轮时不再补发) local function abandonUnissuedRewards() if BaiZhanChengShenDB.IsRewardIssued() then return end BzcsLog.logAction("reward_abandon", "new_round_skip") BaiZhanChengShenDB.SetRewardIssued(true) BaiZhanChengShenDB.ClearAllPendingRewards() ActEnd("abandon_new_round") end -- 是否应开启新轮; 条件满足则执行 newRoundHandle 并广播 local function tryOpenNewRound(now, lastReset, startTime, endTime) if not canOpenNewRoundNow(now, lastReset, startTime, endTime) then return false end if lastReset > 0 and not BaiZhanChengShenDB.IsRewardIssued() then abandonUnissuedRewards() end newRoundHandle(now) return true end -- 周期阶段机 (oneMin/onHour 调用): -- 1) 严格满足开新轮条件(含首轮45天门槛、周末窗口 0:10~23:00、间隔/结束检查) -> newRoundHandle + ActOpen -- 2) 已过 endTime 且未发奖 -> endRoundHandle -- 3) 刚进入可挑战窗口(如周六0:10) -> ActOpen 补偿逻辑服 local function timedStageHandle() local now = os.time() local lastReset = BaiZhanChengShenDB.GetLastResetTime() local startTime, endTime = BaiZhanChengShenDB.GetActivityTimes() local running = isRunning() if tryOpenNewRound(now, lastReset, startTime, endTime) then prevIsRunning = isRunning() return end if startTime > 0 and now >= endTime and not BaiZhanChengShenDB.IsRewardIssued() then endRoundHandle() prevIsRunning = false return end if running and not prevIsRunning then ActOpen(startTime, "window_open") end prevIsRunning = running end -- Timer 每分钟(跳过整点)检查阶段 function oneMin() if _G.is_middle ~= true then return end if Util.getMin() == 0 then return end timedStageHandle() end -- Timer 每小时检查阶段, 0 点刷新星期 function onHour(hour) if _G.is_middle ~= true then return end if hour == 0 or not wDay then updateWDay() end timedStageHandle() end ------------------------------------ N2C (普通服 LW -> 本模块 -> WL 回包) ------------------------------------ -- msg 中带 sourceServerId/playerUuid, 通过 MiddleManager.getFDBySvrIndex 回包 -- 向逻辑服 fd 发送 WL 协议 local function sendWL(fd, msgData) if not fd then return false end InnerMsg.sendMsg(fd, msgData) return true end -- 业务失败时回 WL_BZCS_TIPS local function errTips(sourceServerId, playerUuid, errCode) BzcsLog.logAction("err_tips", string.format("serverId=%s uuid=%s err=%s", sourceServerId or 0, playerUuid or "", errCode or 0)) local msgData = InnerMsg.wl.WL_BZCS_TIPS msgData.playerUuid = playerUuid msgData.errCode = errCode or 0 local fd = MiddleManager.getFDBySvrIndex(sourceServerId) if not fd then return end sendWL(fd, msgData) end -- LW_BZCS_MATCH -> WL_BZCS_MATCH (±500步进扩大, 窗口内随机匹配最多3人; refreshRanks 非空时仅刷新展示) function N2C_Match(msg) local fd = MiddleManager.getFDBySvrIndex(msg.sourceServerId) if not isRunning() then return errTips(msg.sourceServerId, msg.playerUuid, BaiZhanChengShenDefine.BZCS_ERR_NOT_OPEN) end local pinfo = BaiZhanChengShenDB.GetPlayer(msg.playerUuid) local myScore = pinfo and pinfo.score or BaiZhanChengShenDefine.BZCS_INIT_SCORE local refreshRanks = msg.refreshRanks local opponents if refreshRanks and #refreshRanks > 0 then opponents = BaiZhanChengShenDB.GetMatchOpponentsByRanks(refreshRanks) if #opponents < #refreshRanks then opponents = BaiZhanChengShenDB.GetMatchOpponents(msg.playerUuid, myScore, {}) end else opponents = BaiZhanChengShenDB.GetMatchOpponents(msg.playerUuid, myScore, {}) end local msgData = InnerMsg.wl.WL_BZCS_MATCH msgData.playerUuid = msg.playerUuid msgData.myScore = myScore msgData.myRank = BaiZhanChengShenDB.GetRankByUuid(msg.playerUuid) msgData.opponentList = opponents sendWL(fd, msgData) end -- LW_BZCS_RANK_LIST -> WL_BZCS_RANK_LIST function N2C_RankList(msg) local fd = MiddleManager.getFDBySvrIndex(msg.sourceServerId) local msgData = InnerMsg.wl.WL_BZCS_RANK_LIST msgData.playerUuid = msg.playerUuid msgData.rankList = BaiZhanChengShenDB.GetRankList(BaiZhanChengShenDefine.BZCS_RANK_MAX) msgData.myRankInfo = BaiZhanChengShenDB.BuildPlayerRankInfo(msg.playerUuid) sendWL(fd, msgData) end -- LW_BZCS_OPPONENT_INFO -> WL_BZCS_OPPONENT_INFO function N2C_OpponentInfo(msg) local fd = MiddleManager.getFDBySvrIndex(msg.sourceServerId) local target = BaiZhanChengShenDB.GetPlayerByRank(msg.targetRank) local msgData = InnerMsg.wl.WL_BZCS_OPPONENT_INFO msgData.playerUuid = msg.playerUuid msgData.res = target and 0 or -1 msgData.targetInfo = BaiZhanChengShenDB.BuildOpponentInfoSnapshot(target) or {} sendWL(fd, msgData) end -- LW_BZCS_OPPONENT_LINEUP -> WL_BZCS_OPPONENT_LINEUP (含机器人 showInfo) function N2C_OpponentLineup(msg) local fd = MiddleManager.getFDBySvrIndex(msg.sourceServerId) local target = BaiZhanChengShenDB.GetPlayerByRank(msg.targetRank) local msgData = InnerMsg.wl.WL_BZCS_OPPONENT_LINEUP msgData.playerUuid = msg.playerUuid msgData.targetRank = msg.targetRank or 0 msgData.showInfo = target and target.showInfo or {} msgData.isRobot = target and target.isRobot or 0 sendWL(fd, msgData) end -- LW_BZCS_CAN_FIGHT -> WL_BZCS_CAN_FIGHT (按开战时全服名次锁定对手, 扣次在 NS C2N_CanFight) function N2C_CanFight(msg) local fd = MiddleManager.getFDBySvrIndex(msg.sourceServerId) if not isRunning() then return errTips(msg.sourceServerId, msg.playerUuid, BaiZhanChengShenDefine.BZCS_ERR_NOT_OPEN) end local targetRank = msg.targetRank if not targetRank or targetRank < 1 then return errTips(msg.sourceServerId, msg.playerUuid, BaiZhanChengShenDefine.BZCS_ERR_TARGET_INVALID) end local target = BaiZhanChengShenDB.GetPlayerByRank(targetRank) if not target then return errTips(msg.sourceServerId, msg.playerUuid, BaiZhanChengShenDefine.BZCS_ERR_TARGET_INVALID) end if target.uuid == msg.playerUuid then return errTips(msg.sourceServerId, msg.playerUuid, BaiZhanChengShenDefine.BZCS_ERR_TARGET_INVALID) end local msgData = InnerMsg.wl.WL_BZCS_CAN_FIGHT msgData.playerUuid = msg.playerUuid msgData.targetRank = targetRank msgData.defUuid = target.uuid msgData.defServerId = target.serverId or 0 local si = target.showInfo or {} msgData.defName = si.name or "" msgData.defScore = target.score or BaiZhanChengShenDefine.BZCS_INIT_SCORE msgData.isRobot = target.isRobot or 0 msgData.res = 0 sendWL(fd, msgData) end -- LW_BZCS_REGISTER 首次挑战注册跨服玩家(保留已有积分/firstJoinTime) function N2C_Register(msg) local pinfo = msg.playerInfo if not pinfo or not pinfo.uuid then return end local old = BaiZhanChengShenDB.GetPlayer(pinfo.uuid) if old then pinfo.score = old.score pinfo.scoreTime = old.scoreTime if (old.firstJoinTime or 0) > 0 then pinfo.firstJoinTime = old.firstJoinTime end else pinfo.score = BaiZhanChengShenDefine.BZCS_INIT_SCORE pinfo.firstJoinTime = pinfo.firstJoinTime or os.time() pinfo.scoreTime = os.time() end pinfo.isRobot = 0 BaiZhanChengShenDB.UpsertPlayer(pinfo.uuid, pinfo) BzcsLog.logAction("register", string.format("uuid=%s serverId=%s score=%s firstJoin=%s", pinfo.uuid, pinfo.serverId or 0, pinfo.score or 0, pinfo.firstJoinTime or 0)) end -- LW_BZCS_UPDATE_SHOW 增量合并展示数据 function N2C_UpdateShow(msg) local pinfo = BaiZhanChengShenDB.GetPlayer(msg.playerUuid) if not pinfo or not msg.showInfo then return end pinfo.showInfo = pinfo.showInfo or {} BaiZhanChengShenDefine.MergeShowInfo(pinfo.showInfo, msg.showInfo) BaiZhanChengShenDB.UpsertPlayer(msg.playerUuid, pinfo) BzcsLog.logAction("update_show", string.format("uuid=%s type=%s race=%s", msg.playerUuid, msg.updateType or 0, msg.race or 0)) end -- REGISTER 尚未落库时, 用 FIGHT_END 包字段建最小攻方记录(兜底乱序/丢包) local function ensureAtkRegistered(msg) local atkUuid = msg and msg.atkUuid if not atkUuid or atkUuid == "" then return end if BaiZhanChengShenDB.GetPlayer(atkUuid) then return end local pinfo = { uuid = atkUuid, serverId = msg.atkServerId or 0, score = BaiZhanChengShenDefine.BZCS_INIT_SCORE, firstJoinTime = os.time(), scoreTime = os.time(), isRobot = 0, showInfo = { name = msg.atkName or "" }, } BaiZhanChengShenDB.UpsertPlayer(atkUuid, pinfo) BzcsLog.logAction("register_fallback", string.format("uuid=%s serverId=%s", atkUuid, pinfo.serverId)) end -- LW_BZCS_FIGHT_END 整场结算: 攻守加减分, WL 通知攻方; 真人守方另发 WL_BZCS_DEF_NOTIFY function N2C_FightEnd(msg) local atkUuid = msg.atkUuid local defUuid = msg.defUuid local atkWin = msg.atkWin == 1 local atkDelta = atkWin and BaiZhanChengShenDefine.BZCS_ATK_WIN_SCORE or BaiZhanChengShenDefine.BZCS_ATK_LOSE_SCORE local defDelta = atkWin and BaiZhanChengShenDefine.BZCS_DEF_LOSE_SCORE or BaiZhanChengShenDefine.BZCS_DEF_WIN_SCORE ensureAtkRegistered(msg) local atkScore = BaiZhanChengShenDB.UpdateScore(atkUuid, atkDelta) local defScore = BaiZhanChengShenDB.UpdateScore(defUuid, defDelta) if not atkScore then BzcsLog.logAction("fight_end_atk_score_fail", string.format( "atk=%s atkSvr=%s delta=%s", atkUuid or "", msg.atkServerId or 0, atkDelta )) atkScore = BaiZhanChengShenDefine.BZCS_INIT_SCORE + atkDelta end BzcsLog.logAction("fight_end", string.format( "atk=%s def=%s atkWin=%s atkDelta=%s defDelta=%s atkScore=%s defScore=%s atkSvr=%s defSvr=%s", atkUuid or "", defUuid or "", msg.atkWin or 0, atkDelta, defDelta, atkScore, defScore or -1, msg.atkServerId or 0, msg.defServerId or 0 )) local atkFd = MiddleManager.getFDBySvrIndex(msg.atkServerId) local wlAtk = InnerMsg.wl.WL_BZCS_FIGHT_END wlAtk.playerUuid = atkUuid wlAtk.atkWin = msg.atkWin or 0 wlAtk.scoreChange = atkDelta wlAtk.myScore = atkScore wlAtk.defName = msg.defName or "" wlAtk.defServerId = msg.defServerId or 0 wlAtk.raceResults = msg.raceResults or {} if not sendWL(atkFd, wlAtk) then BzcsLog.logAction("fight_end_wl_fail", string.format("atk=%s atkSvr=%s", atkUuid or "", msg.atkServerId or 0)) end local defInfo = BaiZhanChengShenDB.GetPlayer(defUuid) if defInfo and defInfo.isRobot ~= 1 and defInfo.serverId and defScore then local defFd = MiddleManager.getFDBySvrIndex(defInfo.serverId) if defFd then local wlDef = InnerMsg.wl.WL_BZCS_DEF_NOTIFY wlDef.playerUuid = defUuid wlDef.atkName = msg.atkName or "" wlDef.atkServerId = msg.atkServerId or 0 wlDef.atkWin = msg.atkWin == 1 and 0 or 1 wlDef.scoreChange = defDelta wlDef.myScore = defScore wlDef.raceResults = msg.raceResults or {} sendWL(defFd, wlDef) end elseif defInfo and defInfo.isRobot ~= 1 and not defScore then BzcsLog.logAction("fight_end_def_score_fail", string.format( "def=%s defSvr=%s delta=%s", defUuid or "", defInfo.serverId or 0, defDelta )) end end