Geoguessr Team Duels Advanced Options

Adds extra options to team duel settings.

目前為 2023-03-08 提交的版本,檢視 最新版本

// ==UserScript==
// @name         Geoguessr Team Duels Advanced Options
// @description  Adds extra options to team duel settings.
// @version      0.1.4
// @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==

let cachedGameMode = '';
let cachedGameOptions = {};

const getGameId = () => {
    const scripts = document.getElementsByTagName('script');
    for (const script of scripts) {
        if (script.src.includes('_buildManifest.js')) {
            return script.src.split('/')[5];
        }
    }
}

const gameMode = () => {
    const fullText = document.querySelector('.bars_root___G89E').textContent;
    return fullText.substring(0, fullText.lastIndexOf(' ')).toLowerCase();
}

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": "same-origin"
    })
}

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://www.geoguessr.com/_next/data/${getGameId()}/en/party.json`, "GET")
    .then((response) => response.json())
    .then((data) => {
        let gameOptions = data.pageProps.party.gameSettings;
        gameOptions[settingName] = newValue;
        // Push the updated options
        fetchWithCors(`https://www.geoguessr.com/api/v4/parties/v2/game-settings`, "PUT", gameOptions);
    });

    cachedGameMode = gameMode();
    cachedGameOptions[settingName] = e.value;
}

let optionTextInputInnerHTML = (id, settingName, text, icon) =>
    `<div class="game-options_option__Dt26y"><div class="game-options_labelAndIcon__2fzCM"><div class="game-options_optionIcon__ZaJ8L"><img class="rule-icons_icon__dcLov" src="${icon}" alt="" width="48" height="48"></div><div class="game-options_optionLabel__APwH6">${text}</div></div><div><input type="text" id="${id}" onblur="modifySetting(this, '${settingName}')" style="text-align: center; background: rgba(255,255,255,0.1); color: white; border: none; border-radius: 5px; width: 60px;"></div></div>`;

function makeCustomTextInput(elt, id, settingName, text, icon) {
    elt.outerHTML = optionTextInputInnerHTML(id, settingName, text, icon);
    return elt;
}

function updateValue(inputId, option, gameOptions) {
    if (document.querySelector(inputId)) {
        if (gameMode() == cachedGameMode && option in cachedGameOptions) {
            document.querySelector(inputId).value = cachedGameOptions[option];
        } else {
            if (option == 'multiplierIncrement') {
                document.querySelector(inputId).value = gameOptions[option] / 10;
            } else {
                document.querySelector(inputId).value = gameOptions[option];
            }
        }
    }
}

let observer = new MutationObserver((mutations) => {
    if (window.location.href.includes('party') && (document.querySelector('.game-options_slider__AnQku') || document.querySelector('.game-options_roundButton__L0Tz5'))) {
        if (!gameMode().includes('battle royale')) {
             if (document.querySelector('.game-options_lives__S1iOt')) {
                 let healthBox = document.querySelector('.game-options_lives__S1iOt').parentElement;
                 makeCustomTextInput(healthBox, 'health-input', 'initialHealth', 'Health', '/_next/static/images/heart-eb251481d4679b6ee73413eff64d7eed.png');
             }
            if (document.querySelector('.game-options_lives__S1iOt')) {
                let multiplierIncrementBox = document.querySelector('.game-options_lives__S1iOt').parentElement;
                makeCustomTextInput(multiplierIncrementBox, 'increment-input', 'multiplierIncrement', 'Multiplier Increment', '/_next/static/images/multipliers-icon-94c4120e112cfbe8b287083d4e626842.svg');
            }
        }

        if (document.querySelector('.game-options_roundTime__vWMWr')) {
            let roundTimeBox = document.querySelector('.game-options_roundTime__vWMWr').parentElement;
            if (gameMode() == 'city streaks') {
                makeCustomTextInput(roundTimeBox, 'time-input', 'duration', 'Time', '/_next/static/images/time-limit-2f49a01869aca3e939cbaea0fccd590a.png');
            } else {
                makeCustomTextInput(roundTimeBox, 'time-input', 'roundTime', 'Time', '/_next/static/images/time-limit-2f49a01869aca3e939cbaea0fccd590a.png');
            }
        }

        fetchWithCors(`https://www.geoguessr.com/_next/data/${getGameId()}/en/party.json`, "GET")
        .then((response) => response.json())
        .then((data) => {
            let gameOptions = data.pageProps.party.gameSettings;

            updateValue('#health-input', 'initialHealth', gameOptions);
            updateValue('#increment-input', 'multiplierIncrement', gameOptions);

            if (gameMode() != 'bullseye') {
                if (gameMode() == 'city streaks') {
                    updateValue('#time-input', 'duration', gameOptions);
                } else {
                    updateValue('#time-input', 'roundTime', gameOptions);
                }
            }
        });
    }
});


observer.observe(document.body, {
  characterDataOldValue: false,
  subtree: true,
  childList: true,
  characterData: false
});

document.addEventListener('keydown', (event) => {
    if (event.key == 'Escape' && document.querySelector('.party-modal_heading__UqkX6')) {
        document.activeElement.blur();
    }
});