NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==UserScript== // @name CF Team Interface // @namespace https://github.com/PikMike // @version 0.4 // @description More team info // @author PikMike // @include *codeforces.*/team/* // @grant none // @license MIT // ==/UserScript== var lang = getCookie("nocturne.language"); var plurDict = {"country": {"en": "Countries", "ru": "Страны"}, "city": {"en": "Cities", "ru": "Города"}, "org": {"en": "Organizations", "ru": "Организации"}}; var singDict = {"rating": {"en": "Rating", "ru": "Рейтинг"}, "country": {"en": "Country", "ru": "Страна"}, "city": {"en": "City", "ru": "Город"}, "org": {"en": "Organization", "ru": "Организация"}}; var note = {"ru" : "Рейтинг участников вне рейтинга устанавливается равным 1500, поэтому суммарный рейтинг неточный.", "en" : "Unrated users rating is set to 1500, so there is inaccuracy in total rating."}; var xhr = []; var countries = [], cities = [], orgs = []; var teamInfo = document.getElementsByClassName("info")[0]; var list = teamInfo.children[teamInfo.children.length - 1]; var cntProcessed = 0; var ratings = []; var inaccRating = false; var rating = document.createElement("LI"); list.insertBefore(rating, list.children[0]); rating.innerHTML = singDict["rating"][lang] + ": "; var ratingValue = document.createElement("SPAN"); ratingValue.style = "font-weight:bold;"; rating.appendChild(ratingValue); var delimiter = document.createElement("HR"); var countryList = document.createElement("LI"); var cityList = document.createElement("LI"); var orgList = document.createElement("LI"); list.appendChild(delimiter); list.appendChild(countryList); list.appendChild(cityList); list.appendChild(orgList); function getWinProbability(ra, rb){ return 1.0 / (1.0 + Math.pow(10.0, (rb - ra) / 400.0)); } function aggregateRatings(teamRatings){ let left = 1.0; let right = 10000.0; for (let tt = 0; tt < 100; tt++){ let r = (left + right) / 2.0; let rWinsProbability = 1.0; for(var i = 0; i < teamRatings.length; i++) rWinsProbability *= getWinProbability(r, teamRatings[i]); rating = Math.log10(1 / (rWinsProbability) - 1) * 400 + r; if (rating > r) left = r; else right = r; } return (left + right) / 2.0; } var helperFunc = function(i){ return function(){ if(xhr[i].readyState === 4){ ProcessResponseForItem(i); } }; }; function ProcessResponseForItem(i){ if(xhr[i].status === 200){ var resp = xhr[i].response; var info = resp.getElementsByClassName("main-info")[0]; if (info.children[0].children[0].getAttribute('class') !== "user-black") ratings.push(parseInt(resp.getElementsByClassName("info")[0].children[resp.getElementsByClassName("info")[0].children.length - 1].children[0].children[1].innerHTML)); else{ ratings.push(1500); inaccRating = true; } console.log("Info about user " + resp.getElementsByClassName("main-info")[0].children[1].children[0].innerHTML + " loaded"); var country = null; var city = null; var org = null; if (info.children.length > 2){ var data = info.children[2].children; for (var j = 0; j < data.length; j++) for (var k = 0; k < data[j].children.length; k++){ if (data[j].children[k].tagName != "A") continue; if (data[j].children[k].href.includes("city")) city = data[j].children[k].innerHTML; else if (data[j].children[k].href.includes("country")) country = data[j].children[k].innerHTML; else if (data[j].children[k].href.includes("organization")) org = data[j].children[k].innerHTML; } } if (country !== null && !countries.includes(country)){ countries.push(country); countryList.innerHTML = (countries.length === 1 ? singDict["country"][lang] : plurDict["country"][lang]) + ": " + countries.join(", "); } if (city !== null && !cities.includes(city)){ cities.push(city); cityList.innerHTML = (cities.length === 1 ? singDict["city"][lang] : plurDict["city"][lang]) + ": " + cities.join(", "); } if (org !== null && !orgs.includes(org)){ orgs.push(org); orgList.innerHTML = (orgs.length === 1 ? singDict["org"][lang] : plurDict["org"][lang]) + ": " + orgs.join("; "); } cntProcessed++; if (cntProcessed == users.length){ var ratingNum = Math.round(aggregateRatings(ratings)); ratingValue.className = determClass(ratingNum); ratingValue.innerHTML = ""; if (ratingValue.className == "user-legendary") ratingValue.innerHTML += '<span class="legendary-user-first-letter">' + ratingNum.toString()[0] + '</span>' + ratingNum.toString().slice(1); else ratingValue.innerHTML += ratingNum.toString(); if (inaccRating) ratingValue.innerHTML += "<sup><font title='" + note[lang] + "' color='grey'>?</font></sup>"; } } } function determClass(value){ if (value === null) return ""; else if (value < 1200) return "user-gray"; else if (value < 1400) return "user-green"; else if (value < 1600) return "user-cyan"; else if (value < 1900) return "user-blue"; else if (value < 2100) return "user-violet"; else if (value < 2400) return "user-orange"; else if (value < 3000) return "user-red"; else return "user-legendary"; } function getCookie(name) { var value = "; " + document.cookie; var parts = value.split("; " + name + "="); if (parts.length == 2) return parts.pop().split(";").shift(); else return "en"; } var members = document.getElementsByClassName("members")[0]; var users = members.getElementsByClassName("avatar"); for (var i = 0; i < users.length; i++){ var url = users[i].children[0].href; xhr.push(new XMLHttpRequest()); xhr[i].open('GET', url, true); xhr[i].responseType = "document"; xhr[i].onreadystatechange = helperFunc(i); xhr[i].send(null); }