Geoguessr average score display

Calculates average score from your last x amount of games. Restart of browser or refresh clears the currently saved scores.

当前为 2023-11-13 提交的版本,查看 最新版本

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         Geoguessr average score display
// @namespace    https://greasyfork.org/en/users/1080671
// @version      0.1.3
// @description  Calculates average score from your last x amount of games. Restart of browser or refresh clears the currently saved scores.
// @author       Lemson
// @match        https://www.geoguessr.com/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=geoguessr.com
// @grant        GM_setValue
// @grant        GM_getValue
// @run-at       document-idle
// @license MIT
// ==/UserScript==

(function () {
  "use strict";
    //Edit maxEntries to change how many of your past game you want to include.
  const maxEntries = 20;

  const data = GM_getValue('savedData', { scores: [], urls: [] }) || { scores: [], urls: [] };
  let elementDetected = false;

  const observer = new MutationObserver((mutations) => {
    mutations.forEach((mutation) => {
      const targetElements = document.querySelectorAll('[data-qa="final-result-score"] > div');

      if (targetElements.length > 0) {
        if (!elementDetected) {
          const childText = targetElements[0].innerText;
          const scoreValue = parseInt(childText, 10);
          const currentUrl = window.location.href;

          data.scores.push(scoreValue);
          data.urls.push(currentUrl);

          if (data.scores.length > maxEntries) {
            data.scores.shift();
            data.urls.shift();
          }

          GM_setValue('savedData', data);

          const totalScore = data.scores.reduce((sum, value) => sum + value, 0);
          const averageScore = totalScore / data.scores.length;

          displayAverageScore(averageScore);
          displayScoresDropdown(data);

          elementDetected = true;
        }
      } else {
        elementDetected = false;
      }
    });
  });

  const targetNode = document.body;

  if (targetNode) {
    observer.observe(targetNode, { childList: true, subtree: true });
  } else {
    console.error("Target node not found!");
  }

  function createElement(tag, attributes = {}, textContent = "") {
    const element = document.createElement(tag);
    Object.entries(attributes).forEach(([key, value]) => element.setAttribute(key, value));
    element.textContent = textContent;
    return element;
  }

  function displayAverageScore(averageScore) {
    const parentElement = document.querySelector('div[class^="result-overlay_overlayContent__"]');

    if (parentElement) {
      const averageScoreDiv = createElement('div', { style: "text-align: center;" }, `Average Score: ${averageScore.toFixed(2)} <br> (over ${maxEntries} rounds)`);
      parentElement.appendChild(averageScoreDiv);
    } else {
      console.error("Parent element not found!");
    }
  }

  function displayScoresDropdown(data) {
    const parentElement = document.querySelector('div[class^="result-overlay_overlayContent__"]');

    if (parentElement) {
      const dropdownContainer = createElement('div', { style: "text-align: center;" });
      const dropdown = createElement('select', { id: 'scoreDropdown' });

      data.scores.forEach((score, index) => {
        const option = createElement('option', { value: index }, `Round ${index + 1}: ${score}`);
        dropdown.appendChild(option);
      });

      dropdown.addEventListener('change', (event) => {
        const selectedIndex = event.target.value;
        const selectedUrl = data.urls[selectedIndex];
        window.location.href = selectedUrl;
      });

      dropdownContainer.appendChild(dropdown);
      parentElement.appendChild(dropdownContainer);
    } else {
      console.error("Parent element not found!");
    }
  }
})();