123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379 |
- local skynet = require "skynet"
- local battleCore = require "battle.battleCore"
- local battleLog = require "battle.battleLog"
- local battleCode = require "battle.battleCode"
- local battleDefine = require "battle.battleDefine"
- local nodeMgr = require "nodeMgr"
- local httpc = require "http.httpc"
- local md5 = require "md5"
- local machine = require "machine"
- local code = require "code"
- local util_user = require "utils.util_user"
- local gameConst = require("const.gameConst")
- local battleAdapt = require "adapt.battleAdapt"
- local sessionData = require("data.session")
- local battleData = require("data.battle")
- local nodename = skynet.getenv("nodeName")
- local root = class("Battle")
- function root:ctor(matchInfo, battleParams, settleNodeInfo)
- self.matchNodeInfo = {}
- self.matchNodeInfo.nodeName = matchInfo.matchNode
- self.matchNodeInfo.agent = matchInfo.matchAgent
- self.roomId = matchInfo.roomId
- self.matchId = matchInfo.matchId
- self.battleId = matchInfo.battleId
- self.isMatchSettle = matchInfo.isMatchSettle -- 结算经过业务服
- self.settleNodeInfo = settleNodeInfo -- 结算节点
- self.battleParams = battleParams
- local w = battleParams.w
- local h = battleParams.h
- local debugJsonObj = battleParams.debugJsonObj
- self.core = battleCore.new(self, matchInfo.battleReal, matchInfo.battleType, w, h, debugJsonObj)
- self.record = {}
- self.isActive = true
- end
- -- 获取战斗标示
- function root:get_core_id()
- return string.format("%s:%s:%s", self.matchNodeInfo.nodeName, self.matchId, self.battleId)
- end
- function root:enableRecord()
- return true
- end
- function root:addRecord(protoName, msg)
- if self:enableRecord() then
- table.insert(self.record, {proto = protoName, data = msg})
- end
- end
- local protos = {
- "on_battle_qipan_info",
- "on_battle_operate_info",
- "on_battle_start",
- "on_battle_finish",
- "on_battle_attack",
- "on_battle_attack_finish",
- "on_battle_create_info"
- }
- function root:notifyPlayer(uid, protoName, msg)
- if uid == nil or is_robot(uid) or is_empty(protoName) then
- return
- end
- local uidList = self.core:get_real_uid_list()
- if uidList[1] == uid and table.include(protos, protoName) then
- self:addRecord(protoName, msg)
- end
- util_user:user_proto_notify(uid, protoName, msg)
- end
- -- game节点结算
- function root:game_player_settle(uid, msg)
- -- 机器人
- if uid == nil or is_robot(uid) then
- return
- end
- -- 玩家不在线
- local nodeInfo = util_user:user_get_cluster_info(uid, "game")
- if not nodeMgr.is_node_info_valid(nodeInfo) then
- nodeMgr.send("game1_1", ".settleSrv", "offline_settle", uid, msg)
- return
- end
- util_user:user_send_game_agent(uid, "battle.settleBattle", msg)
- end
- function root:notifyClientLog(uid, logStr)
- if uid == nil or is_robot(uid) or is_empty(logStr) then
- return
- end
- battleLog:logClient(logStr)
- -- TODO: Debug 测试代码,上线前修改过来.
- util_user:user_notify_client_log(uid, logStr)
- end
- function root:recordOpenLog(...)
- local logUtil = require "utils.serverLogUtil"
- logUtil.logOpen(...)
- end
- function root:logEvent(...)
- util_user:log_event(...)
- end
- function root:getBattleNode()
- return nodename
- end
- function root:getBattleId()
- return self.battleId
- end
- function root:getBattleParams()
- return self.battleParams
- end
- local GAME_SALT_MD5 = "0bdb9a5863c8c9063a42f38a9d5166fe" -- 游戏服加盐 md5
- local function sendRecord(battleNode, battleStartTime, battleId, version, record)
- local server = machine.get("record_server")
- if is_nil(server) then
- return
- end
- local url = "/record/add?sign="
- local head = {["Content-Type"] = "application/json"}
- local body =
- cjson_encode(
- {
- node = tostring(battleNode),
- startTime = tonumber(battleStartTime),
- id = tonumber(battleId),
- version = tostring(version),
- record = cjson_encode(record)
- }
- )
- url = url .. md5.sumhexa(body .. GAME_SALT_MD5)
- local ok, errCode, response = pcall(httpc.request, "POST", server, url, nil, head, body)
- if not ok then
- battleLog:logError(
- string.format(
- "添加录像失败 battleNode=%s battleStartTime=%s battleId=%s version=%s",
- battleNode,
- battleStartTime,
- battleId,
- version
- )
- )
- end
- if errCode ~= 200 then
- battleLog:logError(
- string.format(
- "添加录像失败 battleNode=%s battleStartTime=%s battleId=%s version=%s response=%s",
- battleNode,
- battleStartTime,
- battleId,
- version,
- tostring(response and cjson_decode(response))
- )
- )
- end
- end
- -- 开始战斗
- function root:startBattle(playerList, viewerList)
- local battleInfo = {
- matchId = self.matchId,
- battleId = self.battleId,
- nodeName = nodename,
- agent = skynet.self()
- }
- for _, v in ipairs(playerList) do
- if not is_robot(v.uid) then
- sessionData:user_update_cluster_info(v.uid, "battle", battleInfo)
- end
- end
- self.core:startBattle(playerList, viewerList)
- end
- -- 结算
- function root:settleBattle(result)
- -- 测试战斗类型
- if battleAdapt:isAiTestBattle(self.core.battleType) then
- log.warning(
- "settleBattle battleId[%s] settleNodeInfo[%s]",
- tostring(self.battleId),
- tostring(self.settleNodeInfo)
- )
- if nodeMgr.is_node_info_valid(self.settleNodeInfo) then
- nodeMgr.send_with_node_info(self.settleNodeInfo, "settle", result)
- else
- nodeMgr.send("test", ".aiSrv", "settle", result)
- end
- return
- end
- -- 组队
- -- 业务服结算
- if self.isMatchSettle then
- nodeMgr.send_with_node_info(self.matchNodeInfo, "match_settle", self.roomId, result)
- return
- end
- for _, v in ipairs(self.core:getAllPlayer()) do
- self:game_player_settle(v.uid, result)
- end
- end
- -- 消耗战斗
- function root:dismissBattle(reason)
- self.isActive = false
- battleLog:logWarning(string.format("开始销毁对战服务并退出 battleId=%s reason=%s", self.battleId, reason))
- nodeMgr.send_with_node_info(self.matchNodeInfo, "destory_battle", self.roomId)
- local uidList = self.core:get_real_uid_list()
- for _, v in ipairs(uidList) do
- -- 清除玩家战斗节点信息
- battleData:user_clear_battle_info(v)
- self:notifyPlayer(v, "on_battle_finish", {code = battleCode.OK})
- end
- if self:enableRecord() then
- sendRecord(self:getBattleNode(), self.core.battleStartTime, self:getBattleId(), 1.0, self.record)
- end
- skynet.call(".BattleMgr", "lua", "battleLeave", self.battleId, skynet.self())
- end
- function root:loginBattle(uid)
- battleLog:logInfo(string.format("玩家%d登入对战", uid))
- local playerData = self.core:getPlayer(uid)
- if not playerData then
- -- 围观进入
- self.core:viewerLoginBattle(uid)
- return
- end
- self.core:loginBattle(playerData)
- -- self:playFinish(uid, self.core:getCurRound())
- end
- function root:logoutBattle(uid)
- battleLog:logInfo(string.format("玩家%d登出对战", uid))
- local playerData = self.core:getPlayer(uid)
- if not playerData then
- return
- end
- self.core:logoutBattle(playerData)
- -- self.core:dismissBattle("force")
- end
- -- 玩家是否在战斗中
- function root:is_user_in_battle(uid)
- local playerData = self.core:getPlayer(uid)
- if playerData then
- return true
- end
- return false
- end
- function root:operate(uid, ids, exSkillGridId)
- if not ids or #ids < battleDefine.MIN_LINK_BLOCK then
- return {code = battleCode.BATTLE_COUNT_LESS}
- end
- local playerData = self.core:getPlayer(uid)
- if not playerData then
- return {code = battleCode.BATTLE_PLAYER_NOT_EXIST}
- end
- if self.core:getNextLinkUid() ~= uid then
- return {code = battleCode.BATTLE_ROUND_ERR}
- end
- if self.core:isPlayerOperated(playerData) then
- return {code = battleCode.BATTLE_OPERATED}
- end
- if not self.core:operate(playerData, ids, exSkillGridId) then
- if IS_TEST then
- self.core:sendTestGrids(playerData)
- end
- return {code = battleCode.BATTLE_CANNOT_LINK}
- end
- return {code = battleCode.OK}
- end
- function root:playFinish(uid, round)
- local playerData = self.core:getPlayer(uid)
- if not playerData then
- return {code = battleCode.BATTLE_PLAYER_NOT_EXIST}
- end
- if self.core:getCurRound() ~= round then
- return {code = battleCode.BATTLE_ROUND_EXPIRED}
- end
- self.core:playFinish(playerData, uid, round)
- return {code = battleCode.OK}
- end
- -- 玩家托管
- function root:auto_link(uid, isAuto)
- local playerData = self.core:getPlayer(uid)
- if not playerData then
- return {code = battleCode.BATTLE_PLAYER_NOT_EXIST}
- end
- self.core:updateAutoLink(playerData, isAuto)
- return {code = code.OK}
- end
- function root:info(uid)
- local playerData = self.core:getPlayer(uid)
- if not playerData then
- return {code = battleCode.BATTLE_PLAYER_NOT_EXIST}
- end
- self.core:info(playerData)
- return {code = battleCode.OK}
- end
- function root:debug(uid, debugType, debugArgs)
- local playerData = self.core:getPlayer(uid)
- if not playerData then
- return {code = battleCode.BATTLE_PLAYER_NOT_EXIST}
- end
- local errorMsg
- if IS_TEST then
- errorMsg = self.core:debug(playerData, debugType, debugArgs)
- end
- return {code = battleCode.OK, errorMsg = errorMsg}
- end
- function root:chat(uid, id, text)
- local playerData = self.core:getPlayer(uid)
- if not playerData then
- return {code = battleCode.BATTLE_PLAYER_NOT_EXIST}
- end
- self.core:chat(playerData, id, text)
- return {code = battleCode.OK}
- end
- function root:getOverview(uid)
- local playerData = self.core:getPlayer(uid)
- if not playerData then
- return {code = battleCode.BATTLE_PLAYER_NOT_EXIST}
- end
- local msg = self.core:getOverview(playerData)
- msg.code = battleCode.OK
- return msg
- end
- function root:addViewers(uid)
- self.core:addViewers(uid)
- end
- function root:deleteViewers(uid)
- self.core:deleteViewers(uid)
- end
- -- 测试对战服务是否还在
- function root:ping(uid)
- local playerData = self.core:getPlayer(uid)
- return playerData and true or false
- end
- function root:fastSettle(uid)
- log.info("battle fastSettle uid = %s", tostring(uid))
- self.core:settleBattle(2, nil, uid)
- end
- -- 服务端是否启用AI
- function root:isServerBattleAiOpen()
- return true
- end
- return root
|