您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Changes the Avatar to your Pin/Profile Picture. Works in Duels, Br, Profile and many more places and not only your Avatar but also the Avatar of others
当前为
// ==UserScript== // @name Geoguessr change Avatar to Pin/ProfilePicture // @description Changes the Avatar to your Pin/Profile Picture. Works in Duels, Br, Profile and many more places and not only your Avatar but also the Avatar of others // @version 1.1.0 // @license MIT // @author joniber#5011 // @match https://www.geoguessr.com/* // @icon https://www.google.com/s2/favicons?sz=64&domain=geoguessr.com // @namespace https://greasyfork.org/users/1072330 // ==/UserScript== //any questons, feedback, problems or feature request -> Discord joniber#5011 //=====================================================================================\\ // change these values however you like (make sure to hit ctrl+s afterwards) \\ // PIN = PROFILE PICTURE \\ //=====================================================================================\\ const PIN_IN_OWN_PROFILE = true // ^^^^ set this to <false> to NOT change your Avatar to a PIN in your own profile const PIN_IN_OTHERS_PROFILE = true // ^^^^^ set this to <false> to NOT change the Avatar to a PIN in other profiles const PIN_IN_DUELS_MATCHMAKING = true // ^^^^ set this to <false> to NOT change the Avatar to a PIN in that area const PIN_IN_BR_MATCHMAKING = true // ^^^^ set this to <false> to NOT change the Avatar to a PIN in that area const NO_AVATARS_END_OF_DUEL = true // ^^^^ set this to <false> to NOT change the Avatar to a PIN in that area const PIN_IN_TEAM_DUEL_PRIVATE_LOBBY = true // ^^^^ set this to <false> to NOT change the Avatar to a PIN in that area const PIN_IN_FRIEND_TAB = true // ^^^^ set this to <false> to NOT change the Avatar to a PIN in that area //=====================================================================================\\ // 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 av = null let index = 0 let player1 = null let player2 = null 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) let level = roundToNearest10(userData.progress.level) if(level == 210){ level = 200 } 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 fillImageMultiple(link, id, setLvl){ if (!link.querySelector(`.${USER_PIN_CLASS}`)) { if(wrapper){ link.firstChild.style.display="none" let destination = link fillImage(link, link, id, true, setLvl) } } } async function changePinInFriendTab(link) { if(link){ if (!link.querySelector(`.${USER_PIN_CLASS}`)) { const wrapper = link.querySelector('[class^="transparent-avatar_imageWrapper__"]') if(wrapper){ wrapper.classList.remove('transparent-avatar_imageWrapper__izUAM') wrapper.classList.add('styles_circle__QFYEk', 'styles_variantFloating__Srm_N', 'styles_colorTransparent__2bG5I', 'styles_borderColorTransparent__CwSAk', 'styles_borderSizeFactorZero__MEFpf') wrapper.insertAdjacentHTML('afterbegin', wrapperFriend1()) const destination = link.querySelector('.styles_content__otIVG') const pin = destination.firstChild let id = link.querySelector('.anchor_variantNoUnderline__SPwsd').href const userId = retrieveIdFromLink(id) const userData = await getUserData(userId) const pinURL = userData.pin.url pin.setAttribute('src', '/images/auto/48/48/ce/0/plain/' + pinURL) wrapper.lastChild.style="display:none" } } } } function fillImage(destination, link, id, c, withLvl){ if(c){ 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 fillPin(pin, retrieveIdFromLink(id)) if(withLvl){ destination = link.querySelector('.styles_rectangle___6gqv.up__') destination.insertAdjacentHTML('beforeend', levelBorder()) const lvl = destination.lastChild fillLvl(lvl, retrieveIdFromLink(id)) } } else{ destination.insertAdjacentHTML('beforeend', wrapper()) destination = document.querySelector('.avatar_titleAvatarImage__A51Dx.up__') destination.insertAdjacentHTML('beforeend', profilePicture1()) const pin = destination.lastChild fillPin(pin, retrieveIdFromLink(id)) if(withLvl){ destination = document.querySelector('.styles_rectangle___6gqv.up__') destination.insertAdjacentHTML('beforeend', levelBorder1()) const lvl = destination.lastChild fillLvl(lvl, retrieveIdFromLink(id)) } } } function changeAvatarToPin(link, avatarToRemove) { if (!link.querySelector(`.${USER_PIN_CLASS}`)) { if (link) { let destination = null if (avatarToRemove == link) { link.querySelector('.styles_image__8M_kp').style = 'display: none' destination = link.firstChild } else { link.querySelector('.player-card_lobbyCardInner__G_xzy').firstChild.remove() destination = link.querySelector('.player-card_lobbyCardInner__G_xzy') } let id = '/me/profile' if (link.querySelector('.player-card_userLink__HhoDo') != null) { id = link.querySelector('.player-card_userLink__HhoDo').href } fillImage(destination, link, id, true, true) } } } let pfpToLink = {} let nameToLink = {} const originalSend = WebSocket.prototype.send WebSocket.prototype.send = function(...args) { window.ws = this if (this.geoguessrClickablePartyCards == 0) return originalSend.call(this, ...args) this.geoguessrClickablePartyCards = 0 const originalOnmessage = this.onmessage this.onmessage = ({ data }) => { if (originalOnmessage != null) originalOnmessage({ data }) const received = JSON.parse(data) if(received.code == 'PartyUpdated'){ let payload = JSON.parse(received.payload) let players = payload.players for (let player of players){ nameToLink[player.name] = "user/"+player.id } } if (received.code == 'PartyMemberListUpdated') { let payload = JSON.parse(received.payload) let members = payload.members for (let member of members) { if (member.pin != "") pfpToLink[member.pin] = "user/"+member.userId if (member.fullBodyPin != "") pfpToLink[member.fullBodyPin] = "user/"+member.userId } } } return originalSend.call(this, ...args) } function addPinToPartyCard(wrapper) { const image = wrapper.querySelector('.member-card_imageWrapper__5L2DF img') if(image){ const imgPin = image.src.substr(57) const id = pfpToLink[imgPin] if (id != null) { const link = wrapper.querySelector('.member-card_imageWrapper__5L2DF') fillImageMultiple(link, id, false) } } } function addPinToTeamDuelsCard(wrapper){ const name = wrapper.querySelector('.user-nick_nick__y4VIt').innerHTML.replace(' ', '').replace(';','') if(name){ if(nameToLink.length != 0){ const id = nameToLink[name] if(id){ const link = wrapper.querySelector('.team-player-card_lobbyCardInner__fT8A_') fillImageMultiple(link, id, true) } } } } let inBattleRoyale = false let inDuels = false let inParty = false let inTeamDuel = false let lastOpenedMapHighscoreTab = 0 function onMutationTeamDuel(mutations,observer){ if (!isTeamDuel()) return const cards = document.querySelectorAll('.team-player-card_lobbyCard__7p_OY') for(let card of cards){ addPinToTeamDuelsCard(card) } if(document.querySelector('.game-finished_avatarContainer__S63IS')){ onMutationEnd() } } function onMutationParty(mutations,observer){ if (location.pathname != "/party") return const cards = document.querySelectorAll(".member-card_root__zbBxx") for (let card of cards) { addPinToPartyCard(card) } } function onMutationEnd() { if (NO_AVATARS_END_OF_DUEL) { const gameFinishedAvatarContainer = document.querySelector( '.game-finished_avatarContainer__S63IS' ) if (gameFinishedAvatarContainer) { if (document.querySelector('.styles_rectangle___6gqv.up__') == null) { gameFinishedAvatarContainer.firstChild.remove() let destination = gameFinishedAvatarContainer 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' fillPin(pin, retrieveIdFromLink(id)) destination = document.querySelector('.styles_rectangle___6gqv.up__') destination.insertAdjacentHTML('beforeend', levelBorder()) const lvl = destination.lastChild if ( document.querySelector('.shadow-text_root__o3lD9').innerHTML.startsWith('YOU') ) { fillLvl(lvl, retrieveIdFromLink(id)) } else { lvl.lastChild.setAttribute( 'src', '/_next/static/images/laurel-wreath-gold-53fd377e1d268ce57fcd6f0dfb9f3727.png' ) } } } } } function onMutationsDuels(mutations, observer) { 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)); } 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; } const endOfDuelsObserver = new MutationObserver(onMutationEnd); if (endOfDuelsObserver) { endOfDuelsObserver.observe( document.querySelector('.overlay_overlay__AR02x'), OBSERVER_CONFIG ); } } function onMutationsStandard(mutations, observer) { if (isDuels() && !inDuels && document.querySelector('.game_hud__fhdo5')) { inDuels = true const duelsObserver = new MutationObserver(onMutationsDuels) duelsObserver.observe(document.querySelector('.game_hud__fhdo5'), OBSERVER_CONFIG) } else if (inDuels && !document.querySelector('.game_hud__fhdo5')) { inDuels = false } else if(isParty() && !inParty){ inParty=true const partyObserver = new MutationObserver(onMutationParty) partyObserver.observe(document.body, OBSERVER_CONFIG) } else if (inParty && !document.querySelector('.party_root__EQz_N')) { inParty = false } else if(isTeamDuel() && !inTeamDuel){ inTeamDuel=true const teamDuelObserver = new MutationObserver(onMutationTeamDuel) teamDuelObserver.observe(document.body, OBSERVER_CONFIG1) } else if (inParty && !document.querySelector('.lobby_root__Z9W2f')) { inTeamDuel = false } if (inBattleRoyale || inDuels || inParty) { return } if (isProfile()) { if (!PIN_IN_OWN_PROFILE && isOwnProfile()) { return } if (!PIN_IN_OTHERS_PROFILE && isOtherProfile()) { return } if (!document.querySelector(`#${USER_PIN_ID}`)) { if(document.querySelector('.profile-header_fullBodyAvatar___LRnw')){ document.querySelector('.profile-header_fullBodyAvatar___LRnw').remove() let destination = document.querySelector('.profile-header_avatarWrapper__5_jDA') fillImage(destination, document, location.href, false, true) } } } if (PIN_IN_BR_MATCHMAKING) { // battle royale matchmaking for (const link of document.querySelectorAll('.player-card_root__NvK_s')) { changeAvatarToPin(link, 'player-card_lobbyCardInner__G_xzy') } } if (PIN_IN_FRIEND_TAB) { for (const link of document.querySelectorAll('.chat-friend_content__zbEBt')) { changePinInFriendTab(link) } } 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() fillImage(av, document, retrieveIdFromLink('/me/profile'), false, true) } if (av != null) { av = null } } } if (document.getElementById('60cf2c9800ea7b00015231a2')) { document.getElementById('60cf2c9800ea7b00015231a2').remove() if (!document.querySelector(`#${USER_PIN_ID}`)) { let destination = document.querySelector('.join-party_avatarWrapper__2WzCN') fillImage(destination, document, retrieveIdFromLink('/me/profile'), false, true) } } } //helpfunctions function roundToNearest10(zahl) { if (zahl % 10 === 0) { return zahl + 10 } else { return Math.ceil(zahl / 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 isParty(){ return pathMatches('party') } function isTeamDuel(){ return pathMatches('team-duels/.+') } function isDuels() { return pathMatches('duels/.+') } async function getUserData(id) { const response = await fetch(`${GEOGUESSR_USER_ENDPOINT}/${id}`) const json = await response.json() return json } function wrapperFriend1(){ return `<div class="styles_rectangle___6gqv" style="padding-top: 100%"><div class="styles_innerCircle__Y_L_e"><div class="styles_content__otIVG up__userPin"><img class="styles_image__8M_kp ${USER_PIN_CLASS}" loading="auto" style="object-fit: cover"></div></div></div>` } function wrapperFriend() { return `<div class="styles_circle__QFYEk styles_variantFloating__Srm_N styles_colorTransparent__2bG5I styles_borderColorTransparent__CwSAk styles_borderSizeFactorZero__MEFpf"><div class="styles_rectangle___6gqv" style="padding-top: 100%"><div class="styles_innerCircle__Y_L_e"><div class="styles_content__otIVG up__"></div></div></div></div>` } 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>` } const OBSERVER_CONFIG = { characterDataOldValue: false, subtree: true, childList: true, characterData: false, } const OBSERVER_CONFIG1 = { characterDataOldValue: false, subtree: true, childList: true, characterData: true, attributes: true, attributeFilter: ["style"] } const ERROR_MESSAGE = (wrong) => '${wrong}' function pathMatches(path) { return location.pathname.match(new RegExp(`^/(?:[^/]+/)?${path}$`)) } const observer = new MutationObserver(onMutationsStandard) observer.observe(document.body, OBSERVER_CONFIG)