Last active
March 21, 2020 10:11
-
-
Save Element118/65ded2b36d030e5564971032edff48ea to your computer and use it in GitHub Desktop.
Singapore Sightread Tournament Point Counter
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
// ==UserScript== | |
// @name SST counter | |
// @namespace http://tampermonkey.net/ | |
// @version 1.2 | |
// @description Point counter for Singapore Sightread Tournament | |
// @author Element118 | |
// @match https://osu.ppy.sh/community/matches/* | |
// @grant none | |
// ==/UserScript== | |
/** | |
Assumptions: | |
I'm relying on the first maps being warmups, and each room playing the same number of warmups. | |
If a room plays a different number of warmups, update this code. | |
**/ | |
(function() { | |
'use strict'; | |
// edit these variables according to the requirements | |
let numMaps = 8; | |
let firstMapIndex = 3;//1; // number of warmup maps | |
let DQ = [""]; // usernames of disqualified users and refs | |
// rest of code | |
let el = document.createElement("button"); el.innerText = "Calculate!"; | |
let doOver = setInterval(function() { | |
let title = document.getElementsByClassName("header-v4__title")[0]; | |
if (title) { | |
clearInterval(doOver); | |
let doOver2 = setInterval(function() { | |
let refText = document.getElementsByClassName("mp-history-event__text")[0]; | |
if (refText) { | |
console.log(refText.textContent); | |
DQ.push(refText.textContent.split(" created the match")[0]); | |
clearInterval(doOver2); | |
title.appendChild(el); | |
} | |
}, 500); | |
} | |
}, 500); | |
let rankData = function(scores) { | |
let result = []; | |
let prevRank = 0, prevScore = Math.pow(2, 31), prevFail = false; | |
for (let i=0;i<scores.length;i++) { | |
let failed = scores[i].getElementsByClassName("mp-history-player-score__failed").length > 0; | |
let score = scores[i].getElementsByClassName("mp-history-player-score__stat-number mp-history-player-score__stat-number--large")[0].textContent; | |
result.push({ | |
name: scores[i].getElementsByClassName("mp-history-player-score__username")[0].textContent, | |
score: score, | |
failed: failed | |
}); | |
} | |
result.sort(function(a, b) { | |
if (a.failed !== b.failed) { | |
if (a.failed) return 1; | |
if (!a.failed) return -1; | |
} | |
return b.score - a.score; | |
}); | |
for (let i=0;i<scores.length;i++) { | |
let failed = scores[i].failed | |
let score = scores[i].score | |
let rank = (+score == +prevScore && failed == prevFail)?prevRank:prevRank+1; | |
result[i].rank = rank; | |
prevRank = rank; prevScore = score; prevFail = failed; | |
} | |
return result; | |
}; | |
el.addEventListener("click", function() { | |
let maps = document.getElementsByClassName("mp-history-game"); | |
let scoreEls = []; | |
let mapsFound = 0; | |
for (let i=0;i<maps.length;i++) { | |
var mapName = maps[i].getElementsByClassName("mp-history-game__metadata mp-history-game__metadata--title")[0].textContent; | |
if (maps[i].getElementsByClassName("mp-history-game__stat")[0].textContent.indexOf("(match in progress)") === -1) { | |
let scores = maps[i].getElementsByClassName("mp-history-player-score__main"); | |
scoreEls.push(rankData(scores)); | |
} | |
} | |
let dataTb = {}; | |
let mapNum = 0; | |
let defaultPoints = []; | |
console.log("Maps played: " + scoreEls.length); | |
for (let i=0;i<numMaps;i++) { | |
let index = scoreEls.length-numMaps+i; | |
if (index < firstMapIndex) continue; | |
mapsFound++; | |
let points = 1; // points of next rank | |
let prevPoints = 0; | |
let prevRank = 0; | |
for (let j=0;j<scoreEls[index].length;j++) { | |
let name = scoreEls[index][j].name; | |
let rank = scoreEls[index][j].rank; | |
if (DQ.indexOf(name) === -1) { // not disqualified | |
dataTb[name] = dataTb[name] || []; | |
while (dataTb[name].length < mapNum) { | |
dataTb[name].push(defaultPoints[dataTb[name].length]); | |
} | |
if (rank > prevRank) prevPoints = points; | |
dataTb[name].push(prevPoints); | |
points++; | |
} | |
} | |
defaultPoints.push(points); | |
// if player not accounted for? | |
mapNum++; | |
for (let i in dataTb) { | |
dataTb[i] = dataTb[i] || []; | |
while (dataTb[i].length < mapNum) { | |
dataTb[i].push(defaultPoints[dataTb[i].length]); | |
} | |
} | |
} | |
console.log(mapsFound + " out of " + numMaps + " played!"); | |
let sortedData = []; | |
let longName = 0; | |
for (let i in dataTb) { | |
longName = Math.max(longName, i.length); | |
} | |
for (let i in dataTb) { | |
var points = dataTb[i].reduce(function(a, b) { return a+b; }); | |
sortedData.push({ | |
text: i+" ".repeat(longName-i.length)+": "+dataTb[i].join(" ")+" ["+points+"]\n", | |
points: points | |
}); | |
} | |
sortedData.sort(function(a, b) { return a.points-b.points; }); | |
let niceOutput = ""; | |
let hasTies = false; | |
for (var i=0;i<sortedData.length;i++) { | |
niceOutput += sortedData[i].text; | |
if (i > 0 && sortedData[i].points == sortedData[i-1].points) hasTies = true; | |
} | |
console.log(niceOutput); | |
// I think warning about ties here is sufficient. | |
if (hasTies) { | |
console.log("WARNING: TIE"); | |
} | |
}); | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment