Geoguessr change Avatar to Pin (beta)

Adds the competitive rating to usernames

目前为 2023-05-09 提交的版本,查看 最新版本

// ==UserScript==
// @name         Geoguessr change Avatar to Pin (beta)
// @description  Adds the competitive rating to usernames
// @version      1.0.1
// @license      MIT
// @author       joniber#5011
// @namespace
// @match        https://www.geoguessr.com/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=geoguessr.com
// @namespace https://greasyfork.org/users/1072330
// ==/UserScript==

//=====================================================================================\\
//    change these values however you like (make sure to hit ctrl+s afterwards)        \\
//                PIN = PROFILE PICTURE                                                \\
//=====================================================================================\\

const PIN_IN_OWN_PROFILE = true;

const PIN_IN_OTHERS_PROFILE = true;

const PIN_IN_DUELS_MATCHMAKING = true;

const PIN_IN_BR_MATCHMAKING = true;

const NO_AVATARS_END_OF_DUEL = true;

const PIN_IN_TEAM_DUEL_PRIVATE_LOBBY = true;

//Beta: still working on it, any questons or feedback -> Discord joniber#5011

//=====================================================================================\\
//  don't edit anything after this point unless you know what you're doing             \\
//=====================================================================================\\

const GEOGUESSR_USER_ENDPOINT = 'https://geoguessr.com/api/v3/users';

const SCRIPT_PREFIX = 'up__';
const USER_PIN_CLASS = SCRIPT_PREFIX + 'userPin';
const USER_PIN_ID = SCRIPT_PREFIX + 'profilePin';

let player1 = null;
let player2 = null;
let av = null;
let index = 0;

const OBSERVER_CONFIG = {
    characterDataOldValue: false,
    subtree: true,
    childList: true,
    characterData: false,
};

const ERROR_MESSAGE = (wrong) => '${wrong}';

function pathMatches(path) {
    return location.pathname.match(new RegExp(`^/(?:[^/]+/)?${path}$`));
}

function wrapperDuels() {
    return `<div class="profile-header_avatarWrapper__5_jDA up__"></div>`;
}

function wrapperEndOfDuels() {
    return `<div class="profile-header_avatar__y6vsp up__"></div>`;
}

function wrapper() {
    return `<div class="profile-header_avatar__y6vsp"><div class="avatar_titleAvatar__0pdL9"><div class="styles_rectangle___6gqv up__" style="padding-top: 100%;"><div class="avatar_titleAvatarImage__A51Dx up__"></div></div></div></div>`;
}

function profilePicture() {
    return `<img class="styles_image__8M_kp ${USER_PIN_CLASS}" loading="auto" style="object-fit:cover;">`;
}
function profilePicture1() {
    return `<img class="styles_image__8M_kp" id="${USER_PIN_ID}" loading="auto" style="object-fit:cover;">`;
}

function levelBorder() {
    return `<picture class="avatar_titleAvatarFrame__AT57_ ${USER_PIN_CLASS}"><source type="image/avif"><source type="image/webp"><img class="avatar_titleAvatarFrame__AT57_"></picture>`;
}

function levelBorder1() {
    return `<picture class="avatar_titleAvatarFrame__AT57_" id="${USER_PIN_ID}"><source type="image/avif"><source type="image/webp"><img class="avatar_titleAvatarFrame__AT57_"></picture>`;
}

async function fillPin(pin, userId) {
    const userData = await getUserData(userId);
    const pinURL = userData.pin.url;
    pin.setAttribute('src', '/images/auto/144/144/ce/0/plain/' + pinURL);
}

async function fillLvl(lvl, userId) {
    const userData = await getUserData(userId);
    const level = roundToNearest10(userData.progress.level);
    lvl.firstChild.setAttribute(
        'srcset',
        '/static/avatars/tiers/low-quality/tier-' + level + '.avif'
    );
    lvl.children[1].setAttribute(
        'srcset',
        '/static/avatars/tiers/low-quality/tier-' + level + '.webp'
    );
    lvl.lastChild.setAttribute('src', '/static/avatars/tiers/low-quality/tier-' + level + '.png');
}

function logCode(event) {
    if (event.key === 'o' || event.key === 'O') {
        var htmlCode = document.getElementById('preroll');
        var htmlCode1 = document.getElementById('overlay-portal-destination');
        console.log(htmlCode);
        console.log(htmlCode1);
    }
}

// Eventlistener hinzufügen, um auf Tastendruck zu reagieren
document.addEventListener('keydown', logCode);

function changeAvatarToPin(link, avatarToRemove) {
    if (!link.querySelector(`.${USER_PIN_CLASS}`)) {
         if (link != null || link != '') {
             let destination = null
             if (avatarToRemove == link){
               link.querySelector('.styles_image__8M_kp').style="display: none"
                  destination = link
             }
             else{
                 link.querySelector('.player-card_lobbyCardInner__G_xzy').firstChild.remove()
                  destination = link.querySelector('.player-card_lobbyCardInner__G_xzy')

             }
         
         destination.insertAdjacentHTML('afterbegin', wrapperDuels());
         destination = link.querySelector('.profile-header_avatarWrapper__5_jDA.up__');
         destination.insertAdjacentHTML('afterbegin', wrapper());
         destination = link.querySelector('.avatar_titleAvatarImage__A51Dx.up__')
         destination.insertAdjacentHTML('beforeend', profilePicture());
         const pin = destination.lastChild
         let id = '/me/profile'
         if(link.querySelector('.player-card_userLink__HhoDo') != null){
          id = link.querySelector('.player-card_userLink__HhoDo').href
         }
         fillPin(pin, retrieveIdFromLink(id));
         destination = link.querySelector('.styles_rectangle___6gqv.up__');
         destination.insertAdjacentHTML('beforeend',levelBorder());
         const lvl = destination.lastChild
         fillLvl(lvl, retrieveIdFromLink(id));

         }
    }
}

// function changeAvatarInGame(link) {
//     if(!document.querySelector(`.${USER_PIN_CLASS}`)){

//             let destination = link
//             destination.insertAdjacentHTML("beforeEnd", wrapperDuels());

//             destination = document.querySelector('.avatar_titleAvatarImage__A51Dx.up__')
//             destination.insertAdjacentHTML("beforeEnd", profilePicture())
//             const pin = destination.lastChild
//             fillPin(pin, retrieveIdFromLink(location.href))

//             destination = document.querySelector(".styles_rectangle___6gqv.up__")
//             destination.insertAdjacentHTML("beforeEnd", levelBorder())
//             const lvl = destination.lastChild
//             fillLvl(lvl, retrieveIdFromLink(location.href))

//         }
// }

let inBattleRoyale = false;
let inDuels = false;
let lastOpenedMapHighscoreTab = 0;

function onMutationsBr(mutations, observer) {
    //     for(let q in document.getElementsByTagName('canvas')){
    //         q.remove();
    //     }
    //     if (PIN_IN_BR_MATCHMAKING) {
    //         // battle royale distance
    //         for (const link of document.querySelectorAll('.distance-player-list_name__fPSwC a')) {
    //             changeAvatarInGame(link);
    //         }
    //         // battle royale countries
    //         for (const link of document.querySelectorAll(
    //             '.countries-player-list_playerName__g4tnM a'
    //         )) {
    //             changeAvatarInGame(link);
    //         }
    //     }
}

function onMutationsDuels(mutations, observer) {
    // for(let i = 0; i<2; i++){
    //     let q = document.getElementsByTagName('canvas')[i];
    //     if(q!=null){
    //     q.remove();
    //     }
    // }

    if (NO_AVATARS_END_OF_DUEL) {
        let avatar_end_of_duel_wrapper = document.querySelector(
            '.game-finished_avatarContainer__S63IS'
        );
        if (avatar_end_of_duel_wrapper != null) {
            avatar_end_of_duel_wrapper.firstChild.remove();
            let destination = avatar_end_of_duel_wrapper
            destination.style = "height: fit-content";
         destination.insertAdjacentHTML('afterbegin', wrapperDuels())
         destination = document.querySelector('.profile-header_avatarWrapper__5_jDA.up__')
         destination.insertAdjacentHTML('afterbegin', wrapper());
         document.querySelector('.profile-header_avatar__y6vsp').style = "display:flex; justify-content:center; align-items:center"
         document.querySelector('.avatar_titleAvatar__0pdL9').style="width:20rem"
         destination = document.querySelector('.avatar_titleAvatarImage__A51Dx.up__')
         destination.insertAdjacentHTML('beforeend', profilePicture());
         const pin = destination.lastChild
         let id = '/me/profile'
         if(document.querySelectorAll('.anchor_variantUnderline__8wlJr')[0] != null){
          id = document.querySelectorAll('.anchor_variantUnderline__8wlJr')[0].href
         }
         fillPin(pin, retrieveIdFromLink(id));
         destination = document.querySelector('.styles_rectangle___6gqv.up__');
         destination.insertAdjacentHTML('beforeend',levelBorder());
         const lvl = destination.lastChild
         fillLvl(lvl, retrieveIdFromLink(id));


        }
    }
    if (PIN_IN_DUELS_MATCHMAKING) {
        if (player1 == null) {
            player1 = document.querySelectorAll('.lobby_avatarContainer__kN2RK')[0];
            if (player1 != null) {
                player1.children[0].firstChild.remove();
                player1.children[0].remove();
                let destination1 = player1;
                destination1.insertAdjacentHTML('afterBegin', wrapperDuels());
                destination1 = document.querySelector('.profile-header_avatarWrapper__5_jDA.up__');
                destination1.insertAdjacentHTML('afterBegin', wrapper());
                destination1 = document.querySelector('.avatar_titleAvatarImage__A51Dx.up__');
                destination1.insertAdjacentHTML('beforeEnd', profilePicture());
                const pin = destination1.lastChild;
                let id = player1.lastChild.firstChild.href;

                fillPin(pin, retrieveIdFromLink(id));
                destination1 = document.querySelector('.styles_rectangle___6gqv.up__');
                destination1.insertAdjacentHTML('beforeEnd', levelBorder());
                const lvl = destination1.lastChild;
                fillLvl(lvl, retrieveIdFromLink(id));
            }
        }
        if (player2 == null) {
            player2 = document.querySelectorAll('.lobby_avatarContainer__kN2RK')[1];
            if (player2 != null) {
                player2.children[0].firstChild.remove();
                player2.children[0].remove();
                let destination2 = player2;
                destination2.insertAdjacentHTML('afterBegin', wrapperDuels());
                destination2 = document.querySelectorAll(
                    '.profile-header_avatarWrapper__5_jDA.up__'
                )[1];
                destination2.insertAdjacentHTML('afterBegin', wrapper());
                destination2 = document.querySelectorAll('.avatar_titleAvatarImage__A51Dx.up__')[1];
                destination2.insertAdjacentHTML('beforeEnd', profilePicture());
                const pin1 = destination2.lastChild;
                let id1 = player2.lastChild.firstChild.href;

                fillPin(pin1, retrieveIdFromLink(id1));
                destination2 = document.querySelectorAll('.styles_rectangle___6gqv.up__')[1];
                destination2.insertAdjacentHTML('beforeEnd', levelBorder());
                const lvl1 = destination2.lastChild;
                fillLvl(lvl1, retrieveIdFromLink(id1));
            }
        }

        if (player1 != null && player2 != null) {
            player1 = null;
            player2 = null;
        }
    }
}
function onMutationsStandard(mutations, observer) {
    if (isBattleRoyale() && document.querySelector('.game_hud__h3YxY ul') && !inBattleRoyale) {
        inBattleRoyale = true;
        console.log('br mode')
        const brObserver = new MutationObserver(onMutationsBr);
        brObserver.observe(document.querySelector('.game_hud__h3YxY ul'), OBSERVER_CONFIG);
    } else if (isDuels() && document.querySelector('.game_hud__fhdo5') && !inDuels) {
        inDuels = true;
        console.log('duels mode');

        const duelsObserver = new MutationObserver(onMutationsDuels);
        duelsObserver.observe(document.querySelector('.game_hud__fhdo5'), OBSERVER_CONFIG);
    } else if (inBattleRoyale && !document.querySelector('.game_hud__h3YxY ul')) {
        inBattleRoyale = false;
        console.log('normal mode');
    } else if (inDuels && !document.querySelector('.game_hud__fhdo5')) {
        inDuels = false;
        console.log('normal mode');
    }
    if (inBattleRoyale || inDuels) {
        return;
        console.log('normal mode');
    }
    if (isProfile()) {
        if (!PIN_IN_OWN_PROFILE && isOwnProfile()) {
            return;
            console.log('normal mode');
        }

        if (!PIN_IN_OTHERS_PROFILE && isOtherProfile()) {
            return;
        }

        if (!document.querySelector(`#${USER_PIN_ID}`)) {
            document.querySelector('.profile-header_fullBodyAvatar___LRnw').remove();
            let destination = document.querySelector('.profile-header_avatarWrapper__5_jDA');
            destination.insertAdjacentHTML('beforeend', wrapper());

            destination = document.querySelector('.avatar_titleAvatarImage__A51Dx.up__');
            destination.insertAdjacentHTML('beforeend', profilePicture1());
            const pin = destination.lastChild;
            fillPin(pin, retrieveIdFromLink(location.href));
            destination = document.querySelector('.styles_rectangle___6gqv.up__');
            destination.insertAdjacentHTML('beforeend', levelBorder1());
            const lvl = destination.lastChild;
            fillLvl(lvl, retrieveIdFromLink(location.href));
        }
    }

    if(PIN_IN_TEAM_DUEL_PRIVATE_LOBBY){
      for (const link of document.querySelectorAll('.team-player-card_lobbyCardInner__fT8A_')){

          changeAvatarToPin(link, link);
      }

    }

    if (PIN_IN_BR_MATCHMAKING) {
        // battle royale matchmaking

        //.player-card_lobbyCard___OpUa

        //.player-card_lobbyCardInner__G_xzy
        for (const link of document.querySelectorAll('.player-card_root__NvK_s')) {

                changeAvatarToPin(link, 'player-card_lobbyCardInner__G_xzy');

        }
    }

        if (isDuels() && PIN_IN_DUELS_MATCHMAKING) {
            if (!document.querySelector(`#${USER_PIN_ID}`)) {
                if (av == null) {

                    av = document.querySelector('.lobby_avatarContainer__kN2RK');
                }
                if (av != null) {
                    av.children[0].remove();
                    let destination_dw = av;
                    destination_dw.insertAdjacentHTML('afterBegin', wrapperDuels());
                    destination_dw = document.querySelector(
                        '.profile-header_avatarWrapper__5_jDA.up__'
                    );
                    destination_dw.insertAdjacentHTML('afterBegin', wrapper());
                    destination_dw = document.querySelector('.avatar_titleAvatarImage__A51Dx.up__');
                    destination_dw.insertAdjacentHTML('beforeEnd', profilePicture1());
                    const pin = destination_dw.lastChild;
                    let id = 'https://www.geoguessr.com/me/profile';

                    fillPin(pin, retrieveIdFromLink(id));
                    destination_dw = document.querySelector('.styles_rectangle___6gqv.up__');
                    destination_dw.insertAdjacentHTML('beforeEnd', levelBorder1());
                    const lvl = destination_dw.lastChild;
                    fillLvl(lvl, retrieveIdFromLink(id));
                }

                if (av != null) {
                    av = null;
                }
            }
        }
    }


//helpfunctions

function roundToNearest10(number) {
    return Math.ceil(number / 10) * 10;
}

function retrieveIdFromLink(link) {
    if (link.endsWith('/me/profile')) {
        const data = document.querySelector('#__NEXT_DATA__').text;
        const json = JSON.parse(data);
        return json.props.middlewareResults[1].account.user.userId;
    }
    return link.split('/').at(-1);
}

function isOtherProfile() {
    return pathMatches('user/.+');
}

function isOwnProfile() {
    return pathMatches('me/profile');
}

function isProfile() {
    return isOwnProfile() || isOtherProfile();
}

function isBattleRoyale() {
    return pathMatches('battle-royale/.+');
}

function isDuels() {
    return pathMatches('duels/.+');
}

async function getUserData(id) {
    const response = await fetch(`${GEOGUESSR_USER_ENDPOINT}/${id}`);
    const json = await response.json();

    return json;
}

const observer = new MutationObserver(onMutationsStandard);

observer.observe(document.body, OBSERVER_CONFIG);