Last active
January 12, 2020 03:48
-
-
Save Poeticalto/00de8353fce79cac9059b22f20242039 to your computer and use it in GitHub Desktop.
Link to repo: https://github.com/poeticalto/tagpro-comp-stats
This file contains 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 TagPro Competitive Stats | |
// @author Poeticalto | |
// @namespace https://poeticalto.github.io/ | |
// @website https://github.com/poeticalto/tagpro-comp-stats | |
// @supportURL https://www.reddit.com/message/compose/?to=Poeticalto | |
// @include *://*.koalabeast.com* | |
// @description Sets up an Autoscore/Backscore compatible no-script group and sends cap updates/stats while in game | |
// @updateURL https://github.com/Poeticalto/tagpro-comp-stats/raw/stable/tagpro_competitive_stats.user.js | |
// @downloadURL https://github.com/Poeticalto/tagpro-comp-stats/raw/stable/tagpro_competitive_stats.user.js | |
// @grant GM_getValue | |
// @grant GM_setValue | |
// @version 0.4100 | |
// ==/UserScript== | |
// Special thanks to Destar, Some Ball -1, Ko, and ballparts for their work in this userscript! | |
// If your abbreviations/jerseys are out of date, message /u/Poeticalto using the support link above so he can update them or make a pull request on the corresponding GitHub repo (pull from the stable branch). | |
/////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
// Custom Options can be accessed through the following steps: // | |
// 1. Create a private group as the leader. // | |
// 2. Click on the League Modifier Box. (Underneath the Swap Teams button) // | |
// 3. At the bottom of the list, click on the option you want to toggle. // | |
// The option's current state will be shown in brackets. (like [currently enabled]) // | |
// Current Options: // | |
// Enable/Disable H2 Overtime = Enables/Disables overtime settings for overtime in two half games // | |
// Enable/Disable Jerseys = Enables/Disables team jerseys in spectator mode // | |
// Enable/Disable Jersey Spin = Enables/Disables the spin of jerseys in spectator mode // | |
// Enable/Disable Save Stats Locally = Allows the user to locally save game stats after leaving the game // | |
// Enable/Disable Abbreviation Checks = Enables/Disables warnings for when team names are not set // | |
// Enable/Disable Sound Checks = Enables/Disables automatic reset of volume to 0 when sounds are muted // | |
/////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
// Log script in console | |
console.log(GM_info.script.name + ' active (Version: ' + GM_info.script.version + ')'); | |
// Start Script (Group functions) | |
if (window.location.href.split(".com")[1].match(/^\/groups\/[a-z]{8}\/*#*[cr]*g*-*[ 0-z]*$/)) { // This gets your unique ID to determine which team you are in the group | |
//This is separate from the main functions because the 'you' event may get sent before the rest of the script has loaded | |
tagpro.ready(function() { | |
tagpro.group.socket.on("you", function(p) { | |
GM_setValue("tpUserId", p); | |
}); | |
}); | |
} | |
(function(window) { | |
'use strict'; | |
if (GM_getValue("tpcsLastHref",0) != 0) { // This is a refresh condition to check if the player has re-entered the game. | |
if (GM_getValue("tpcsLastHref",0) != window.location.href) { // player left the game, so clear the checks | |
GM_setValue("compCheck", 0); // Set comp check to 0 to avoid accidentally triggering spec mode | |
GM_setValue("tpcsLastHref",0); | |
GM_setValue("tpcsStartTime",0); | |
} | |
} | |
// Group Functions, or the functions which run when user is on the group page | |
if (window.location.href.split(".com")[1].match(/^\/groups\/#[cr]g-*[ 0-z]*$/)) { // If #cg/#tg/#rg is passed through, creates new group with competitive settings | |
if (window.location.href.split(new RegExp("-", "gi")).length == 3) { | |
GM_setValue("setMap", window.location.href.split("-")[2]); // sets a global var to remember the map name passed through | |
} | |
document.getElementsByTagName("input")[1].checked = false; // ensures private group | |
GM_setValue("makepug", true); // makepug is the flag to automatically set competitive settings | |
document.getElementById("create-group-btn").click(); // create group | |
} | |
else if (window.location.href.split(".com")[1].match(/^\/groups\/[a-z]{8}\/*#*[cr]*g*-*[ 0-z]*$/) && Array.apply(null, document.getElementsByClassName("js-leader")).length > 0) { // the fancy stuff for the first condition allows for a map to be passed in | |
leaderReady(); // runs function to set up leader stuff | |
groupReady(true); // runs function to grab group info | |
} | |
else if (window.location.pathname.match(/^\/groups\/[a-z]{8}$/) && Array.apply(null, document.getElementsByClassName("js-leader")).length === 0) { // non-leader in group | |
// spectator shouldn't need arguments, so there's no need to parse group type/map choice | |
GM_setValue("groupId", window.location.href.split("/")[4]); // the leader function already sets groupId, so there's no need to set it again | |
console.log("Spectator/Player detected, skipping group setup"); | |
groupReady(false); // runs function to grab group info | |
var redundantCount = 0; | |
var redundantLeadCheck = setInterval(function () { // Recheck for leader every half second for ten seconds in case leader functions didn't load | |
if (Array.apply(null, document.getElementsByClassName("js-leader")).length > 0) { | |
if (!document.getElementById("autoscoreLeague")) { // if leader stuff wasn't activated by something else, start leader functions | |
changeLeader(true); | |
} | |
window.clearInterval(redundantLeadCheck); // clear interval since you're done checking | |
} | |
else if (redundantCount > 20) { // clear interval after ten seconds | |
window.clearInterval(redundantLeadCheck); | |
} | |
else { // increment up if it hasn't been ten seconds yet | |
redundantCount++; | |
} | |
}, 500); | |
} | |
// Game functions, or functions which run when user is in game | |
else if (!window.tagpro && GM_getValue("compCheck", 0) >= 1 && tagproConfig && tagproConfig.gameSocket) { //comp game is detected when the tagpro object does not exist and gameSocket exists in the tagproConfig object | |
// Because the tagpro object is not defined, this already defines a comp eligible game, so there's no need for redundant checks | |
var gameLink = tagproConfig.gameSocket; | |
var groupServer = gameLink.split("-")[1].split(".")[0]; | |
var groupPort = gameLink.split(":")[1]; | |
var userTeam = GM_getValue("userTeam", "none"); | |
var m = new Date(); | |
var startTime = (Math.floor(m.getTime() / 1000) + m.getTimezoneOffset() * 60); | |
console.log("Comp game detected on " + groupServer + ":" + groupPort + ", player mode activated with team " + userTeam); | |
var backscoreRedCaps = 0; //backscore is taken directly from scoreboard, so it can be trusted | |
var backscoreBlueCaps = 0; | |
var updateRedCaps = 0; //auto is guessed from sound events, so it can't be trusted completely [used for cap updates] | |
var updateBlueCaps = 0; | |
var firstSound = true; | |
var tableExport = []; // tableExport will send the scoreboard data | |
var scoreboardCaps = [0, 0]; // scoreboard caps keeps count of each team's caps | |
var teamNum = []; // teamNum represents the team of each player: Red = 1 and Blue = 2 | |
var sendCheck = GM_getValue("tpcsConfirmation", false); | |
var localCheck = GM_getValue("backLocalStorage", false); | |
var soundCheck = GM_getValue("tpcsSoundCheck", true); | |
var playerCompCheck = GM_getValue("compCheck", 0); | |
var playerLate = GM_getValue("tpcsLateFlag", false); | |
document.getElementById("cheering").addEventListener("play", function() { // cheering plays when the game starts or when your team caps | |
if (firstSound === true) { //the first cheering sound starts the game, so don't increment cap counter | |
console.log("Start of comp game detected"); | |
var x = new Date(); | |
if (tagproAnalyticsCollector && tagproAnalyticsCollector.data && tagproAnalyticsCollector.data.date) { | |
// if the analytics collector is available, get the server defined start time | |
startTime = tagproAnalyticsCollector.data.date+x.getTimezoneOffset() * 60; | |
} | |
else { | |
startTime = (Math.floor(x.getTime() / 1000) + x.getTimezoneOffset() * 60); // gets start time in UTC to avoid timezone confusion | |
} | |
GM_setValue("tpcsStartTime", startTime); | |
} | |
else if (userTeam == 1) { // adds cap to Red team | |
updateRedCaps += 1; | |
} | |
else if (userTeam == 2) { // adds cap to Blue team | |
updateBlueCaps += 1; | |
} | |
if ((userTeam == 1 || userTeam == 2) && (updateRedCaps != 0 || updateBlueCaps != 0 || firstSound === true)) { // enter the cap update if the above scenarios are met | |
if (sendCheck === true && playerLate === false && playerCompCheck > 0) { // if the user has allowed sending data, send cap update | |
capUpdate(updateRedCaps, updateBlueCaps, startTime, groupPort, tableExport, teamNum, groupServer, false); | |
} | |
if (firstSound === true) { | |
firstSound = false; | |
} | |
} | |
}, false); //Note: play event does not activate if sounds are muted | |
document.getElementById("sigh").addEventListener("play", function() { // sigh plays when other team caps | |
if (userTeam == 1) { // adds cap to Blue team | |
updateBlueCaps += 1; | |
} | |
else if (userTeam == 2) { // adds cap to Red team | |
updateRedCaps += 1; | |
} | |
if (userTeam == 1 || userTeam == 2) { // enter the cap update if the above scenarios are met | |
if (sendCheck === true && playerLate === false && playerCompCheck > 0) { // if the user has allowed sending data, send cap update | |
capUpdate(updateRedCaps, updateBlueCaps, startTime, groupPort, tableExport, teamNum, groupServer, false); | |
} | |
} | |
}, false); // However, play event does activate is volume is set to 0 (but no mute) | |
var forceChangeEvent = new Event('change'); // define a change event to force volume update | |
if (soundCheck === true) { // if user has enabled sound checks | |
setTimeout(function(){ // check and update volume | |
if (document.getElementById("soundEffects").className == "off") { | |
// manually reset volume if it is off | |
document.getElementById("soundEffects").click(); | |
document.getElementById("volumeSlider").value = -50; | |
document.getElementById("volumeSlider").dispatchEvent(forceChangeEvent); | |
} | |
}, 500); | |
document.getElementById("soundEffects").addEventListener("click", function() { | |
setTimeout(function(){ | |
if (document.getElementById("soundEffects").className == "off") { | |
document.getElementById("soundEffects").click(); | |
document.getElementById("volumeSlider").value = -50; | |
document.getElementById("volumeSlider").dispatchEvent(forceChangeEvent); | |
} | |
}, 500); | |
}, false); | |
} | |
if (GM_getValue("tpcsStartTime",0) > 0) { // If the start time was previously saved (i.e. player refreshed), call back | |
startTime = GM_getValue("tpcsStartTime"); | |
updateRedCaps = GM_getValue("tpcsRefreshRed", 0); | |
updateBlueCaps = GM_getValue("tpcsRefreshBlue", 0); | |
playerLate = false; | |
firstSound = false; | |
} | |
setInterval(function() { | |
if (document.getElementById("options").style.display == "block") { // If the table is open, save stats | |
var playerStats = getStats(); // This was split into a function because I'm trying to see if the stats table can be updated without having the table open | |
tableExport = playerStats[0]; | |
teamNum = playerStats[1]; | |
backscoreRedCaps = playerStats[2][0]; | |
backscoreBlueCaps = playerStats[2][1]; | |
} | |
}, 100); // update ten times per second | |
document.onkeydown = function() { // This function sends a backup of the scoreboard in case partial stats are needed or stats need to be recreated. | |
if (event.keyCode == 27) { // 27 corresponds to escape key | |
setTimeout(function() { // setTimeout is used to ensure the scoreboard is updated before the stats get sent | |
if (document.getElementById("options").style.display == "block") { // checks if scoreboard is open | |
if (sendCheck === true) { // sends partial stats if the user has allowed sending data | |
capUpdate(backscoreRedCaps, backscoreBlueCaps, startTime, groupPort, tableExport, teamNum, groupServer, false); | |
} | |
} | |
}, 500); | |
} | |
}; | |
window.onbeforeunload = function() { //send stats before exiting the game | |
GM_setValue("tpcsLateFlag", true); // set the late flag to true in case the user refreshes. | |
GM_setValue("tpcsRefreshRed", updateRedCaps); | |
GM_setValue("tpcsRefreshBlue", updateBlueCaps); | |
if (typeof(backscoreRedCaps) == "undefined") { // undefined happens when there is no player on a team, so redefine to 0. | |
backscoreRedCaps = 0; | |
} | |
if (typeof(backscoreBlueCaps) == "undefined") { | |
backscoreBlueCaps = 0; | |
} | |
if (sendCheck === true && localCheck === false) { // send stats, but do not save locally | |
submitStats(backscoreRedCaps, backscoreBlueCaps, tableExport, teamNum, startTime, groupPort, groupServer, false, 0); | |
} | |
else if (sendCheck === true && localCheck === true) { // send stats AND save locally | |
submitStats(backscoreRedCaps, backscoreBlueCaps, tableExport, teamNum, startTime, groupPort, groupServer, false, 1); | |
} | |
else { // only save stats locally | |
submitStats(backscoreRedCaps, backscoreBlueCaps, tableExport, teamNum, startTime, groupPort, groupServer, false, 2); | |
} | |
}; | |
} | |
else if (GM_getValue("compCheck", 0) >= 1 && tagproConfig && tagproConfig.gameSocket) { // Spectator mode | |
// A check is needed here because there is no difference between this and a regular public game | |
// Note: On the test server, the tagpro object is currently disabled as a spec, meaning that the script will trigger player mode for spectators | |
GM_setValue("tpcsLateFlag", false); // It doesn't matter if a spectator is late since they have access to the tagpro object | |
var specLink = tagproConfig.gameSocket; | |
var specServer = specLink.split("-")[1].split(".")[0]; | |
var specGroupPort = specLink.split(":")[1]; | |
var ma = new Date(); | |
var specStartTime = (Math.floor(ma.getTime() / 1000) + ma.getTimezoneOffset() * 60) + 20; // set redundant start time | |
var specRedCaps = 0; | |
var specBlueCaps = 0; | |
var endSubmit = false; // endSubmit is a flag for the end event | |
var firstUpdate = false; | |
var specUpdateCheck = GM_getValue("tpcsConfirmation", false); | |
var specLocalCheck = GM_getValue("backLocalStorage", false); | |
console.log("TagPro Competitive Stats is now running in Spectator mode on " + specServer + ":" + specGroupPort); | |
tagpro.ready(function() { | |
if ((GM_getValue("backRedJersey", false) || GM_getValue("backBlueJersey", false)) && GM_getValue("backJerseyFlag", true)) { // adapted version of Some Ball -1's jersey script | |
var red = GM_getValue("backRedJersey"); // grab jersey data from the group | |
var blue = GM_getValue("backBlueJersey"); | |
var jersey = [red === "none" ? false : red, blue === "none" ? false : blue, GM_getValue("ballRedTrans", 1), GM_getValue("ballBlueTrans", 1), GM_getValue("jerseyRedTrans", 1), GM_getValue("jerseyBlueTrans", 1)]; // set an array for jersey data for easy processing | |
if (jersey[0] || jersey[1]) { // If either team has jerseys, get the jersey image | |
var tr = tagpro.renderer, | |
oldUPSP = tr.updatePlayerSpritePosition; | |
tr.createJersey = function(player) { | |
if (!jersey[player.team - 1]) { // make empty container if one team doesn't have a jersey | |
if (player.sprites.jersey) player.sprites.ball.removeChild(player.sprites.jersey); | |
player.sprites.jersey = new PIXI.DisplayObjectContainer(); | |
player.sprites.jersey.team = player.team; | |
player.sprites.ball.addChildAt(player.sprites.jersey, 1); | |
} | |
else { // make container for jersey | |
if (player.sprites.jersey) { | |
player.sprites.ball.removeChild(player.sprites.jersey); | |
} | |
player.sprites.jersey = new PIXI.Sprite(PIXI.Texture.fromImage("http://i.imgur.com/" + jersey[player.team - 1] + ".png")); | |
player.sprites.jersey.team = player.team; | |
player.sprites.ball.addChildAt(player.sprites.jersey, 1); //add on top of ball, below other stuff | |
player.sprites.jersey.anchor.x = 0.5; | |
player.sprites.jersey.anchor.y = 0.5; | |
player.sprites.jersey.x = 20; | |
player.sprites.jersey.y = 20; | |
if (jersey[player.team + 1] < 1 && jersey[player.team + 1] >= 0) { // set transparency value for actual ball | |
player.sprites.actualBall.alpha = jersey[player.team + 1]; | |
} | |
else { // reset | |
player.sprites.actualBall.alpha = 1; | |
} | |
if (jersey[player.team + 3] < 1 && jersey[player.team + 3] >= 0) { // set transparency value for jersey | |
player.sprites.jersey.alpha = jersey[player.team + 3]; | |
} | |
else { // reset | |
player.sprites.jersey.alpha = 1; | |
} | |
} | |
}; | |
tr.updatePlayerSpritePosition = function(player) { | |
if (!player.sprites.jersey) { | |
tr.createJersey(player); | |
} | |
if (player.sprites.jersey.team !== player.team) { | |
tr.createJersey(player); | |
} | |
var index = player.sprites.ball.getChildIndex(player.sprites.actualBall) + 1; | |
if (index !== player.sprites.ball.getChildIndex(player.sprites.jersey)) { | |
player.sprites.ball.setChildIndex(player.sprites.jersey, index); | |
} | |
if (GM_getValue("backJerseySpin", true)) { | |
player.sprites.jersey.rotation = player.angle; | |
} | |
oldUPSP(player); | |
}; | |
} | |
} | |
setTimeout(function () { | |
var tempStartTime = Math.floor(tagpro.gameEndsAt.getTime() / 1000) + tagpro.gameEndsAt.getTimezoneOffset() * 60; // returns UTC | |
if (tempStartTime <= specStartTime + 10) { // If you're in the 20 second waiting period, tagpro.gameEndsAt will return when the game starts | |
// A 10 second buffer is added for people who have faster balls. | |
// Note that the 10 second buffer does not affect which statement is triggered since if the user is in game, gameEndsAt will return a completely different time. | |
specStartTime = tempStartTime; | |
} | |
else { // user is in game, subtract game length from designated end time | |
specStartTime = tempStartTime - (parseInt(GM_getValue("groupTime", "10")) * 60); | |
} | |
var currentId = sortByScore(Object.getOwnPropertyNames(tagpro.players)); | |
var capStats = getSpecStats(currentId); | |
if (specUpdateCheck === true) { // the first cap update comes from here since it has the correct start time | |
capUpdate(tagpro.score.r, tagpro.score.b, specStartTime, specGroupPort, capStats[0], capStats[1], specServer, true); | |
} | |
firstUpdate = true; | |
}, 1000); // tagpro.gameEndsAt is not immediately available, so ping a little after | |
tagpro.socket.on("score", function(data) { // Cap update condition | |
if (firstUpdate === true && (tagpro.score.r != 0 || tagpro.score.b != 0)) { // score event gets spammed on occasion before the beginning of the game due to bad connection, so only process if caps are not zero | |
if ('r' in data) { // process red | |
specRedCaps = data.r; | |
} | |
if ('b' in data) { // process blue | |
specBlueCaps = data.b; | |
} | |
var currentId = sortByScore(Object.getOwnPropertyNames(tagpro.players)); | |
var capStats = getSpecStats(currentId); | |
if (specUpdateCheck === true) { // send data if user has allowed it | |
capUpdate(specRedCaps, specBlueCaps, specStartTime, specGroupPort, capStats[0], capStats[1], specServer, true); | |
} | |
} | |
}); | |
tagpro.socket.on("end", function(data) { // submit stats when the end event is sent by the server | |
var finalId = sortByScore(Object.getOwnPropertyNames(tagpro.players)); // sort IDs of players in the game by their score | |
var specStats = getSpecStats(finalId); // get the stats using finalId | |
if (specUpdateCheck === true && specLocalCheck === false) { // send stats, but do not save locally | |
submitStats(specRedCaps, specBlueCaps, specStats[0], specStats[1], specStartTime, specGroupPort, specServer, true, 0); | |
} | |
else if (specUpdateCheck === true && specLocalCheck === true) { // send stats AND save locally | |
submitStats(specRedCaps, specBlueCaps, specStats[0], specStats[1], specStartTime, specGroupPort, specServer, true, 1); | |
} | |
else { // only save stats locally | |
submitStats(specRedCaps, specBlueCaps, specStats[0], specStats[1], specStartTime, specGroupPort, specServer, true, 2); | |
} | |
endSubmit = true; | |
}); | |
/*tagpro.socket.on("playerLeft", function (id) { | |
// support for players leaving will be added in a future update. | |
});*/ | |
}); | |
window.onbeforeunload = function() { // sends stats if you leave the game for some reason before the end event, or if stats fail to send during the end event | |
if (endSubmit === false) { | |
var finalId = sortByScore(Object.getOwnPropertyNames(tagpro.players)); | |
var specStats = getSpecStats(finalId); | |
if (specUpdateCheck === true && specLocalCheck === false) { // send stats, but do not save locally | |
submitStats(specRedCaps, specBlueCaps, specStats[0], specStats[1], specStartTime, specGroupPort, specServer, false, 0); | |
} | |
else if (specUpdateCheck === true && specLocalCheck === true) { // send stats AND save locally | |
submitStats(specRedCaps, specBlueCaps, specStats[0], specStats[1], specStartTime, specGroupPort, specServer, false, 1); | |
} | |
else { // only save stats locally | |
submitStats(specRedCaps, specBlueCaps, specStats[0], specStats[1], specStartTime, specGroupPort, specServer, false, 2); | |
} | |
} | |
}; | |
} | |
else { // script has been called on a page that is not a comp game or relating to groups | |
console.log(GM_info.script.name + " running in non-league mode."); | |
} | |
})(unsafeWindow); | |
// Misc Functions, alphabetical order by name of function | |
function capUpdate(updateRedCaps, updateBlueCaps, startTime, groupPort, tableExport, teamNum, groupServer, specFlag) { // send cap update | |
var y = new Date(); | |
var currentTime = (Math.floor(y.getTime() / 1000) + y.getTimezoneOffset() * 60); // gets start time in UTC | |
var backscoreUpdate = "https://docs.google.com/forms/d/e/1FAIpQLSe57NOVRdas-tzT4MZ8-XPSkNO3MyKCTrAOyFGXp4PtNQcdkQ/formResponse?entry.133949532=" + GM_getValue("backscoreRedAbr", "Red") + "&entry.454687569=" + GM_getValue("backscoreBlueAbr", "Blue") + "&entry.184122371=" + updateRedCaps + "&entry.1906941178=" + updateBlueCaps + "&entry.2120828603=" + groupServer + "&entry.1696460484=" + GM_getValue("groupId", "none") + "&entry.968816448=" + GM_getValue("groupMap", "none") + "&entry.1523561265=" + startTime + "&entry.1474408630=" + currentTime + "&entry.1681155627=" + groupPort + "&entry.1189129646=" + GM_getValue("groupTime", "none") + "&entry.2065162742=" + encodeURIComponent(tableExport.toString()) + "&entry.2098213735=" + teamNum.toString(); | |
if (currentTime - startTime < GM_getValue("groupTime", 0) * 60 && GM_getValue("backscoreBlueAbr", "Blue") != "Blue" && GM_getValue("backscoreRedAbr", "Red") != "Red") { // don't send a cap update if any of the team names are default | |
var capUpdateRequest = new XMLHttpRequest(); | |
capUpdateRequest.open("POST", backscoreUpdate + "&entry.197322272=" + GM_getValue("backscorePlayer", "Some%20Ball") + ((specFlag === true) ? "%20[S]" : "") + "&submit=Submit"); | |
capUpdateRequest.send(); | |
console.log("Cap detected, score update sent and is now " + updateRedCaps + "-" + updateBlueCaps); | |
} | |
} | |
function changeLeader(status) { | |
if (status) { // status returns whether or not the user is the leader of the group | |
if (!!document.getElementById("autoscoreLeague") && !!document.getElementById("redTeamAbr")) { // unhide leader elements if the user already had them loaded | |
document.getElementById("autoscoreLeague").style.display = "block"; | |
document.getElementById("redTeamAbr").style.display = "block"; | |
document.getElementById("blueTeamAbr").style.display = "block"; | |
} | |
else { // if the leader elements are not loaded, run the leaderReady function | |
leaderReady(); | |
} | |
} | |
else { // changeLeader(false) only happens when the leader elements already exist, so hide leader elements | |
if (!!document.getElementById("autoscoreLeague") && !!document.getElementById("redTeamAbr")) { | |
document.getElementById("autoscoreLeague").style.display = "none"; | |
document.getElementById("redTeamAbr").style.display = "none"; | |
document.getElementById("blueTeamAbr").style.display = "none"; | |
} | |
} | |
} | |
function compCheck() { | |
var checkSum = 0; | |
var checkToggles = 0; | |
var extraSettingsNum = document.getElementsByClassName("js-setting-value").length; | |
var defaultSettings = ["Random", "10 Minutes", "No Overtime", "No Capture Limit", "No Mercy Rule", "100% (Default)", "100% (Default)", "100% (Default)", "3 Seconds (Default)", "10 Seconds (Default)", "30 Seconds (Default)", "1 Minute (Default)", "Enabled", "Disabled (Default)", "Disable", "Disable", "Disabled", "Disabled"]; | |
for (var i = 1; i < extraSettingsNum; i++) { | |
if (i == 2) { | |
continue; | |
} | |
var extraSetting = document.getElementsByClassName("js-setting-value")[i].innerText; | |
if (extraSetting == defaultSettings[i]) { | |
checkSum++; | |
} | |
if (extraSetting == defaultSettings[i] && i >= 14) { | |
checkToggles++; | |
} | |
} | |
return [checkSum, checkToggles]; | |
} | |
function download(content, fileName, contentType) { // this function exports game data into a json file | |
var a = document.createElement("a"); | |
var file = new Blob([content], {type: contentType}); | |
a.href = URL.createObjectURL(file); | |
a.download = fileName; | |
a.click(); | |
} | |
function getJerseys() { // set jerseys for each team | |
var specRedTeam = GM_getValue("backscoreRedAbr", "none"); | |
var specBlueTeam = GM_getValue("backscoreBlueAbr", "none"); | |
var teamJersey = GM_getValue("jerseyLinks"); | |
if (teamJersey.hasOwnProperty(specRedTeam)) { // If jersey exists, set jersey | |
GM_setValue("backRedJersey", teamJersey[specRedTeam][0]); | |
GM_setValue("ballRedTrans", teamJersey[specRedTeam][2]); | |
GM_setValue("jerseyRedTrans", teamJersey[specRedTeam][4]); | |
} | |
else { // otherwise, set to false to avoid issues | |
GM_setValue("backRedJersey", false); | |
GM_setValue("ballRedTrans", 1); | |
GM_setValue("jerseyRedTrans", 1); | |
} | |
if (teamJersey.hasOwnProperty(specBlueTeam)) { // repeat for blue | |
GM_setValue("backBlueJersey", teamJersey[specBlueTeam][1]); | |
GM_setValue("ballBlueTrans", teamJersey[specBlueTeam][3]); | |
GM_setValue("jerseyBlueTrans", teamJersey[specBlueTeam][5]); | |
} | |
else { | |
GM_setValue("backBlueJersey", false); | |
GM_setValue("ballBlueTrans", 1); | |
GM_setValue("jerseyBlueTrans", 1); | |
} | |
} | |
function getSpecStats(finalId) { | |
var specExport = []; | |
var specTeamExport = []; | |
for (var i in finalId) { | |
if (tagpro.players[finalId[i]]) { | |
var playerrow = []; | |
var playerObject = tagpro.players[finalId[i]]; | |
playerrow = [playerObject.auth ? "✓" + playerObject.name : playerObject.name, playerObject.score, playerObject["s-tags"], playerObject["s-pops"], playerObject["s-grabs"], playerObject["s-drops"], timeFromSeconds(playerObject["s-hold"], true), playerObject["s-captures"], timeFromSeconds(playerObject["s-prevent"], true), playerObject["s-returns"], playerObject["s-support"], playerObject["s-powerups"]]; | |
specExport.push(playerrow); | |
specTeamExport.push(playerObject.team); | |
} | |
} | |
return [specExport, specTeamExport]; | |
} | |
function getStats() { | |
var statPlayers = document.getElementsByTagName("table").stats.rows.length; | |
var tableExport = []; | |
var scoreboardCaps = [0, 0]; | |
var teamNum = []; | |
for (var i = 2; i < statPlayers; i++) { // This part pushes the stats table into an array to be exported later. | |
var playerPush = []; | |
var playerTeam = document.getElementsByTagName("table").stats.rows[i].getElementsByClassName("team-blue").length; | |
teamNum.push(playerTeam + 1); | |
for (var j = 0; j <= 11; j++) { | |
var editVal = document.getElementsByTagName("table").stats.rows[i].cells[j].innerText; | |
if (j == 0) { | |
if (editVal.substring(0, 1) == "✓") { // remove whitespace between checkmark and name | |
editVal = "✓".concat(editVal.substring(1).trim()); | |
} | |
else { | |
editVal = editVal.trim(); | |
} | |
} | |
else if (j == 7) { // add team caps | |
scoreboardCaps[playerTeam] += parseInt(editVal); | |
} | |
playerPush.push(editVal); | |
} | |
tableExport.push(playerPush); | |
} | |
return [tableExport, teamNum, scoreboardCaps]; | |
} | |
function groupEscape(group, checkVersion) { | |
var groupPlayers = Object.keys(tagpro.group.players); | |
var pubCount = 0; | |
for (var g = 0; g < groupPlayers.length; g++) { // This function checks if anyone is in pub team (team 0) | |
if (tagpro.group.players[groupPlayers[g]].team == 0) | |
{ | |
pubCount++; | |
} | |
} | |
if (pubCount == 0) { | |
if (typeof group != "undefined" && typeof group.self != "undefined" && typeof group.players != "undefined") { | |
GM_setValue("userTeam", group.players[group.self].team); | |
} | |
else if (typeof group.self == "undefined") { | |
GM_setValue("userTeam", "none"); | |
} | |
GM_setValue("backscoreRedAbr", document.getElementsByTagName("input").redTeamName.value); | |
GM_setValue("backscoreBlueAbr", document.getElementsByTagName("input").blueTeamName.value); | |
GM_setValue("groupMap", document.getElementsByTagName("select").map.value); | |
GM_setValue("groupTime", document.getElementsByTagName("select").time.value); | |
GM_setValue("groupCapLimit", document.getElementsByTagName("select").caps.value); | |
GM_setValue("tpcsStartTime", 0); | |
if (tagpro.group.players[GM_getValue("tpUserId", undefined)]) { // set the name of the user based on their name in group | |
GM_setValue("backscorePlayer", encodeURIComponent(tagpro.group.players[GM_getValue("tpUserId", undefined)].name + " (" + checkVersion + ")")); | |
} | |
else { // if the group var is corrupt, set name to Some Ball | |
GM_setValue("backscorePlayer", encodeURIComponent("Some Ball (" + checkVersion + ")")); | |
} | |
var escapeCheck = compCheck(); | |
if (escapeCheck[0] >= 15 && escapeCheck[1] == 4) { | |
if (escapeCheck[0] == 16 || document.getElementsByClassName("js-setting-value")[1].innerText != "10 Minutes") { // If minutes is the only thing which doesn't match, then it's still a legal comp game | |
GM_setValue("compCheck", 2); // state 2 matches a standard comp game | |
getJerseys(); | |
} | |
else { | |
GM_setValue("compCheck", 1); // state 1 matches a comp game with non-default settings (ex. 1 second boost) | |
getJerseys(); | |
} | |
} | |
else if (escapeCheck[1] == 4) { | |
GM_setValue("compCheck", 1); | |
getJerseys(); | |
} | |
else { // If not enough checks passed or if a player was detected on the pub team, comp check fails. | |
GM_setValue("compCheck", 0); // state 0 matches a pub group or a group which does not have comp toggle activated | |
} | |
} | |
else { | |
GM_setValue("compCheck", 0); | |
} | |
} | |
function groupReady(isLeader) { // grab necessary info from the group | |
tagpro.ready(function() { | |
var jerseyRequest = new XMLHttpRequest(); | |
jerseyRequest.open("GET", "https://raw.githubusercontent.com/Poeticalto/tagpro-comp-stats/stable/jerseys.json"); // This json contains a master list of jerseys | |
jerseyRequest.responseType = "json"; | |
jerseyRequest.send(); | |
jerseyRequest.onload = function() { | |
GM_setValue("jerseyLinks", jerseyRequest.response); | |
} | |
var mapRequest = new XMLHttpRequest(); | |
mapRequest.open("GET", "https://raw.githubusercontent.com/Poeticalto/tagpro-comp-stats/stable/customMaps.json"); // This json contains a master list of custom maps | |
mapRequest.responseType = "json"; | |
mapRequest.send(); | |
mapRequest.onload = function() { | |
mapRequest.response; | |
let mapTestKeys = Object.keys(mapRequest.response); | |
for (let i = 0; i < mapTestKeys.length; i++) { | |
let currentLabel = document.createElement("optgroup"); | |
currentLabel.label = mapTestKeys[i]; | |
let currentList = mapRequest.response[mapTestKeys[i]]; | |
for (let j = 0; j < mapRequest.response[mapTestKeys[i]].length; j++) { | |
let currentOption = document.createElement("option"); | |
currentOption.text = currentList[j].name; | |
currentOption.value = "id/"+currentList[j].mapID.toString(); | |
currentLabel.appendChild(currentOption); | |
} | |
document.getElementsByName("map")[1].appendChild(currentLabel); | |
} | |
} | |
var group = tagpro.group = Object.assign(tagpro.group, { | |
self: GM_getValue("tpUserId", undefined), | |
players: {} | |
}); | |
var socket = group.socket; | |
socket.on("member", function(member) { | |
group.players[member.id] = Object.assign(group.players[member.id] || {}, member); | |
if (typeof tagpro.group.players[GM_getValue("tpUserId", undefined)] != "undefined") { | |
if (tagpro.group.players[GM_getValue("tpUserId")].leader != isLeader) { | |
isLeader = tagpro.group.players[GM_getValue("tpUserId")].leader; | |
changeLeader(isLeader); | |
} | |
} | |
}); | |
var checkVersion = GM_getValue("tpcsCurrentVer",0); | |
setTimeout(function(){ | |
if (checkVersion != GM_info.script.version || GM_getValue("tpcsConfirmation", false) === false) { | |
checkVersion = GM_info.script.version; | |
GM_setValue("tpcsCurrentVer",checkVersion); | |
var updateNotes = "The TagPro Competitive Stats Userscript has been updated to V" + GM_info.script.version + "!\nHere is a summary of updates:\n1. Overtime is off by default in comp groups\n2. Added ability to set custom map lists\n3. Updated comp check functions to support overtime\n4. Added new custom option to support H2 overtime\n5. General Cleanup\nClicking Ok means you accept the changes to this script and the corresponding privacy policy.\nThe full privacy policy and change log can be found by going to the script homepage through the Tampermonkey menu."; | |
GM_setValue("tpcsConfirmation", window.confirm(updateNotes)); | |
} | |
},1000); | |
socket.on("play", function() { // play event | |
groupEscape(group, checkVersion); // groupEscape grabs the necessary data from the group page | |
GM_setValue("tpcsLateFlag", false); | |
}); | |
document.getElementById("join-game-btn").onclick = function() { // join button, or player enters game late | |
// note: If a player enters the game late using the join game button, any stats they send when they leave will be marked incomplete due to time. | |
// This can be corrected on the server side if needed. | |
groupEscape(group, checkVersion); | |
GM_setValue("tpcsLateFlag", true); | |
}; | |
}); | |
} | |
function leaderReady() { | |
console.log("Group leader detected, setting up group"); | |
if (window.location.href.split(".com")[1].match(/^\/groups\/[a-z]{8}\/#tg-*[ 0-z]*$/) || GM_getValue("setMap", "none") != "none") { // set up map if passed through | |
var mapName = ""; | |
var mapList = document.getElementsByClassName("form-control js-socket-setting")[0]; | |
if (GM_getValue("setMap", "none") == "none") { // map name is in the url | |
mapName = window.location.href.split("-")[2].replace(" ", "_").toLowerCase(); | |
} | |
else { // map name is in "setMap" | |
mapName = GM_getValue("setMap", "none").replace(" ", "_").toLowerCase(); | |
} | |
GM_setValue("setMap", "none"); | |
var mapNameKey = { // This is the list of TagPro maps which does not follow standard naming conventions | |
"angry_pig": "AngryPig", | |
"bombing_run": "bomber", | |
"center_flag": "centerflag", | |
"command_center": "CommandCenter", | |
"danger_zone_3": "DangerZone", | |
"geokoala": "teamwork", | |
"hurricane": "Hurricane2", | |
"hyper_reactor": "HyperReactor", | |
"mars_ball_explorer": "WelcomeToMars", | |
"mars_game_mode": "GameMode", | |
"mode_7": "Mode7", | |
"snes_v2": "snes", | |
"thinking_with_portals": "ThinkingWithPortals", | |
"big_vird": "vee2", | |
"blast_off": "blastoff", | |
"boostsv2.1": "Boosts", | |
"contain_masters": "ContainMasters", | |
"diamond_faces": "Diamond", | |
"dumbell": "fullspeed", | |
"event_horizon": "eventhorizon", | |
"event_horizon_2": "eventhorizon2", | |
"figure_8": "map2-2", | |
"glory_hole": "RiskAndReward", | |
"grail_of_speed": "GrailOfSpeed", | |
"open_field_masters": "OFM", | |
"pokeball": "community1", | |
"push_it": "PushIt", | |
"the_holy_see": "HolySee", | |
"holy_see": "HolySee", | |
"vee": "bird", | |
"whirlwind_2": "whirlwind", | |
"yiss_3.2": "yiss 3.2", | |
"egg_ball": "mode/eggball" | |
}; | |
Array.apply(null, mapList).forEach(function(mapOption) { // get the rest of the map names from the group | |
var name = mapOption.value; | |
mapNameKey[name.toLowerCase()] = name; | |
}); | |
var map = mapNameKey[mapName] || ""; // defaults to random if the map name is not found | |
tagpro.group.socket.emit("setting", {name: "map", value: map}); // syncs map change to server | |
} | |
if (GM_getValue("makepug", false) === true) { // If the group has been passed through with a toggle, automatically set competitive settings | |
console.log("Automated new group detected, setting comp settings"); | |
document.getElementById("pug-btn").click(); | |
document.getElementsByName("competitiveSettings")[0].click(); | |
GM_setValue("makepug", false); | |
} | |
setTimeout(function(){ | |
document.getElementById("pug-btn").onclick = function() { // If group is private, turn the group into a comp game | |
console.log("Private group detected, setting up comp settings"); | |
if (document.getElementsByName("competitiveSettings")[0].checked === false) { | |
document.getElementsByName("competitiveSettings")[0].click(); // Turns on competitive settings | |
tagpro.group.socket.emit("setting", { name: "overtime", value: "false"}); | |
} | |
if (!!document.getElementById("autoscoreLeague") && !!document.getElementById("redTeamAbr")) { // unhide leader elements if the user already had them loaded | |
document.getElementById("autoscoreLeague").style.display = "block"; | |
document.getElementById("redTeamAbr").style.display = "block"; | |
document.getElementById("blueTeamAbr").style.display = "block"; | |
} | |
} | |
},100); | |
GM_setValue("groupId", window.location.href.split("/")[4]); | |
var buttonSettings = document.getElementsByClassName("pull-left player-settings")[0]; | |
var selectList = document.createElement("select"); // selectList is the League selector in group | |
selectList.id = "autoscoreLeague"; | |
buttonSettings.appendChild(selectList); | |
selectList.className = "form-control js-socket-setting"; | |
selectList.style.margin = "1% 0%"; | |
if (document.getElementById("pub-btn").offsetParent === null) { | |
selectList.style.display = "none"; | |
} | |
else { | |
selectList.style.display = "block"; | |
} | |
selectList.title = "Click here to set a league for team abbreviations or change custom settings!"; | |
var abbrRequest = new XMLHttpRequest(); | |
abbrRequest.open("GET", "https://raw.githubusercontent.com/Poeticalto/tagpro-comp-stats/stable/teams.json"); // This json contains the abbreviations to use in group | |
abbrRequest.responseType = "json"; | |
abbrRequest.send(); | |
abbrRequest.onload = function() { | |
GM_setValue("autoscoreAbr", abbrRequest.response); | |
var array = abbrRequest.response.Leagues; | |
array["TagPro Competitive Stats Settings"] = [GM_getValue("backMLTPOvertime", false) ? "Disable H2 Overtime [Currently Enabled]" : "Enable H2 Overtime [Currently Disabled]", GM_getValue("backJerseyFlag", true) ? "Disable Jerseys [Currently Enabled]" : "Enable Jerseys [Currently Disabled]", GM_getValue("backJerseySpin", true) ? "Disable Jersey Spin [Currently Enabled]" : "Enable Jersey Spin [Currently Disabled]", GM_getValue("backLocalStorage", false) ? "Disable Saving Local Stats [Currently Enabled]" : "Enable Saving Local Stats [Currently Disabled]", GM_getValue("backAbbrCheck", true) ? "Disable Abbreviation Checks [Currently Enabled]" : "Enable Abbreviation Checks [Currently Disabled]", GM_getValue("tpcsSoundCheck", true) ? "Disable Sound Checks [Currently Enabled]" : "Enable Sound Checks [Currently Disabled]"]; | |
var noneOption = document.createElement("option"); | |
noneOption.value = "None"; | |
noneOption.text = "None"; | |
selectList.appendChild(noneOption); | |
var regionList = Object.keys(array); | |
var leagueList = []; | |
for (var i = 0; i < regionList.length; i++) { // Fill in the league selector with the leagues in the json | |
var optionParent = document.createElement("optgroup"); | |
optionParent.label = regionList[i]; | |
selectList.appendChild(optionParent); | |
var leaguesToAdd = array[regionList[i]]; | |
for (var j = 0; j < leaguesToAdd.length; j++) | |
{ | |
var optionToAdd = document.createElement("option"); | |
optionToAdd.value = leaguesToAdd[j]; | |
optionToAdd.text = leaguesToAdd[j]; | |
optionParent.appendChild(optionToAdd); | |
leagueList.push(leaguesToAdd[j]); | |
} | |
} | |
if (leagueList.indexOf(GM_getValue("autoscoreImport", "None")) > -1) { // Standard Import Condition | |
selectList.value = GM_getValue("autoscoreImport", "None"); | |
} | |
else { // This happens when the league has been removed from the teams json, usually because the season is over or league is dead | |
selectList.value = "None"; | |
} | |
updateTeamAbr(); | |
document.getElementById("autoscoreLeague").onchange = function() { // redo team names when league is changed | |
updateTeamAbr(); | |
}; | |
} | |
document.getElementById("launch-private-btn").onmouseover = function () { | |
var alertCheck = compCheck()[0]; | |
if (alertCheck == 13) { // all checks passed, so enter abbr check | |
var checkTime = new Date(); | |
var checkProcess = (Math.floor(checkTime.getTime() / 1000) + checkTime.getTimezoneOffset() * 60); // get the current time | |
var oldId = GM_getValue("launchGroupId","none"); // last group ID | |
var currentId = GM_getValue("groupId", "none"); // current group ID | |
var oldTime = GM_getValue("checkTime",0); // last time when notification was shown | |
var teamNameCheck = true; // default value, should pass | |
if (document.getElementsByTagName("input").redTeamName.value == "Red" || document.getElementsByTagName("input").blueTeamName.value == "Blue") { // change the check to fail if either of the team names are default (Red for red team, Blue for blue team) | |
teamNameCheck = false; | |
} | |
if (((checkProcess - oldTime) >= (15*60) || currentId != oldId) && teamNameCheck === false && GM_getValue("backAbbrCheck", true) === true) { // If it has been 15 minutes or the group has changed since the last check, and abbr check failed, and user allowed notifs, then execute | |
GM_setValue("checkTime", checkProcess); | |
GM_setValue("launchGroupId", currentId); | |
window.alert("A competitive game was detected without proper abbreviations!\nMake sure your abbreviations are set before launching!"); | |
} | |
} | |
} | |
document.getElementById("pub-btn").onclick = function() { | |
document.getElementById("autoscoreLeague").style.display = "none"; | |
if (!!document.getElementById("redTeamAbr")) { // In case element does not exist (i.e. function is called before the updateTeamAbr() function is called) | |
document.getElementById("redTeamAbr").style.display = "none"; | |
document.getElementById("blueTeamAbr").style.display = "none"; | |
} | |
} | |
document.getElementById("pug-btn").onclick = function() { | |
document.getElementById("autoscoreLeague").style.display = "block"; | |
if (!!document.getElementById("redTeamAbr") && document.getElementById("autoscoreLeague").value != "None") { // Don't interrupt default behavior of none | |
document.getElementById("redTeamAbr").style.display = "block"; | |
document.getElementById("blueTeamAbr").style.display = "block"; | |
} | |
} | |
} | |
function openSettings(setting) { | |
var newSetting = ""; | |
if (setting == "Disable H2 Overtime [Currently Enabled]") { | |
GM_setValue("backMLTPOvertime", false); | |
newSetting = "Enable H2 Overtime [Currently Disabled]"; | |
tagpro.group.socket.emit("setting", { name: "overtime", value: "false"}); | |
tagpro.group.socket.emit("setting", { name: "redTeamScore", value: "0"}); | |
tagpro.group.socket.emit("setting", { name: "blueTeamScore", value: "0"}); | |
} | |
else if (setting == "Enable H2 Overtime [Currently Disabled]") { | |
GM_setValue("backMLTPOvertime", true); | |
newSetting = "Disable H2 Overtime [Currently Enabled]"; | |
tagpro.group.socket.emit("setting", { name: "overtime", value: "true"}); | |
let lastGameData = GM_getValue("tpcsLastGame",[{name:"Red",score:0},{name:"Blue",score:0}]); | |
let curRedName = document.getElementsByName("redTeamName")[0].value; | |
let curBlueName = document.getElementsByName("blueTeamName")[0].value; | |
if (document.getElementsByName("redTeamName")[0].value == lastGameData[0].name) { | |
document.getElementById("swapTeams-btn").click(); | |
if (curRedName == lastGameData[0].name) { | |
tagpro.group.socket.emit("setting", { name: "blueTeamScore", value: lastGameData[0].score.toString()}); | |
} | |
else if (curRedName == lastGameData[1].name) { | |
tagpro.group.socket.emit("setting", { name: "blueTeamScore", value: lastGameData[1].score.toString()}); | |
} | |
if (curBlueName == lastGameData[0].name) { | |
tagpro.group.socket.emit("setting", { name: "redTeamScore", value: lastGameData[0].score.toString()}); | |
} | |
else if (curBlueName == lastGameData[1].name) { | |
tagpro.group.socket.emit("setting", { name: "redTeamScore", value: lastGameData[1].score.toString()}); | |
} | |
} | |
else { | |
if (curRedName == lastGameData[0].name) { | |
tagpro.group.socket.emit("setting", { name: "redTeamScore", value: lastGameData[0].score.toString()}); | |
} | |
else if (curRedName == lastGameData[1].name) { | |
tagpro.group.socket.emit("setting", { name: "redTeamScore", value: lastGameData[1].score.toString()}); | |
} | |
if (curBlueName == lastGameData[0].name) { | |
tagpro.group.socket.emit("setting", { name: "blueTeamScore", value: lastGameData[0].score.toString()}); | |
} | |
else if (curBlueName == lastGameData[1].name) { | |
tagpro.group.socket.emit("setting", { name: "blueTeamScore", value: lastGameData[1].score.toString()}); | |
} | |
} | |
} | |
else if (setting == "Disable Jerseys [Currently Enabled]") { | |
GM_setValue("backJerseyFlag", false); | |
newSetting = "Enable Jerseys [Currently Disabled]"; | |
} | |
else if (setting == "Enable Jerseys [Currently Disabled]") { | |
GM_setValue("backJerseyFlag", true); | |
newSetting = "Disable Jerseys [Currently Enabled]"; | |
} | |
else if (setting == "Disable Jersey Spin [Currently Enabled]") { | |
GM_setValue("backJerseySpin", false); | |
newSetting = "Enable Jersey Spin [Currently Disabled]"; | |
} | |
else if (setting == "Enable Jersey Spin [Currently Disabled]") { | |
GM_setValue("backJerseySpin", true); | |
newSetting = "Disable Jersey Spin [Currently Enabled]"; | |
} | |
else if (setting == "Enable Saving Local Stats [Currently Disabled]") { | |
GM_setValue("backLocalStorage", true); | |
newSetting = "Disable Saving Local Stats [Currently Enabled]"; | |
} | |
else if (setting == "Disable Saving Local Stats [Currently Enabled]") { | |
GM_setValue("backLocalStorage", false); | |
newSetting = "Enable Saving Local Stats [Currently Disabled]"; | |
} | |
else if (setting == "Disable Abbreviation Checks [Currently Enabled]") { | |
GM_setValue("backAbbrCheck", false); | |
newSetting = "Enable Abbreviation Checks [Currently Disabled]"; | |
} | |
else if (setting == "Enable Abbreviation Checks [Currently Disabled]") { | |
GM_setValue("backAbbrCheck", true); | |
newSetting = "Disable Abbreviation Checks [Currently Enabled]"; | |
} | |
else if (setting == "Disable Sound Checks [Currently Enabled]") { | |
GM_setValue("tpcsSoundCheck", false); | |
newSetting = "Enable Sound Checks [Currently Disabled]"; | |
} | |
else if (setting == "Enable Sound Checks [Currently Disabled]") { | |
GM_setValue("tpcsSoundCheck", true); | |
newSetting = "Disable Sound Checks [Currently Enabled]"; | |
} | |
var updateSettingsArray = document.getElementById("autoscoreLeague").getElementsByTagName("option"); | |
for (var i = updateSettingsArray.length - 1; i >= 0; i--) { // loop backwards in the league selector array to update setting text | |
if (updateSettingsArray[i].value == setting) { | |
updateSettingsArray[i].value = newSetting; | |
updateSettingsArray[i].text = newSetting; | |
break; | |
} | |
} | |
} | |
//stolen from tagpro client code | |
function pad(t, e) { | |
t = t.toString(); | |
var i = (e = e.toString()) + t, | |
o = e.length > t.length ? e.length : t.length; | |
return i.substr(i.length - o); | |
} | |
function sortByScore(playerArr) { // bubble sort id array based on the score | |
var scoreArr = []; // create an array to sort | |
for (var k in playerArr) { | |
scoreArr.push(tagpro.players[playerArr[k]].score); | |
} | |
for (var i = 0; i < scoreArr.length; i++) { // basic (reverse) bubble sort because I'm boring | |
for (var j = scoreArr.length - 1; j >= i; j--) { | |
if (scoreArr[j - 1] < scoreArr[j]) { | |
var tempElementScore = scoreArr[j - 1]; | |
var tempElementId = playerArr[j - 1]; | |
scoreArr[j - 1] = scoreArr[j]; | |
scoreArr[j] = tempElementScore; | |
playerArr[j - 1] = playerArr[j]; | |
playerArr[j] = tempElementId; | |
} | |
} | |
} | |
return playerArr; | |
} | |
function submitStats(backscoreRedCaps, backscoreBlueCaps, tableExport, teamNum, startTime, groupPort, groupServer, endCheck, localCheck) { // submit stats at the end of the game | |
var endCompCheck = GM_getValue("compCheck", 0); | |
var submitRequest = new XMLHttpRequest(); | |
var doneCheck = true; | |
var z = new Date(); | |
var endTime = (Math.floor(z.getTime() / 1000) + z.getTimezoneOffset() * 60); // gets end time in UTC | |
var backscoreLink = "https://docs.google.com/forms/d/e/1FAIpQLSe57NOVRdas-tzT4MZ8-XPSkNO3MyKCTrAOyFGXp4PtNQcdkQ/formResponse?entry.133949532=" + GM_getValue("backscoreRedAbr", "Red") + "&entry.454687569=" + GM_getValue("backscoreBlueAbr", "Blue") + "&entry.184122371=" + backscoreRedCaps + "&entry.1906941178=" + backscoreBlueCaps + "&entry.2120828603=" + groupServer + "&entry.1696460484=" + GM_getValue("groupId", "none") + "&entry.968816448=" + GM_getValue("groupMap", "none") + "&entry.2065162742=" + encodeURIComponent(tableExport.toString()) + "&entry.2098213735=" + teamNum.toString() + "&entry.1523561265=" + startTime + "&entry.1474408630=" + endTime + "&entry.1681155627=" + groupPort + "&entry.1189129646=" + GM_getValue("groupTime", "none") + "&entry.197322272=" + GM_getValue("backscorePlayer", "Some%20Ball") + ((endCheck === true) ? "%20[S]" : "") + ((endCompCheck > 0) ? "" : "%20[F]"); | |
var groupCapLimit = GM_getValue("groupCapLimit", -1); | |
if (groupCapLimit == 0) { | |
groupCapLimit = -1; | |
} | |
if (endCheck === true) { // This occurs when a spectator reaches the end of the game and the 'end' event is activated | |
submitRequest.open("POST", backscoreLink + "&entry.2031694514=X&submit=Submit"); | |
console.log("Game detected as complete [End event], stats submitted"); | |
GM_setValue("compCheck", 0); | |
GM_setValue("tpcsLastHref",0); | |
GM_setValue("tpcsStartTime",0); | |
} | |
else if ((endTime - startTime) > (GM_getValue("groupTime", 0) * 60)) { //This is the Time success condition, when stats are submitted after the game has ended | |
submitRequest.open("POST", backscoreLink + "&entry.2031694514=X&submit=Submit"); | |
console.log("Game detected as complete [Time], stats submitted"); | |
GM_setValue("compCheck", 0); | |
GM_setValue("tpcsLastHref",0); | |
GM_setValue("tpcsStartTime",0); | |
} | |
else if (backscoreRedCaps == groupCapLimit || backscoreBlueCaps == groupCapLimit) { //This is the Cap success condition, when stats are submitted when cap limit is reached | |
submitRequest.open("POST", backscoreLink + "&entry.2031694514=X&submit=Submit"); | |
console.log("Game detected as complete [Cap Limit], stats submitted"); | |
GM_setValue("compCheck", 0); | |
GM_setValue("tpcsLastHref",0); | |
GM_setValue("tpcsStartTime",0); | |
} | |
else { //Everything else means something went wrong, i.e. game ended early or the you left the game early | |
submitRequest.open("POST", backscoreLink + "&submit=Submit"); | |
doneCheck = false; | |
console.log("Game detected as incomplete, stats submitted"); | |
GM_setValue("tpcsLastHref", window.location.href); | |
} | |
GM_setValue("tpcsLastGame",[{name:GM_getValue("backscoreRedAbr", "Red"),score:backscoreRedCaps},{name:GM_getValue("backscoreBlueAbr", "Blue"),score:backscoreBlueCaps}]); | |
if (localCheck <= 1) { // send stats to server | |
submitRequest.send(); | |
} | |
if (localCheck >= 1) { // save stats locally | |
var dataJson = { | |
"complete": doneCheck, | |
"redTeamName": GM_getValue("backscoreRedAbr", "Red"), | |
"blueTeamName": GM_getValue("backscoreBlueAbr", "Red"), | |
"groupServer": groupServer, | |
"groupId": GM_getValue("groupId", "none"), | |
"groupMap": GM_getValue("groupMap", "none"), | |
"playerStats": tableExport.toString(), | |
"teamNum": teamNum.toString(), | |
"startTime": startTime, | |
"endTime": endTime, | |
"groupPort": groupPort, | |
"groupTime": GM_getValue("groupTime", "none") | |
}; | |
download(JSON.stringify(dataJson),"tpcs-"+dataJson.startTime+"-"+dataJson.redTeamName+"-"+dataJson.blueTeamName+".json", "application/json"); | |
} | |
} | |
//stolen from tagpro client code | |
function timeFromSeconds(t, e) { | |
if (0 == e) e = !1; | |
var i = pad; | |
t = parseFloat(t); | |
var o = parseInt(t / 3600), | |
n = t % 60, | |
r = i(parseInt(t / 60) % 60, "00") + ":" + i(n, "00"); | |
return (!e || o > 0) && (r = i(o, "00") + ":" + r), r; | |
} | |
function updateTeamAbr() { // This function fills in the team abbreviations on the group page | |
var abrJson = GM_getValue("autoscoreAbr"); | |
var settingsList = ["Disable Jerseys [Currently Enabled]", "Enable Jerseys [Currently Disabled]", "Disable Jersey Spin [Currently Enabled]", "Enable Jersey Spin [Currently Disabled]", "Disable Saving Local Stats [Currently Enabled]", "Enable Saving Local Stats [Currently Disabled]", "Disable Abbreviation Checks [Currently Enabled]", "Enable Abbreviation Checks [Currently Disabled]","Disable Sound Checks [Currently Enabled]", "Enable Sound Checks [Currently Disabled]", "Disable H2 Overtime [Currently Enabled]", "Enable H2 Overtime [Currently Disabled]"]; | |
if (settingsList.indexOf(document.getElementById("autoscoreLeague").value) >= 0) { | |
openSettings(document.getElementById("autoscoreLeague").value); | |
document.getElementById("autoscoreLeague").value = GM_getValue("autoscoreImport", "none"); | |
document.getElementById("autoscoreLeague").text = GM_getValue("autoscoreImport", "none"); | |
} | |
GM_setValue("autoscoreImport", document.getElementById("autoscoreLeague").value); | |
var redTeamName = document.getElementsByClassName("team-name")[2]; | |
var blueTeamName = document.getElementsByClassName("team-name")[3]; | |
var teams = []; | |
var redTeamAbr; | |
var blueTeamAbr; | |
if (!!document.getElementById("redTeamAbr")) { | |
redTeamAbr = document.getElementById("redTeamAbr"); | |
blueTeamAbr = document.getElementById("blueTeamAbr"); | |
} | |
else { | |
redTeamAbr = document.createElement("select"); | |
blueTeamAbr = document.createElement("select"); | |
redTeamAbr.id = "redTeamAbr"; | |
blueTeamAbr.id = "blueTeamAbr"; | |
redTeamAbr.title = "Click here to select the Red team's abbreviation!"; | |
blueTeamAbr.title = "Click here to select the Blue team's abbreviation!"; | |
redTeamName.appendChild(redTeamAbr); | |
blueTeamName.appendChild(blueTeamAbr); | |
} | |
if (document.getElementById("redTeamAbr").style.display == "none") { | |
document.getElementById("redTeamAbr").style.display = "block"; | |
document.getElementById("blueTeamAbr").style.display = "block"; | |
} | |
if (document.getElementById("pub-btn").offsetParent === null) { | |
document.getElementById("autoscoreLeague").style.display = "none"; | |
document.getElementById("redTeamAbr").style.display = "none"; | |
document.getElementById("blueTeamAbr").style.display = "none"; | |
} | |
else { | |
document.getElementById("autoscoreLeague").style.display = "block"; | |
document.getElementById("redTeamAbr").style.display = "block"; | |
document.getElementById("blueTeamAbr").style.display = "block"; | |
} | |
switch (document.getElementById("autoscoreLeague").value) { | |
// teams is the list which is shown on the group page | |
// teamsLabels is the list of labels to help differentiate teams (usually server or conference) | |
// teamsRaw is the list of abbreviations to put into the group | |
case "TToC": // tournaments follow the same procedure so flow one case because I'm lazy | |
case "TPA": | |
case "TBT": | |
var tourneyModifier; | |
if (document.getElementById("autoscoreLeague").value == "TToC") { | |
tourneyModifier = "T"; | |
} | |
else if (document.getElementById("autoscoreLeague").value == "TPA") { | |
tourneyModifier = "A"; | |
} | |
else if (document.getElementById("autoscoreLeague").value == "TBT") { | |
tourneyModifier = "B"; | |
} | |
teams = {"Teams":{}}; | |
for (let t = 1; t <= 16; t++) { | |
let addTeam = ""; | |
if (t < 10) { | |
addTeam = tourneyModifier + "0" + t; | |
} | |
else { | |
addTeam = tourneyModifier + t; | |
} | |
teams.Teams[addTeam] = addTeam; | |
} | |
break; | |
case "None": | |
teams = []; | |
document.getElementById("redTeamAbr").style.display = "none"; | |
document.getElementById("blueTeamAbr").style.display = "none"; | |
break; | |
default: | |
teams = abrJson[GM_getValue("autoscoreImport")]; | |
break; | |
} | |
while (redTeamAbr.firstChild) { | |
redTeamAbr.removeChild(redTeamAbr.firstChild); | |
blueTeamAbr.removeChild(blueTeamAbr.firstChild); | |
} | |
var divisionLabelList = Object.keys(teams); | |
var noneOptionR = document.createElement("option"); | |
var noneOptionB = document.createElement("option"); | |
noneOptionR.value = ""; | |
noneOptionR.text = ""; | |
noneOptionB.value = ""; | |
noneOptionB.text = ""; | |
redTeamAbr.appendChild(noneOptionR); | |
blueTeamAbr.appendChild(noneOptionB); | |
for (var k = 0; k < divisionLabelList.length; k++) { | |
var divisionLabelR = document.createElement("optgroup"); | |
var divisionLabelB = document.createElement("optgroup"); | |
divisionLabelR.label = divisionLabelList[k]; | |
divisionLabelB.label = divisionLabelList[k]; | |
var divisionTeams = Object.keys(teams[divisionLabelR.label]); | |
for (var l = 0; l < divisionTeams.length; l++) { | |
var optionr = document.createElement("option"); | |
var optionb = document.createElement("option"); | |
optionr.text = divisionTeams[l]; | |
optionr.value = teams[divisionLabelR.label][optionr.text]; | |
optionb.value = optionr.value; | |
optionb.text = optionr.text; | |
divisionLabelR.appendChild(optionr); | |
divisionLabelB.appendChild(optionb); | |
} | |
redTeamAbr.appendChild(divisionLabelR); | |
blueTeamAbr.appendChild(divisionLabelB); | |
} | |
redTeamAbr.className = "form-control js-socket-setting"; | |
blueTeamAbr.className = "form-control js-socket-setting"; | |
document.getElementById("redTeamAbr").onchange = function() { | |
if (document.getElementById("redTeamAbr").value.length <= 0) { | |
tagpro.group.socket.emit("setting", { name: "redTeamName", value: "Red" }); | |
} | |
else { | |
tagpro.group.socket.emit("setting", { name: "redTeamName", value: document.getElementById("redTeamAbr").value}); | |
} | |
}; | |
document.getElementById("blueTeamAbr").onchange = function() { | |
if (document.getElementById("blueTeamAbr").value.length <= 0) { | |
tagpro.group.socket.emit("setting", { name: "blueTeamName", value: "Blue" }); | |
} | |
else { | |
tagpro.group.socket.emit("setting", { name: "blueTeamName", value: document.getElementById("blueTeamAbr").value}); | |
} | |
}; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment