if (!!!backlog){ backlog = console } function space(n){ let str = "" for (let index = 0; index < n; index++) { str = str+" " } return str } //消息-下载录像 function DownloadRecord(url) { url = url||"record.json" REPLAY_NAME=url url="https://zth5.ztgame.com/record/"+url var httpRequest = new XMLHttpRequest(); httpRequest.open('GET', url, true); httpRequest.send(); httpRequest.onreadystatechange = function () { if (httpRequest.readyState == 4 && httpRequest.status == 200) { var json = httpRequest.responseText; window["REPLAY"]=JSON.parse(json) backlog.log("下载完成"); } }; } //消息-保存 function SaveRecord() { let filename = "record_"+REC.begin+".json" let text = JSON.stringify(REC) var pom = document.createElement('a'); pom.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text)); pom.setAttribute('download', filename); if (document.createEvent) { var event = document.createEvent('MouseEvents'); event.initEvent('click', true, true); pom.dispatchEvent(event); } else { pom.click(); } } //消息-回放 function ReplayRecord(rec) { rec=rec||REPLAY let S_TIME=rec.messages[0].time let IDX=0 let state = 0 let TID = setInterval(()=>{ S_TIME=S_TIME+1 while(IDXrec.messages[IDX].time){ let msg={ destinationName:rec.messages[IDX].name, payloadString:rec.messages[IDX].playload, } if(state==0 && msg.destinationName=="SC_OnEnterGame"){ S_TIME=S_TIME-5 //给客户端缓冲加载时间 state = 1 continue } if (msg.destinationName.indexOf("HD_")!=0){ NetWork.ExcuteMessage(msg) } IDX=IDX+1 } if(IDX>=rec.messages.length){ clearInterval(IDX) } },1000) return TID } //消息-开始录制 function StartRecord() { if (!window["M"]){ window["M"] = NetWork.ExcuteMessage window["BACK"]=[] } REC={begin:new Date(),end:null, messages:[]} //记录消息内容 NetWork.ExcuteMessage = (msg)=>{ M(msg) REC.messages.push({ time:G_GameData.serverTime, clienttime:new Date().getTime(), name:msg.destinationName, playload:msg.payloadString }) } return "开始录制" } //消息-结束录制 function EndRecord() { if( window["M"]){ NetWork.ExcuteMessage = window["M"] } if(REC.end==null){ REC.end = new Date() BACK.push(REC) } backlog.log("结束录制") SaveRecord() return REC } //分析 function AnalyzRecord(rec) { let N = 15 rec = rec || REPLAY let S = rec.messages[rec.messages.length-1].time - rec.messages[0].time cnt = {} size = {} rec.messages.forEach((val)=>{ if (!cnt[val.name]){cnt[val.name]=0} cnt[val.name] = cnt[val.name]+1 if (!size[val.name]){size[val.name]=0} size[val.name] = size[val.name]+JSON.stringify({val}).length }) l=[] for (k in cnt){ l.push({name:k,count:cnt[k]}) } l.sort((i,j)=>{return j.count-i.count}) l = l.splice(0,N) backlog.log("%c%s 录制时长: %d 秒%c (调用次数前 %d)", "color:red;font-size:16px", REPLAY_NAME,S,"", N) l.forEach((val)=>{ backlog.log("%s:%s%d%sPS:%d Size:%fKB", val.name, space(28-val.name.length), val.count,space(8-(""+val.count).length), 0.5+val.count/S, 0.5+size[val.name]/1024.0/S ) }) } function AnalyzRecord2(rec) { N = 20 rec = rec || REPLAY let S = rec.messages[rec.messages.length-1].time - rec.messages[0].time cnt = {} rec.messages.forEach((val)=>{ if (val.name == "SC_UpdateMapBuff"){ let obj = JSON.parse(val.playload) for(const key in obj.buffbox){ const buf = obj[key] if (!cnt[key]){cnt[key]=0} cnt[key] = cnt[key]+1 } } }) l=[] for (k in cnt){ l.push({name:k,count:cnt[k]}) } l.sort((i,j)=>{return j.count-i.count}) l = l.splice(0,N) backlog.log("%c%s BuffId前 %d%c", "color:red;font-size:16px", "SC_UpdateMapBuff",N,"") backlog.log("%c%s 录制时长: %d 秒%c", "color:red;font-size:16px", REPLAY_NAME,S,"") backlog.log("%s:%s%s", "BuffId",space(18-"BuffId".length), "数量") l.forEach((val)=>{ backlog.log("%s:%s%d%sPS:%d", val.name, space(18-val.name.length), val.count, space(8-(""+val.count).length), 0.5+val.count/S, ) }) backlog.log(l) } backlog.log("记录消息工具加载完成") backlog.log("开始录像 StartRecord()") backlog.log("结束录制 EndRecord()") backlog.log("保存文件 SaveRecord()") backlog.log("下载录像 DownloadRecord(\"record.json\")") backlog.log("回放 ReplayRecord()") backlog.log("分析 AnalyzRecord()")