import { StringMap } from "../Collections/StringMap"; import Gamecfg from "../common/gameCfg"; import { gameMethod } from "../common/gameMethod"; import { HdClubPkFightAll, PlayerLogin, PlayerLoginPlayer, PlayerLoginUser, PlayerReconnect, TaichuWajieMap, UserAdok, ZhangjieDaguai } from "../common/Xyc"; import { SevBack, SevBackType } from "../common/Xys"; import Config from "../Config"; import { GameEvent, NetworkEvent, UserEvent, WindowEvent } from "../data/const/EventConst"; import { InGame, ReportRoleType } from "../data/const/TypeConst"; import GameDataCenter from "../data/GameDataCenter"; import EventMng from "../manager/EventMng"; import HttpRequest, { POST_DATA } from "./HttpRequest"; import SevDataMng from "./SevDataMng"; export default class Network { private leftSevbacks: { cb: Function, sevback: SevBack }[] = [] stopRequest: boolean = false //后端提示重启后停止发送协议 stopPopEp: boolean = false //处理装备的属性变化不飘字 isEpChange: boolean = false private isOutClub: boolean = false // 是否退出公会 private isShowTimeben: [number, string] = [0, ""] // 是否打开或刷新福利礼包 cmdCounts: number = 0 //网络请求计数 m_Timers: StringMap = new StringMap(); reSentTime: number; private getLoginUrl(url: string): string { let realUrl = Gamecfg.packageInfo.getItem(Config.pid).wayhttp + url + "?version=" + Config.appVersion + "&time=" + GameDataCenter.time.sevTime return realUrl } private getCmdUrl(url: string, cmdId: number): string { let realUrl = Gamecfg.packageInfo.getItem(Config.pid).wayhttp + url + "?uuid=" + GameDataCenter.user.uuid + "&token=" + GameDataCenter.user.token + "&version=" + Config.appVersion + "&cmdId=" + cmdId + "&time=" + GameDataCenter.time.sevTime return realUrl } constructor() { } // 不需要处理回调数据的,走这里 static POST_SPECIAL(path: string, body: string, cb: Function = () => { }) { let r = new XMLHttpRequest() r.open("POST", path, true) r.timeout = 15000 r.setRequestHeader("Content-Type", "application/json") r.onreadystatechange = () => { if (r.status >= 200 && r.status <= 400 && r.readyState == 4) { cb() } }; r.send(body) } sendLogin(url: string, body: Object, callback: Function = () => { }) { HttpRequest.POST(this.getLoginUrl(url), { uuid: GameDataCenter.user.uuid, version: Config.appVersion, url: url }, body, (result: SevBack) => { this.updateSevBack(result, callback) }, true) } send(url: string, body: Object, cb1?: (sev: SevBack) => void, cb2?: (sev: SevBack) => void, deal: number = 1, needWait: boolean = false, cmdId: number = -1) { if (this.stopRequest) { return } //每发送一个消息,消息计数累计,方便服务端做判断 this.cmdCounts++ //先缓存发送的消息,超时重新请求 let postDataTemp: POST_DATA = { url: url, body: body, cb1: cb1, cb2: cb2, deal: deal, cmdId: cmdId == -1 ? this.cmdCounts : cmdId } let unErrArr = [PlayerReconnect.url, UserAdok.url, UserAdok.url]; if (unErrArr.indexOf(url) < 0) { //重连接口,心跳包, 挂机打怪无需重新发送 HttpRequest.errPostMap.Add(url, postDataTemp) let unArr = [PlayerLogin.url, PlayerLoginPlayer.url, PlayerLoginUser.url, HdClubPkFightAll.url, TaichuWajieMap.url, ZhangjieDaguai.url]; if (unArr.indexOf(url) < 0) { let postTime = new Date().getTime() postDataTemp.postTime = postTime HttpRequest.curPostMap.Add(url, postDataTemp) } } this.AddTimer(url, () => { let curTime = new Date().getTime() if (!this.reSentTime) { this.reSentTime = cc.sys.platform == cc.sys.TAOBAO_MINIGAME ? 3000 : 1500; } if (HttpRequest.curPostMap.ContainsKey(url) && curTime - HttpRequest.curPostMap.Value(url).postTime >= this.reSentTime) { console.log(`1.5s后重新发送:${url}`) //遮罩计数-1 EventMng.emit(NetworkEvent.WAIT, -1) this.m_Timers.Remove(url) let value = HttpRequest.curPostMap.Value(url) this.send(value.url, value.body, value.cb1, value.cb2, value.deal, false, value.cmdId) } }, 500) if (needWait) EventMng.emit(NetworkEvent.NETWAIT_MASK, true) let curCmdId = cmdId == -1 ? this.cmdCounts : cmdId HttpRequest.POST(this.getCmdUrl(url, curCmdId), { uuid: GameDataCenter.user.uuid, version: Config.appVersion, url: url }, body, (result: SevBack) => { if (needWait) EventMng.emit(NetworkEvent.NETWAIT_MASK, false) if (result.type == SevBackType.wu) { //无需处理的消息 return } if (cb2) { cb2(result) } if (result.type == SevBackType.fail) { // 如果出现异常,则直接处理 this.updateSevBack(result, cb1) return } if (deal == 1) { if (this.leftSevbacks.length > 0) { this.leftSevbacks.push({ cb: cb1, sevback: result }) } else { this.updateSevBack(result, cb1) } } else if (deal == 2) { // 暂存弹窗信息 if (this.leftSevbacks.length > 0) { this.leftSevbacks.push({ cb: cb1, sevback: result }) } else { let tempSevback: SevBack = { type: result.type } this.leftSevbacks.push({ cb: () => { }, sevback: tempSevback }) this.updateSevBack(result, cb1) } } else { this.leftSevbacks.push({ cb: cb1, sevback: result }) } }, false) } // 处理暂存的后端数据 dealLeftSevback() { this.leftSevbacks.forEach(element => { this.updateSevBack(element.sevback, element.cb) }); this.leftSevbacks = [] } updateSevBack(result: SevBack, cb1: Function) { // 刷新后端数据列表 let oldPower: number = GameDataCenter.sevBack?.userInfo?.a?.power ?? 0; let sevback = SevDataMng.sevBackUpdate(GameDataCenter.sevBack, result) // 这里去检测通用类数据的前后对比 this.isOutClub = false this.isShowTimeben = [0, ""] GameDataCenter.sevBack = sevback; if ((!gameMethod.isEmpty(result?.userInfo?.a?.power) || (!gameMethod.isEmpty(result?.userInfo?.u?.power)))) { // 更新战斗力 if (GameDataCenter.zhanLi) GameDataCenter.zhanLi.updateTotalZhanLi(oldPower, sevback?.userInfo?.a?.power); } // 业务逻辑自定义参数处理 for (let key in result) { let rspModels = GameDataCenter._rspModel.get(key) for (let i = 0; i < rspModels?.length; i++) { //需要分发事件的模块分发 rspModels[i]?.doSevback(result) } } // 触发事件,刷新UI this.updateEvent(result, cb1) // 需要在数据处理后触发 if (this.isOutClub) { } } updateEvent(result: SevBack, cb1: Function) { let alreadyRspModel = [] //已分发的模块,同个消息同个模块只分发一次 for (let key in result) { let rspModels = GameDataCenter._rspModel.get(key) for (let i = 0; i < rspModels?.length; i++) { if (alreadyRspModel.indexOf(rspModels[i]) >= 0) { continue } //需要分发事件的模块分发 rspModels[i]?.doEvent(result) alreadyRspModel.push(rspModels[i]) } } // 执行各自协议发送者回调 if (cb1) { cb1(result) } } /** * 增加定时器 * @param callback * @param delta 单位毫秒ms */ AddTimer(key: string, callback: Function, delta: number) { if (this.m_Timers.ContainsKey(key)) { return } let timer = setInterval(() => { callback.apply(this); }, delta); this.m_Timers.Add(key, timer); return timer; } /** 移除所有定时器 */ RemoveTimers() { this.m_Timers.Foreach((key: string, value: NodeJS.Timer) => { clearInterval(value); }); this.m_Timers.Clear() } }