Greasy Fork is available in English.
Adds a hedge streak counter to the GeoGuessr website. Compatible with country streak counters if both scripts are at least v.1.3.0.
当前为
// ==UserScript==
// @name Hedge Streak Counter (Automated)
// @version 1.3.5
// @description Adds a hedge streak counter to the GeoGuessr website. Compatible with country streak counters if both scripts are at least v.1.3.0.
// @author victheturtle#5159
// @license MIT
// @match https://www.geoguessr.com/*
// @icon https://www.google.com/s2/favicons?sz=64&domain=geoguessr.com
// @namespace http://greasyfork.icu/users/967692-victheturtle
// ==/UserScript==
// Credits to quarksauce for the original Hedge Streak Counter script
const HEDGE_THRESHOLD = 20000;
// ^^^^^ You can change the threshold for getting the streak here
let streak = parseInt(sessionStorage.getItem("HedgeStreak") || 0, 10);
let lastGameId = sessionStorage.getItem("HedgeLastGameId") || "";
function checkGameMode() {
return (location.pathname.startsWith("/game/"));
};
const _cndic = {};
const hrefset = new Set();
async function scanStyles() {
for (let node of document.querySelectorAll('head link[rel="preload"], head style[data-n-href*=".css"]')) {
const href = node.href || location.origin+node.dataset.nHref;
if (hrefset.has(href)) continue;
hrefset.add(href);
await fetch(href)
.then(res => res.text())
.then(stylesheet => {
for (let className of stylesheet.split(".")) {
const ind = className.indexOf("__");
if (ind != -1) _cndic[className.substr(0, ind+2)] = className.substr(0, ind+7);
};
});
};
};
const cn = (classNameStart) => _cndic[classNameStart]; // cn("status_section__") -> "status_section__8uP8o"
function geoguessrStyle(number) {
return `<div class="${cn("guess-description-distance_distanceLabel__")}">
<div class="${cn("slanted-wrapper_root__")} ${cn("slanted-wrapper_variantWhiteTransparent__")} ${cn("slanted-wrapper_roundnessSmall__")}">
<div class="${cn("slanted-wrapper_start__")} ${cn("slanted-wrapper_right__")}"></div>
<div class="${cn("guess-description-distance_distanceValue__")}">${number}</div>
<div class="${cn("slanted-wrapper_end__")} ${cn("slanted-wrapper_right__")}"></div>
</div>
</div>`;
};
function addStreakStatusBar() {
if (document.getElementById("hedge-streak") == null && document.getElementsByClassName(cn("status_section__")).length >= 3) {
const newDiv = document.createElement("div");
newDiv.className = cn("status_section__");
newDiv.innerHTML = `<div class="${cn("status_label__")}">Hedge</div><div id="hedge-streak" class="${cn("status_value__")}">${streak}</div>`;
document.getElementsByClassName(cn("status_inner__"))[0].appendChild(newDiv);
}
};
function addStreakGameSummary() {
if (document.getElementById("hedge-streak2") == null && !!document.querySelector('div[class*="standard-final-result_section__"]')) {
const newDiv = document.createElement("div");
newDiv.innerHTML = `<div id="hedge-streak2" style="text-align:center;margin-top:10px;"><h2><i>Hedge Streak: ${streak}</i></h2></div>`;
const progressSection = document.querySelector('div[class*="standard-final-result_progressSection__"]');
progressSection.parentNode.insertBefore(newDiv, progressSection);
progressSection.style.marginTop = "10px";
progressSection.style.marginBottom = "10px";
};
};
function updateStreak(newStreak) {
sessionStorage.setItem("HedgeStreak", newStreak);
if (document.getElementById("hedge-streak") != null) {
document.getElementById("hedge-streak").innerHTML = newStreak;
};
if (document.getElementById("hedge-streak2") != null &&
(!!document.querySelector('div[data-qa="guess-description"]') || !!document.querySelector('div[class*="standard-final-result_section__"]'))) {
document.getElementById("hedge-streak2").innerHTML = `<h2><i>Hedge Streak: ${newStreak}</i></h2>`;
if (newStreak == 0) {
if (streak >= 2) {
document.getElementById("hedge-streak2").innerHTML = `<h2><i>Hedge Streak: 0</i></h2>
Your hedge streak ended after ${geoguessrStyle(streak)} seeds.`;
} else if (streak == 1) {
document.getElementById("hedge-streak2").innerHTML = `<h2><i>Hedge Streak: 0</i></h2>
Your hedge streak ended after ${geoguessrStyle(1)} seed.`;
};
};
};
streak = newStreak;
};
function check() {
const gameId = window.location.href.substring(window.location.href.lastIndexOf('/') + 1);
if (checkGameMode() && gameId != lastGameId) {
const apiUrl = "https://www.geoguessr.com/api/v3/games/" + gameId;
fetch(apiUrl)
.then(res => res.json())
.then((out) => {
if (out.state == "finished") {
if (parseInt(out.player.totalScore.amount, 10) >= HEDGE_THRESHOLD) {
updateStreak(streak+1);
lastGameId = gameId;
sessionStorage.setItem("HedgeLastGameId", lastGameId);
} else {
updateStreak(0);
}
};
}).catch(err => { throw err; });
};
};
function doCheck() {
if (!document.querySelector('div[class*="result-layout_root__"]')) {
sessionStorage.setItem("HedgeChecked", 0);
} else if ((sessionStorage.getItem("HedgeChecked") || 0) == 0) {
check();
sessionStorage.setItem("HedgeChecked", 1);
}
};
let lastDoCheckCall = 0;
new MutationObserver(async (mutations) => {
if (!checkGameMode() || lastDoCheckCall >= (Date.now() - 50)) return;
lastDoCheckCall = Date.now();
await scanStyles();
doCheck();
addStreakStatusBar();
addStreakGameSummary();
}).observe(document.body, { subtree: true, childList: true });
document.addEventListener('keypress', (e) => {
if (e.key == '5') {
updateStreak(streak + 1);
} else if (e.key =='6') {
updateStreak(streak - 1);
} else if (e.key == '9') {
updateStreak(0);
}
});