Greasy Fork

Greasy Fork is available in English.

Seterra for speedrunners

Doesn't change the game mechanics, only visual stuff

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name         Seterra for speedrunners
// @namespace    http://tampermonkey.net/
// @version      1.0
// @description  Doesn't change the game mechanics, only visual stuff
// @author       Carus (feat. GPT-3)
// @license      MIT
// @match        https://www.geoguessr.com/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=geoguessr.com
// @grant        none
// ==/UserScript==

// ALL LINES COMMENTED WITH "⚠ ⚠ ⚠" must be adjusted depending on your setup

(function() {
  'use strict';
// ------------------------------- Add mean time by question counter -------------------------------

  // Convert time to ms
  function tempsTexteToMillisecondes(tempsTexte) {
    var parties = tempsTexte.split(':');
    var minutes = parseInt(parties[0]);
    var secondes = parseFloat(parties[1].replace(',', '.'));

    var tempsEnMillisecondes = minutes * 60000 + secondes * 1000;
    return tempsEnMillisecondes;
  }

  // Execute when target div appears
  function executerScriptQuandPresent() {
    // Check if "score-modal_scoreModal__rtmEE" is present
    var scoreModalDiv = document.querySelector('.score-modal_scoreModal__rtmEE');
    if (scoreModalDiv && !scoreModalDiv.dataset.executed) {
      // Prevent infinite loop
      scoreModalDiv.dataset.executed = true;

      // Collect all divs with class = "label_sizeXLarge__N1iE_"
      var divsCibles = document.querySelectorAll('.label_sizeXLarge__N1iE_');

      // Collect time in text in the second div
      var tempsTexte = divsCibles[1].textContent;

      // Convert time into ms
      var tempsEnMillisecondes = tempsTexteToMillisecondes(tempsTexte);

      // Count questions
      var nombreDivs = document.querySelectorAll('li.area-list_listItem__SVHpB').length;

      // Divide time by the number of questions
      var tempsMoyenSecondes = tempsEnMillisecondes / 1000 / nombreDivs;

      // Create new div
      var nouveauDiv = document.createElement('div');

      // Add class to the new div (not useful at the moment)
      nouveauDiv.className = 'meantime';

      // Write mean time by question in s.ms format
      nouveauDiv.textContent = "t/q : " + tempsMoyenSecondes.toFixed(3);

      // Select the results pannel div "initial-score-view_result__b0EVM"
      var resultatDiv = document.querySelector('.initial-score-view_result__b0EVM');
      // Append the new div to the results
      resultatDiv.appendChild(nouveauDiv);
    }
  }

  // Create mutation observer
  var observer = new MutationObserver(function(mutations) {
    mutations.forEach(function(mutation) {
      if (mutation.type === 'childList') {
        executerScriptQuandPresent();
      }
    });
  });

  // Observation options
  var options = {
    childList: true,
    subtree: true
  };

  // Select node
  var bodyNode = document.body;

  // Observe node with options
  observer.observe(bodyNode, options);

// ------------------------------- Remove "Click on" -------------------------------

function supprimerPremiereLigne() {
  // Select div "game-tooltip_tooltip__iJM_6"
  const tooltipDiv = document.querySelector('.game-tooltip_tooltip__iJM_6');

  // Check if div has text
  if (tooltipDiv && tooltipDiv.firstChild && tooltipDiv.firstChild.nodeType === Node.TEXT_NODE) {
    // Get text
    const textePremiereLigne = tooltipDiv.firstChild.textContent;

    // Check if div starts with "Click on"
    if (textePremiereLigne.startsWith('Click on')) { // Replace "Click on" on this line with the translation in your language and keep the single quotation marks ⚠ ⚠ ⚠
      // Remove "Click on"
      tooltipDiv.firstChild.remove();
    }
  }
}

// Execute every second
setInterval(supprimerPremiereLigne, 1000);

// ------------------------------- Change appearance -------------------------------

function modifyCSS(element, properties) {
  for (const property in properties) {
    element.style[property] = properties[property];
  }
}

// Select css classes
function modifyDivs() {
  const tooltipDiv = document.querySelector('.game-tooltip_tooltip__iJM_6');
  const labelBoxDiv = document.querySelector('.map-styles_labelBox__s5xsm');
  const labelVisibleDiv = document.querySelector('.label-flash_labelVisible__58deG');
  const correctFlash = document.querySelector('.correct-flash_wrapper__jONHo');
  const countryBordersDivs = document.querySelectorAll('.map-question_question__xQovH .map-question_hitbox__HqANz');

  // Cursor label
  if (tooltipDiv) {
    modifyCSS(tooltipDiv, {
      backgroundColor: 'rgba(0, 0, 0, 0)',
      color: 'yellow',
      textShadow: '2px 0 #000, -3px 0 #000, 0 3px #000, 0 -3px #000, 1px 1px #000, -1px -1px #000, 1px -1px #000, -1px 1px #000',
      position: 'fixed',
      fontSize: '1.8em',
      // Disgraceful way of changing the position of the cursor label, but it works
      marginLeft: '20%', // Depends on screen width, adjust the value ⚠ ⚠ ⚠
      marginTop: '-4%' // Depends on how much the page is scrolled, adjust the value ⚠ ⚠ ⚠
    });
  }

  // Country labels
  if (labelBoxDiv) {
    modifyCSS(labelBoxDiv, {
      display: 'none'
    });
  }
  // Country labels
  if (labelVisibleDiv) {
    modifyCSS(labelVisibleDiv, {
      display: 'none'
    });
  }

  // Correct answer flashes
  if (correctFlash) {
    modifyCSS(correctFlash, {
      display: 'none'
    });
  }

  // Country borders
  countryBordersDivs.forEach(div => {
    modifyCSS(div, {
      stroke: '#000', // Adjust the color if you have a "dark mode" browser addon of some kind ⚠ ⚠ ⚠
      strokeWidth: '1px', // Can change depending on the size of the map ⚠ ⚠ ⚠
      transition: 'fill 0s ease'
    });
  });
}

// Execute constantly as fast as possible !!!!!!
setInterval(modifyDivs, 1); // Should be capped by your browser, but increase the value if there is lag (1000 = 1 second) ⚠ ⚠ ⚠


})();