// ==UserScript== // @name Elo tracker // @version 0.1 // @description Adds an elo tracker to the GeoGuessr website // @match https://www.geoguessr.com/* // @run-at document-start // @author eru // @license MIT // @icon https://www.google.com/s2/favicons?sz=64&domain=geoguessr.com // @grant none // @namespace https://greasyfork.org/users/1348455 // @downloadURL none // ==/UserScript== /* jshint esversion: 8 */ const API_URL = 'https://ggstats.eu'; async function getUserInfo() { try { const response = await fetch('https://www.geoguessr.com/api/v3/profiles'); if (!response.ok) { throw new Error(`HTTP error! Status: ${response.status}`); } const data = await response.json(); return {nick: data.user.nick, hexId: data.user.id}; } catch (error) { console.error('Error fetching data:', error); return null; } } function updateElo(data) { fetch(API_URL+'/add-elo', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(data) }).then(response => response.json()).then(data => console.log('Success:', data)).catch((error) => console.error('Error:', error)); } function run() { const elo_string = document.querySelector('div[class*="game-finished-ranked_box__"]').firstChild.firstChild.firstChild.textContent; getUserInfo() .then(infos => { const { nick, hexId } = infos; const data = { name: nick, player_hexid: hexId, elo: parseInt(elo_string) }; updateElo(data); }) } let lastDoCheckCall = 0; // Any changes in the DOM triggers the MutationObserver callback new MutationObserver(async (mutations) => { // First make sure we are in a game if (!location.pathname.includes("/duels/") || lastDoCheckCall >= (Date.now() - 50)) return; lastDoCheckCall = Date.now(); // Then make sure we are in the finished game screen if (!document.querySelector('div[class*="game-finished-ranked_container__"]')) { sessionStorage.setItem("Checked", 0); return; } else if ((sessionStorage.getItem("Checked") || 0) == 0) { run(); sessionStorage.setItem("Checked", 1); } }).observe(document.body, { subtree: true, childList: true });