Download as txt, pdf, or txt
Download as txt, pdf, or txt
You are on page 1of 10

// ==UserScript==

// @name BR Butler UI
// @version 2.6.70
// @description Save BR picks and more.
// @author PsCid
// @match https://animemusicquiz.com/*
// @grant none
// @require https://unpkg.com/popper.js@1
// @require https://unpkg.com/tippy.js@5
// @updateURL https://gitlab.com/amq-pscid/br-butler/-/raw/master/BR%20Butler
%20UI.user.js
// ==/UserScript==

// ----------------------
// Mostrar nomes no mapa = Shift + 'E'
// Apagar nomes no mapa = Shift + 'Q'
// Modo hover = Shift + 'R'
// ----------------------

if (document.getElementById("startPage")) return;

// Main
$(document.documentElement).keydown(function (event) {
if (document.querySelector("#mhShowSelectionSlider > div.slider-handle.min-
slider-handle.round").getAttribute("aria-valuenow") == 2) {
var list;
var i = 0;
if (event.which === 69 && event.shiftKey === true) {
list = document.querySelectorAll(".brShowEntry.brMapObject");
for(i = 0; i < list.length; ++i) {
simulateMouseClick(list[i], 'on');
}
} else if (event.which === 81 && event.shiftKey === true) {
list = document.querySelectorAll(".brShowEntry.brMapObject");
for(i = 0; i < list.length; ++i) {
simulateMouseClick(list[i], 'off');
}
} else if (event.which === 82 && event.shiftKey === true) {
toggleHoverMode();
}
}
});

var brChatTemplate = `<div id="brMsgBox" class="chatBox">


<div class="chatBoxContainer">
<div class="chatTopBar">
<p>BR Picks</p>
<span id="brMsgBoxCloseBtn" class="glyphicon glyphicon-remove
clickAble" aria-hidden="true"></span>
<span id="brMsgBoxCopyBtn" class="glyphicon clickAble playerProfile"
aria-hidden="true"><i class="fa fa-clipboard" aria-hidden="true"></i></span>
<span id="brMsgBoxSendCodeBtn" class="glyphicon clickAble
playerProfile" aria-hidden="true"><i class="fa fa-share-square-o" aria-
hidden="true"></i></span>
</div>
<textarea id="brPicksCodeInputBox" spellcheck="false" placeholder="Digite
um código de time"></textarea>
<ul id="brMsgBoxChatContent" class="chatContent"></ul>
</div>
<div id="brMsgBoxFooterBtn" class="chatBoxFooter text-center clickAble
leftRightButtonBottom">
<h4 id="brMsgBoxFooterHigh1" class="chatHighlight"><span>BR
Picks</span></h4>
<h4 id="brMsgBoxFooterHigh2" class="chatHighlight chatBoxTextGlow"><span>BR
Picks</span></h4>
</div>
</div>`;

function createBrChatBox(firstStage) {
var chatElement = document.getElementById("brMsgBox");
if (chatElement == null) {
var msgBox = $(format(brChatTemplate, "BR Picks"));
$("#activeChatScrollContainer").append(msgBox);
chatElement = document.getElementById("brMsgBox");
var msgBoxContainer =
chatElement.getElementsByClassName("chatBoxContainer")[0];
var chatRollBtn = document.getElementById("brMsgBoxFooterBtn");
chatRollBtn.addEventListener('click', function () {
if (msgBoxContainer.style.transform != "translateY(0%)") {
msgBoxContainer.style.transform = "translateY(0%)";
} else {
msgBoxContainer.style.transform = "translateY(105%)";
}

document.getElementById("brMsgBoxFooterHigh1").classList.remove("chatHighlight");

document.getElementById("brMsgBoxFooterHigh2").classList.remove("chatHighlight");
}, false);

tippy.setDefaultProps({delay: [800, 200]});

var copyPicksBtn = document.getElementById("brMsgBoxCopyBtn");


copyPicksBtn.addEventListener('click', function () {
sendPicksToChat();
}, false);

tippy('#brMsgBoxCopyBtn', {
content: 'Envia seus picks automaticamente para o chat'
});

var sendPicksBtn = document.getElementById("brMsgBoxSendCodeBtn");


sendPicksBtn.addEventListener('click', function () {
if (isTeamMode()) {
sendPicksCode();
} else {
gameChat.systemMessage("Você não está em um BR de times!");
}
}, false);

tippy('#brMsgBoxSendCodeBtn', {
content: 'Envia seu código de picks (BR de times)'
});

var closeBtn = document.getElementById("brMsgBoxCloseBtn");


closeBtn.addEventListener('click', function () {
if (chatElement != null) {
removeBrChat();
}
}, false);

var codeInputBox = document.getElementById("brPicksCodeInputBox");


codeInputBox.addEventListener('keypress', function (e) {
if (e.keyCode == 13) {
getPicksFromCloud(codeInputBox.value);
codeInputBox.value = "";
e.preventDefault();
}
}, false);

if (firstStage) {
saveAndPrintBrPicks();
sendPicksToCloud();
}
}
}

function isTeamMode() {
return quiz.teamMode;
}

function isOdd(num) { return num % 2;}

function addPickToBrChatBox(rowIndex, appeared, correct) {


var li;
var ul = document.getElementById("brMsgBoxChatContent");
if (ul == null) { return false;}
if (document.getElementById("brBoxPick" + rowIndex) == null) {
li = document.createElement("li");
li.setAttribute("id", "brBoxPick" + rowIndex);
li.classList.add("chatPicksLi");
colorPick(rowIndex, li, appeared, correct);
li.appendChild(document.createTextNode("• " + localStorage.getItem('pick '
+
rowIndex).replace(pickAlreadyPlayedCorrect,"").replace(pickAlreadyPlayedIncorrect,"
")));
ul.appendChild(li);

var answerPick = li;


answerPick.addEventListener('click', function () {
writePickToField(rowIndex, "qpAnswerInput");
}, false);
} else {
li = document.getElementById("brBoxPick" + rowIndex);
colorPick(rowIndex, li, appeared, correct);
}
}

function colorPick(rowIndex, li, appeared, correct) {


if (appeared) {
if (correct) {
li.style.background = "darkgreen";
} else {
li.style.background = "darkred";
}
} else {
if (isOdd(rowIndex)) {
li.style.background = "dimgray";
}
}
}

function removeBrChat() {
if (document.getElementById("brMsgBox") != null) {
document.getElementById("brMsgBox").remove();
}
}

// Mouse simulation
function simulateMouseClick(targetNode, type) {
function triggerMouseEvent(targetNode, eventType) {
var clickEvent = document.createEvent('MouseEvents');
clickEvent.initEvent(eventType, true, true);
targetNode.dispatchEvent(clickEvent);
}
if (type == 'on') {
["mouseover"].forEach(function(eventType) {
triggerMouseEvent(targetNode, eventType);
});
} else {
["mouseout"].forEach(function(eventType) {
triggerMouseEvent(targetNode, eventType);
});
}
}

// BR Picks
var pickList;
var pickAlreadyPlayedCorrect = "";
var pickAlreadyPlayedIncorrect = "❌";
function saveAndPrintBrPicks() {
var currentIndex = 1;
pickList = document.querySelectorAll("#brCollectedList li");
if (pickList.length >= 1) {
deleteLocalStorage();
for (var i = 0; i < pickList.length; ++i) {
localStorage.setItem('pick ' + currentIndex,
pickList[i].textContent.substring(2, pickList[i].textContent.length));
addPickToBrChatBox(currentIndex, false, true);
localStorage.setItem('length', currentIndex.toString());
currentIndex += 1;
}
}
}

function writePickToField(animeIndex, element) {


if (localStorage.getItem('pick ' + animeIndex) !== null) {
var input = document.getElementById(element);
var pickName = localStorage.getItem('pick ' +
animeIndex).replace(pickAlreadyPlayedCorrect,"").replace(pickAlreadyPlayedIncorrect
,"");
input.value = pickName;
var ev = document.createEvent('Event');
ev.initEvent('keypress');
ev.which = ev.keyCode = 13;
input.dispatchEvent(ev);
}
}

async function wait() {


await new Promise(resolve => setTimeout(resolve, 10));
}

function checkPicks(newSong) {
if (localStorage.getItem('length') != null) {
for (var i = 1; i <= parseInt(localStorage.getItem('length')); ++i) {
var currentPick = localStorage.getItem('pick ' + i);
if
((currentPick.replace(pickAlreadyPlayedCorrect,"").replace(pickAlreadyPlayedIncorre
ct,"") == newSong.anime.english
||
currentPick.replace(pickAlreadyPlayedCorrect,"").replace(pickAlreadyPlayedIncorrect
,"") == newSong.anime.romaji)
|| (currentPick.endsWith(pickAlreadyPlayedCorrect) ||
currentPick.endsWith(pickAlreadyPlayedIncorrect))) {
if (currentPick.endsWith(pickAlreadyPlayedCorrect)) {
localStorage.setItem('pick ' + i,
currentPick.replace(pickAlreadyPlayedCorrect,"") + pickAlreadyPlayedCorrect);
addPickToBrChatBox(i, true, true);
} else if (currentPick.endsWith(pickAlreadyPlayedIncorrect)) {
localStorage.setItem('pick ' + i,
currentPick.replace(pickAlreadyPlayedIncorrect,"") + pickAlreadyPlayedIncorrect);
addPickToBrChatBox(i, true, false);
} else {
if (newSong.correct) {
localStorage.setItem('pick ' + i,
currentPick.replace(pickAlreadyPlayedCorrect,"") + pickAlreadyPlayedCorrect);
} else {
localStorage.setItem('pick ' + i,
currentPick.replace(pickAlreadyPlayedIncorrect,"") + pickAlreadyPlayedIncorrect);
}
addPickToBrChatBox(i, true, newSong.correct);
}
} else {
addPickToBrChatBox(i, false, newSong.correct);
}
}
}
}

function sendPicksToChat() {
for (var i = 1; i <= parseInt(localStorage.getItem('length')); ++i) {
writePickToField(i, "gcInput");
}
}

function sendPicksCode() {
if (!document.getElementById("gcTeamChatSwitch").classList.contains("active"))
{
document.getElementById('gcTeamChatSwitch')
.dispatchEvent(new MouseEvent('click', {shiftKey: false}));
}
var input = document.getElementById("gcInput");
var picksCode;
if (localStorage.getItem('sendPicksCode') !== null) {
picksCode = "Código: " + localStorage.getItem('sendPicksCode');
} else {
picksCode = "Criando código para os picks, tente novamente em alguns
segundos...";
}
input.value = picksCode;
var ev = document.createEvent('Event');
ev.initEvent('keypress');
ev.which = ev.keyCode = 13;
input.dispatchEvent(ev);
}

function deleteLocalStorage() {
for (var i = 1; i <= parseInt(localStorage.getItem('length')); ++i) {
localStorage.removeItem('pick ' + i);
}
localStorage.removeItem('length');
localStorage.removeItem('sendPicksCode');
}

// Hover mode
const mutationObserver = new MutationObserver(callback);
function callback(mutationsList) {
mutationsList.forEach(mutation => {
if (mutation.attributeName === 'class') {
if (mutation.target.classList.contains("active") &&
mutation.target.classList.contains("brShowEntry")) {
mutation.target.click();
}
}
})
}

function turnOnHoverMode() {
mutationObserver.observe(
document.getElementById('brMapContent'),
{ attributes: true, subtree: true }
);
}

function toggleHoverMode() {
if (!$("#brMapContent").is(":hidden")) {
if (localStorage.getItem("brHoverMode") != "on") {
turnOnHoverMode();
localStorage.setItem("brHoverMode", "on");
gameChat.systemMessage("Modo hover ligado!");
} else {
mutationObserver.disconnect();
localStorage.setItem("brHoverMode", "off");
gameChat.systemMessage("Modo hover desligado!");
}
}
}

function checkHoverModeIsOn() {
return localStorage.getItem("brHoverMode") == "on";
}
// Setup
let loadInterval = setInterval(() => {
if (document.getElementById("loadingScreen").classList.contains("hidden")) {
setup();
clearInterval(loadInterval);
}
}, 500);

function isBattleRoyale() {
return document.querySelector("#mhShowSelectionSlider > div.slider-handle.min-
slider-handle.round").getAttribute("aria-valuenow") == 2 && !quiz.isSpectator;
}

function setup() {
let resultsListener = new Listener("answer results", (result) => {
if (isBattleRoyale()) {
let newSong = {
anime: result.songInfo.animeNames
};
let findPlayer = Object.values(quiz.players).find((tmpPlayer) => {
return tmpPlayer._name === selfName &&
tmpPlayer.avatarSlot._disabled === false
});
if (findPlayer !== undefined) {
let playerIdx = Object.values(result.players).findIndex(tmpPlayer
=> {
return findPlayer.gamePlayerId === tmpPlayer.gamePlayerId
});
newSong.correct = result.players[playerIdx].correct;
}
createBrChatBox(false);
checkPicks(newSong);
}
});

let brMapListener = new Listener("battle royal spawn", (data) => {


if (checkHoverModeIsOn()) {
turnOnHoverMode();
}
});

let quizReadyListener = new Listener("quiz ready", (data) => {


if (isBattleRoyale()) {
createBrChatBox(true);
mutationObserver.disconnect();
}
});

let quizOverListener = new Listener("quiz over", (roomSettings) => {


if (isBattleRoyale()) {
deleteLocalStorage();
removeBrChat();
}
});

let quizReturnToLobbyListener = new Listener("return lobby vote result",


(payload) => {
if (payload.passed) {
if (isBattleRoyale()) {
deleteLocalStorage();
removeBrChat();
}
}
});

let quizLeaveListener = new Listener("New Rooms", (rooms) => {


if (isBattleRoyale()) {
deleteLocalStorage();
removeBrChat();
}
});

resultsListener.bindListener();
brMapListener.bindListener();
quizReadyListener.bindListener();
quizOverListener.bindListener();
quizLeaveListener.bindListener();
quizReturnToLobbyListener.bindListener();

addCss(`
#brMsgBoxChatContent {
overflow-x: hidden;
scrollbar-width: none;
height: 158px;
}
#brMsgBoxChatContent::-webkit-scrollbar {
width: 0px;
}
#brMsgBoxChatContent li:hover {
background-color: ` + $('#xpBarInner').css('backgroundColor') + ` !
important;
color: ` + $('.levelText').css('Color') + ` !important;
}
#brPicksCodeInputBox {
height: 10px;
min-height: 13%;
font-size: smaller;
outline: none;
}
.chatPicksLi {
border-bottom: 1px solid black;
padding-left: 3px;
cursor: pointer;
}
`);
}

function addCss(css) {
let head = document.head;
let style = document.createElement("style");
head.appendChild(style);
style.type = "text/css";
style.appendChild(document.createTextNode(css));
}

// Get teammates pick part


const picksUrl = "https://br-butler.herokuapp.com/documents";
function sendPicksToCloud() {
if (isTeamMode()) {
var picks = formatPicksToSend();
var xhr = new XMLHttpRequest();
xhr.open("POST", picksUrl);
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
var responseData = xhr.responseText;
var jsonResponse = JSON.parse(responseData);
localStorage.setItem('sendPicksCode', jsonResponse.key);
} else {
console.error("Ocorreu um erro durante o envio dos picks.
Status: " + xhr.status);
}
}
};

var data = picks;


xhr.send(data);
}
}

function getPicksFromCloud(code) {
if (isTeamMode() && !isSelfPicksCode(code)) {
var xhr = new XMLHttpRequest();
xhr.open("GET", picksUrl + "/" + code);

xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
var responseData = xhr.responseText;
var jsonResponse = JSON.parse(responseData);
addTeammatesPicks(jsonResponse.data.split(" || "));
} else {
gameChat.systemMessage("Código inválido.");
}
}
};

xhr.send();
} else if (isSelfPicksCode(code)) {
gameChat.systemMessage("Você não precisa adicionar os próprios picks!");
} else {
gameChat.systemMessage("Você não está em um BR de times!");
}
}

function isSelfPicksCode(code) {
var localCode = localStorage.getItem('sendPicksCode');
return code == localCode && localCode != null;
}

function addTeammatesPicks(pickList) {
if (pickList.length >= 1) {
var currentPicksLength = parseInt(localStorage.getItem('length'));
var currentIndex = currentPicksLength + 1;
for (var i = 0; i < pickList.length; ++i) {
localStorage.setItem('pick ' + currentIndex, pickList[i]);
addPickToBrChatBox(currentIndex, false, true);
currentIndex++;
}
localStorage.setItem('length', currentPicksLength + pickList.length);
}
}

function formatPicksToSend() {
var picks = "";
for (var i = 1; i <= parseInt(localStorage.getItem('length')); ++i) {
picks = picks + localStorage.getItem('pick ' +
i).replace(pickAlreadyPlayedCorrect,"").replace(pickAlreadyPlayedIncorrect,"") + "
|| ";
}
return picks.substring(0, picks.length - 4);
}

You might also like