local BattleAgent_Model = {} local private = {agentList = {}} local EventSystem = require('Event/EventSystem') local battle_begin_pb = require 'Proto/battle_begin_pb' local ping_test_pb = require 'Proto/ping_test_pb' local BattleAgentPingTimeOut = 3 function BattleAgent_Model.OnStartup() NetManager.RegisterMsgCB(MessageEnums.MessageGetBattleAgentList, private.GetBattleAgentListResp) NetManager.RegisterMsgCB(MessageEnums.MessageSelectBattleAgent, private.SelectBattleAgentResp) NetManager.RegisterMsgCB(MessageEnums.MessageGetKcpPingServerInfo, private.GetKCPBattleAgentListResp) EventSystem.Regist(EventID.OnNetworkPingCompleted, private.OnNetworkPingCompleted) private.agentList = {} private.curSelectName = nil private.openList = false --kcp 连接的代理服 private.kcpAgentList = {} end --region -- **************** 协议部分 ******************* -- -- 请求全部的地址列表,并返回当前正在连接的 function BattleAgent_Model.GetBattleAgentListReq(openList) local msg = battle_begin_pb.GetBattleAgentListReq() private.openList = openList NetManager.SendMessage(MessageEnums.MessageGetBattleAgentList, msg) end function private.GetBattleAgentListResp(msgResp) if msgResp.Resp.Code == 0 then for _, v in ipairs(msgResp.agentList) do local agentData for _, data in ipairs(private.agentList) do if data.name == v.name then agentData = data break end end if agentData then agentData.ip = v.ip agentData.pingHost = string.gsub(v.ip, "http://", "") agentData.delay = v.delay else table.insert(private.agentList, { name = v.name, ip = v.ip, pingHost = string.gsub(v.ip, "http://", ""), delay = v.delay, lastPingTime = 0, -- 初始化时候将上次ping过的时间设置为0 }) end end private.curSelectName = msgResp.lastName if private.openList then EventSystem.Dispatch(EventID.BattleAgent_OpenAgentList) private.openList = false end MDL.BattleAgent.RequestAllPing() end end -- 请求下一次进入战斗连接的地址 function BattleAgent_Model.SelectBattleAgentReq(name) local msg = battle_begin_pb.SelectBattleAgentReq() msg.name = name msg.allPings = BattleAgent_Model.GetAllPings() NetManager.SendMessage(MessageEnums.MessageSelectBattleAgent, msg) end function private.SelectBattleAgentResp(msgResp) if msgResp.Resp.Code == 0 then CTL.Tips.AddTipsMsg(Const_IDS.IDS_kcpagent_4) private.curSelectName = msgResp.name EventSystem.Dispatch(EventID.BattleAgent_SelectChanged, msgResp.name) end end --endregion 协议部分 --region -----------------数据部分--------------------- -- 仅仅cheat可以调用 function BattleAgent_Model.SetAgentPingByCheat(index, cheatPing) local agentData = private.agentList[index] if agentData then agentData.cheatPing = math.floor(cheatPing) end end function BattleAgent_Model.GetBattleAgentList() return private.agentList end function BattleAgent_Model.GetCurSelectName() return private.curSelectName end function BattleAgent_Model.GetCurSelectAgentData() for _, v in ipairs(private.agentList) do if v.name == private.curSelectName then return v end end return nil end function BattleAgent_Model.GetAgentPing(data) if data.cheatPing and data.cheatPing > 0 then return data.cheatPing end local ping = data.ping if ping and ping > 0 then return ping + data.delay end return -1 end function BattleAgent_Model.GetAllPings() local str = "" for _, data in ipairs(private.agentList) do if data.ping and data.ping > 0 then str = str .. data.ping + data.delay .. "," else str = str .. "此地址ping出现问题," end end return str end --endregion 数据部分 --region -----------------Ping值数据的处理--------------------- function BattleAgent_Model.RequestAllPing() for _, v in ipairs(private.agentList) do private.RequestPing(v) end end function BattleAgent_Model.RequestCurPing() for _, v in ipairs(private.agentList) do if v.name == private.curSelectName then private.RequestPing(v) end end end function private.RequestPing(agentData) local curServerTimestamp = UTL.Time.GetServerTimestamp() if curServerTimestamp > agentData.lastPingTime + BattleAgentPingTimeOut + 1 then -- 这里限制的稍微多一点 防止卡顿带来的时间影响 if GameAppInfo.IsVersionGreaterThan18000() then if string.match(agentData.ip, "[0-9]+%.[0-9]+%.[0-9]+%.[0-9]+") then -- 这里因为服务器下发的ip地址已经确定过,所以正则比较简单 UIUtils.NetworkPing(agentData.pingHost, BattleAgentPingTimeOut, false) else UIUtils.NetworkPing(agentData.pingHost, BattleAgentPingTimeOut, true) end else UIUtils.NetworkPing(agentData.pingHost, BattleAgentPingTimeOut) end agentData.lastPingTime = curServerTimestamp end end function private.OnNetworkPingCompleted(hostName, ping) for i, v in ipairs(private.agentList) do if v.pingHost == hostName then v.ping = math.floor(ping) EventSystem.Dispatch(EventID.BattleAgent_UpdateIndex, i, v) break end end end --endregion Ping值数据的处理 --region kcp 连接代理的相关函数 function BattleAgent_Model.GetKCPBattleAgentListReq() local msg = ping_test_pb.GetKcpPingServerInfoReq() NetManager.SendMessage(MessageEnums.MessageGetKcpPingServerInfo, msg) end function private.GetKCPBattleAgentListResp(msgResp) if msgResp.Resp.Code == 0 then for _, v in ipairs(msgResp.serverList) do table.insert(private.kcpAgentList, {ip = v.ip, port = v.port, name = v.name, hasPingedTimes = 0 }) -- hasPingedTimes 已经ping过了几次,5次则停止ping end -- 开启ping CTL.BattleAgent.StartKCPPingBattleAgent() end end function BattleAgent_Model.GetKCPAgentList() return private.kcpAgentList end function BattleAgent_Model.SetPingBattleAgentIsOver(val) private.pingBattleAgentIsOver = val if val == true then private.kcpAgentList = nil end end function BattleAgent_Model.ResetKCPAgentList() private.kcpAgentList = {} end function BattleAgent_Model.GetPingBattleAgentIsOver() return private.pingBattleAgentIsOver end --endregion kcp 连接代理的相关函数 return BattleAgent_Model