Hedge Streak Counter (Automated)

Adds a hedge streak counter to the GeoGuessr website. Compatible with country streak counters if both scripts are at least v.1.3.0.

目前为 2022-10-10 提交的版本。查看 最新版本

// ==UserScript==
// @name         Hedge Streak Counter (Automated)
// @version      1.3.3
// @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    https://gf.qytechs.cn/users/967692-victheturtle
// ==/UserScript==

// Credits to quarksauce for the original Hedge Streak Counter script. My only contribution was to make it compatible with the Country Streak Counter

const HEDGE_THRESHOLD = 20000;


if (sessionStorage.getItem("HedgeStreak") == null) {
    sessionStorage.setItem("HedgeStreak", 0);
};
if (sessionStorage.getItem("Checked") == null) {
    sessionStorage.setItem("Checked", 0);
};

let streak = parseInt(sessionStorage.getItem("HedgeStreak"), 10);
let lastGameId = sessionStorage.getItem("HedgeLastGameId");

function checkGameMode() {
    return (location.pathname.startsWith("/game/"));
};

let _cndic = {};
function cn(classNameStart) { // cn("status_section__") -> "status_section__8uP8o"
    let memorized = _cndic[classNameStart];
    if (memorized != null) return memorized;
    let selected = document.querySelector(`div[class*="${classNameStart}"]`);
    if (selected == null) return classNameStart;
    for (let className of selected.classList) {
        if (className.startsWith(classNameStart)) {
            _cndic[classNameStart] = className;
            return className;
        }
    }
}

function geoguessrStyle(number) {
    return `<div class="guess-description-distance_distanceLabel__23Opn">
                <div class="slanted-wrapper_root__2eaEs slanted-wrapper_variantWhiteTransparent__i_PRb slanted-wrapper_roundnessSmall__rEqsY">
                    <div class="slanted-wrapper_start__Kl7rv slanted-wrapper_right__G0JWR"></div>
					<div class="guess-description-distance_distanceValue__BRuXF">${number}</div>
					<div class="slanted-wrapper_end__cD1Qu slanted-wrapper_right__G0JWR"></div>
				</div>
			</div>`;
};

function addCounter() {
	if (!checkGameMode()) {
		return;
	};
    if (document.getElementById("hedge-streak") == null && document.getElementsByClassName(cn("status_section__")).length >= 3) {
        let newDiv = document.createElement("div");
        newDiv.className = cn("status_section__");
        document.getElementsByClassName(cn("status_inner__"))[0].appendChild(newDiv);
        newDiv.innerHTML = `<div class="${cn("status_label__")}">Hedge</div><div id="hedge-streak" class="${cn("status_value__")}">${streak}</div>`;
    }
};

function addStreakGameSummary() {
    if (document.getElementById("hedge-streak2") == null && !!document.querySelector('div[class*="standard-final-result_section__"]')) {
        let newDiv = document.createElement("div");
        let progressSection = document.getElementsByClassName(cn("standard-final-result_progressSection__"))[0];
        progressSection.parentNode.insertBefore(newDiv, progressSection);
        progressSection.style.marginTop = "10px";
        progressSection.style.marginBottom = "10px";
        newDiv.innerHTML = `<div id="hedge-streak2" style="text-align:center;margin-top:10px;"><h2><i>Hedge Streak: ${streak}</i></h2></div>`;
    };
};

function updateStreak(newStreak) {
    sessionStorage.setItem("HedgeStreak", newStreak);
    geoguessrStyle() // call cn() for the geoguessrStyle styles to memorize them while they are there
    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) {
        let 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) {
        check();
        sessionStorage.setItem("HedgeChecked", 1);
    }
};

function tryAddCounter() {
    addCounter();
    for (let timeout of [400,1200,2000,3000,4000]) {
        if (document.getElementsByClassName(cn("status_section__")).length == 0) {
            setTimeout(addCounter, timeout);
        };
    }
};

function tryAddCounterOnRefresh() {
    setTimeout(addCounter, 50);
    setTimeout(addCounter, 300);
};

function tryAddStreak() {
	if (!checkGameMode()) {
		return;
	};
    doCheck();
    for (let timeout of [250,500,1200,2000]) {
        setTimeout(doCheck, timeout);
    }
    for (let timeout of [250,500,1200,2000]) {
        setTimeout(addStreakGameSummary, timeout);
    }
};

document.addEventListener('keypress', (e) => {
    switch (e.key) {
        case '5':
            updateStreak(streak + 1);
            break;
        case '6':
            updateStreak(streak - 1);
            break;
        case '9':
            updateStreak(0);
    }
});

document.addEventListener('click', tryAddCounter, false);
document.addEventListener('click', tryAddStreak, false);
document.addEventListener('load', tryAddCounterOnRefresh(), false);

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址