Created
July 21, 2019 23:21
-
-
Save Maistho/5e93df870604a0842e8931133e552c94 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
javascript:var CsgoMap;!function(t){t.de_mirage="Mirage",t.de_dust2="Dust II",t.de_subzero="Subzero",t.de_train="Train",t.de_nuke="Nuke",t.de_inferno="Inferno",t.de_cache="Cache",t.de_overpass="Overpass"}(CsgoMap||(CsgoMap={}));class MinMaxAvg{constructor(){this.min=1/0,this.max=-1/0,this.avg=0,this.total=0}append(t,e){this.min=Math.min(t,this.min),this.max=Math.max(t,this.max),this.total+=t,this.avg=this.total/e}}class PlayerStats{constructor(t){this.timesPlayed=0,this.roundsPlayed=0,this.ping=new MinMaxAvg,this.kills=new MinMaxAvg,this.assists=new MinMaxAvg,this.deaths=new MinMaxAvg,this.mvps=new MinMaxAvg,this.headshotRate=new MinMaxAvg,this.score=new MinMaxAvg,this.link=t.link,this.image=t.image,this.name=t.name}add(t,e){this.roundsPlayed+=e,this.timesPlayed+=1,this.ping.append(t.ping,this.timesPlayed),this.kills.append(t.kills,this.timesPlayed),this.assists.append(t.assists,this.timesPlayed),this.deaths.append(t.deaths,this.timesPlayed),this.mvps.append(t.mvps,this.timesPlayed),this.headshotRate.append(Number(t.headshotRate),this.timesPlayed),this.score.append(t.score,this.timesPlayed)}}async function getAllMatches(){if("steamcommunity.com"!=window.location.hostname)return alert("Redirecting to steamcommunity.com, please run the bookmarklet again after the page has reloaded"),void(window.location.href="https://steamcommunity.com");const t=document.querySelector("#global_actions>a.user_avatar");if(!t)throw alert("You need to be logged in"),new Error("User not logged in");const e=t.href.replace(/\/$/,""),n=[];let a,i=0;do{const t=new URLSearchParams({ajax:"1",tab:"matchhistorycompetitive"});a&&t.append("continue_token",a);const s=`${e}/gcpd/730?${t.toString()}`;let o;const r=`_csgo_stats_cache_${s}`;if(a)try{o=JSON.parse(localStorage.getItem(r)||"")}catch(t){}if(o||(o=await fetch(s,{credentials:"include"}).then(t=>t.json())),!o.success)throw new Error(JSON.stringify(o));localStorage.setItem(r,JSON.stringify(o));const l=(new DOMParser).parseFromString(o.html,"text/html");n.push(...Array.from(l.querySelectorAll(".generic_kv_table.csgo_scoreboard_root>tbody>tr")).map(t=>({map:getMap(t),time:getTime(t),waitTime:getWaitTime(t),matchDuration:getMatchDuration(t),score:getScore(t),demo:getDemo(t),...getTeams(t,e)})).filter(({map:t})=>!!t)),a=o.continue_token,loadingStatus.innerText=`${++i} pages parsed...`}while(a);return n}const getTeams=(t,e)=>{const n=[[],[]],a=Array.from(t.querySelectorAll(".csgo_scoreboard_inner_right>tbody>tr"));let i=-1;for(const t of a){const e=q(t,"a.linkTitle");null!=e?n[i].push({link:e.attributes.getNamedItem("href").textContent||"",name:getInfo(t,"a.linkTitle"),image:getAttribute(q(t,".playerAvatar img"),"src"),ping:parseInt(getInfo(t,"td:nth-child(2)")),kills:parseInt(getInfo(t,"td:nth-child(3)")),assists:parseInt(getInfo(t,"td:nth-child(4)")),deaths:parseInt(getInfo(t,"td:nth-child(5)")),mvps:parseInt(getInfo(t,"td:nth-child(6)").substr(1))||0,headshotRate:getInfo(t,"td:nth-child(7)"),score:parseInt(getInfo(t,"td:nth-child(8)"))}):i+=1}return{teams:n,userTeam:n.findIndex(t=>t.some(t=>t.link===e))}},getDemo=t=>{const e=q(t,".csgo_scoreboard_inner_left .csgo_scoreboard_btn_gotv");return getAttribute(e&&e.parentElement,"href")},getScore=t=>getInfo(t,".csgo_scoreboard_score"),getMatchDuration=t=>getInfo(t,".csgo_scoreboard_inner_left>tbody>tr:nth-child(4)").replace(/^Match Duration: /,""),getWaitTime=t=>getInfo(t,".csgo_scoreboard_inner_left>tbody>tr:nth-child(3)").replace(/^Wait Time: /,""),getTime=t=>new Date(getInfo(t,".csgo_scoreboard_inner_left>tbody>tr:nth-child(2)")),getMap=t=>getInfo(t,".csgo_scoreboard_inner_left>tbody>tr:nth-child(1)").replace(/^Competitive /,"");function getInfo(t,e){return getText(q(t,e))}function getText(t){return(t&&t.textContent||"").trim()}function q(t,e){return t&&t.querySelector(e)}function getAttribute(t,e){return(t&&t.getAttribute(e)||"").trim()}function parseMatches(t){const e={},n={};return t.forEach(t=>{const a=t.score.split(":").map(t=>t.trim()).map(t=>Number(t)),i=a[0]+a[1],s=t.userTeam,o=0===s?1:0;e[t.map]||(e[t.map]={name:t.map,timesPlayed:0,wins:0,losses:0,draws:0,winrate:0,roundsWon:0,roundsLost:0,roundWinrate:0});const r=e[t.map];a[s]>a[o]?r.wins+=1:a[s]<a[o]?r.losses+=1:r.draws+=1,r.timesPlayed+=1,r.roundsWon+=a[s],r.roundsLost+=a[o];for(const e of t.teams)for(const t of e){n[t.link]||(n[t.link]=new PlayerStats(t)),n[t.link].add(t,i)}}),Object.keys(e).forEach(t=>{const n=e[t];n.winrate=n.wins/(n.timesPlayed-n.draws),n.roundWinrate=n.roundsWon/(n.roundsWon+n.roundsLost)}),{maps:e,players:n}}function fmt(t){return Number(t.toFixed(2))}function printStatistics(t,e){console.table(e.sort((t,e)=>e.timesPlayed-t.timesPlayed).slice(0,50).map(t=>({name:t.name,gamesPlayed:t.timesPlayed,kdr:fmt(t.kills.total/t.deaths.total),totalKills:t.kills.total,avgKills:fmt(t.kills.avg),killsPerRound:fmt(t.kills.total/t.roundsPlayed)})));var n=Object.values(t).sort((t,e)=>e.winrate-t.winrate).map(t=>({...t,winrate:formatWinrate(t.winrate),roundWinrate:formatWinrate(t.roundWinrate)}));console.table(n);let a=`<table style="margin: 0 auto;">\n <tr>\n <th>Map</th>\n <th>Winrate</th>\n <th>(W/D/L)</th>\n </tr>\n ${n.map(t=>`\n <tr>\n <td>${t.name}</td>\n <td>${t.winrate}</td>\n <td>(${t.wins}/${t.draws}/${t.losses})</td>\n </tr>\n `).join("\n")}\n </table>`;const i="__maistho_csgo_stats_table_wrapper";let s=document.getElementById(i);s||((s=document.createElement("div")).id=i,s.style.background="#171a21",s.style.color="white",document.body.prepend(s)),s.innerHTML=a;const o=`${s.clientHeight}px`,r=document.querySelector(".responsive_header");r&&(r.style.marginTop=o)}function formatWinrate(t){return(100*t).toLocaleString(void 0,{maximumFractionDigits:2,minimumFractionDigits:0})+"%"}const loadingSpinner=document.createElement("div");loadingSpinner.innerHTML='<img src="https://steamcommunity-a.akamaihd.net/public/images/login/throbber.gif">',loadingSpinner.style.display="flex",loadingSpinner.style.alignItems="center",loadingSpinner.style.justifyContent="center",loadingSpinner.style.position="fixed",loadingSpinner.style.top="0",loadingSpinner.style.left="0",loadingSpinner.style.bottom="0",loadingSpinner.style.right="0",loadingSpinner.style.background="rgba(0,0,0,0.5)",loadingSpinner.style.flexDirection="column",loadingSpinner.style.zIndex="999999";const loadingStatus=document.createElement("div");loadingStatus.innerText="0 pages parsed...",loadingStatus.style.color="white",loadingStatus.style.margin="1em",loadingSpinner.appendChild(loadingStatus),document.body.appendChild(loadingSpinner),getAllMatches().then(t=>{const{maps:e,players:n}=parseMatches(t);printStatistics(e,Object.values(n))}).catch(t=>{alert(t)}).finally(()=>{document.body.removeChild(loadingSpinner)}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment