// ==UserScript==
// @name Geoguessr Team Duels Advanced Options
// @description Adds extra options to team duel settings.
// @version 0.1.3
// @author macca#8949
// @license MIT
// @match https://www.geoguessr.com/*
// @run-at document-start
// @grant none
// @namespace https://greasyfork.org/en/scripts/452579-geoguessr-team-duels-advanced-options
// ==/UserScript==
const getGameId = () => {
return window.location.href.split('/')[4];
}
async function fetchWithCors(url, method, body) {
return await fetch(url, {
"headers": {
"accept": "*/*",
"accept-language": "en-US,en;q=0.8",
"content-type": "application/json",
"sec-fetch-dest": "empty",
"sec-fetch-mode": "cors",
"sec-fetch-site": "same-site",
"sec-gpc": "1",
"x-client": "web"
},
"referrer": "https://www.geoguessr.com/",
"referrerPolicy": "strict-origin-when-cross-origin",
"body": JSON.stringify(body),
"method": method,
"mode": "cors",
"credentials": "include"
})
}
window.modifySetting = (e, settingName) => {
let newValue = e.value;
if (settingName === 'multiplierIncrement') {
newValue *= 10;
newValue = Math.round(newValue);
} else {
newValue *= 1; // string to number conversion
newValue = Math.round(newValue);
}
// Fetch the game options
fetchWithCors(`https://game-server.geoguessr.com/api/lobby/${getGameId()}/join`, "POST", {})
.then((response) => response.json())
.then((data) => {
let gameOptions = data.gameOptions;
gameOptions[settingName] = newValue;
// Push the updated options
fetchWithCors(`https://game-server.geoguessr.com/api/lobby/${getGameId()}/options`, "PUT", gameOptions);
});
}
let optionTextInputInnerHTML = (id, settingName, text) =>
`<input type="text" id="${id}" onchange="modifySetting(this, '${settingName}')" style="text-align: center; background: rgba(255,255,255,0.1); color: white; border: none; border-radius: 5px; width: 60px;"><div class="game-options_optionLabel__dJ_Cy">${text}</div>`
function makeCustomTextInput(elt, id, settingName, text) {
if (elt == null) elt = document.createElement('label');
elt.className = "game-options_option__eCz9o game-options_editableOption__Mpvar";
elt.innerHTML = optionTextInputInnerHTML(id, settingName, text);
elt.style = "display: flex; flex-direction: column; align-items: center; justify-content: center;";
return elt
}
function insertAfter(elt, child) {
child.parentNode.insertBefore(elt, child.nextSibling);
}
let observer = new MutationObserver((mutations) => {
if ((window.location.href.includes('duels') || window.location.href.includes('live-challenge')) && document.querySelector('.game-options_slider__JwEe2')) {
if (window.location.href.includes('duels')) {
let healthElement = document.querySelectorAll('.game-options_lives__wNSwd')[0].parentElement;
let multiplierIncrementBox = document.querySelectorAll('.game-options_lives__wNSwd')[1].parentElement
makeCustomTextInput(healthElement, "health-input", "initialHealth", "Health");
makeCustomTextInput(multiplierIncrementBox, "increment-input", "multiplierIncrement", "Multiplier Increment");
}
let timeElementBox = makeCustomTextInput(null, "time-input", "roundTime", "Time");
let timeSliderBox = document.querySelectorAll('.game-options_slider__JwEe2')[0].parentNode.parentNode;
insertAfter(timeElementBox, timeSliderBox);
timeSliderBox.remove()
fetchWithCors(`https://game-server.geoguessr.com/api/lobby/${getGameId()}/join`, "POST", {})
.then((response) => response.json())
.then((data) => {
let gameOptions = data.gameOptions;
if (window.location.href.includes('duels')) document.querySelector('#health-input').value = gameOptions.initialHealth;
if (window.location.href.includes('duels')) document.querySelector('#increment-input').value = gameOptions.multiplierIncrement / 10;
document.querySelector('#time-input').value = gameOptions.roundTime;
});
}
});
observer.observe(document.body, {
characterDataOldValue: false,
subtree: true,
childList: true,
characterData: false
});