您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Quickly resets the game by navigating to the last visited map and starting a new game.
当前为
// ==UserScript== // @name GeoGuessr Retry Hotkey // @namespace https://www.geoguessr.com/ // @version 1.3 // @description Quickly resets the game by navigating to the last visited map and starting a new game. // @author Shukaaa (mr aduchi) // @match https://www.geoguessr.com/* // @grant GM_setValue // @grant GM_getValue // @grant window.focus // @license MIT // ==/UserScript== (function () { 'use strict'; // Constants for script metadata, storage keys const SCRIPT_NAME = "GeoGuessr Retry Hotkey"; const LAST_VISITED_MAP_KEY = "lastVisitedMap"; const PLAY_TRIGGERED_KEY = "playTriggered"; const RESET_KEY_STORAGE = "resetKey"; // Retry Hotkey let RESET_KEY = localStorage.getItem(RESET_KEY_STORAGE) || "p"; // Helper: Logging function for consistent console outputs const log = (message, level = "log") => { const levels = { log: console.log, warn: console.warn }; const logFunction = levels[level] || console.log; logFunction(`[${SCRIPT_NAME}] ${message}`); }; // Helper: Save to GM storage const saveToStorage = (key, value) => GM_setValue(key, value); // Helper: Load from GM storage const loadFromStorage = (key, defaultValue = null) => GM_getValue(key, defaultValue); // Handle keydown for resetting the game const handleKeyDown = (event) => { const currentURL = window.location.href; // Open Change Key Dialog when CTRL + ALT + KEY is pressed if (event.ctrlKey && event.altKey && event.key === RESET_KEY) { openChangeKeyDialog(); return; } // Trigger reset if (currentURL.includes("/game/") && event.key === RESET_KEY) { const lastVisitedMap = loadFromStorage(LAST_VISITED_MAP_KEY); if (lastVisitedMap) { log(`'${RESET_KEY.toUpperCase()}' key pressed. Navigating to: ${lastVisitedMap}`); saveToStorage(PLAY_TRIGGERED_KEY, true); // Set playTriggered to true window.location.href = lastVisitedMap; // Redirect to the map } else { log("No last map URL found. Reset aborted.", "warn"); } } if (!currentURL.includes("/game/")) { log("Reset aborted: Not on a game page.", "warn"); } }; // Open dialog to change hotkey const openChangeKeyDialog = () => { const dialog = document.createElement("div"); dialog.style.position = "fixed"; dialog.style.top = "50%"; dialog.style.left = "50%"; dialog.style.transform = "translate(-50%, -50%)"; dialog.style.padding = "20px"; dialog.style.boxShadow = "inset 0 0.0625rem 0 hsla(0,0%,100%,.15),inset 0 -0.0625rem 0 rgba(0,0,0,.25)"; dialog.style.background = "linear-gradient(180deg,rgba(161,155,217,.6) 0%,rgba(161,155,217,0) 50%,rgba(161,155,217,0) 50%),var(--ds-color-purple-80)"; dialog.style.color = "var(--ds-color-white)"; dialog.style.fontSize = "var(--font-size-18)"; dialog.style.fontWeight = "700"; dialog.style.fontStyle = "italic"; dialog.style.zIndex = "10000"; dialog.style.borderRadius = "0.1875rem"; dialog.innerHTML = ` <p>Press a new key to set as the hotkey... (Press DEL to abort)</p> `; document.body.appendChild(dialog); // Handle key press const handleNewKey = (event) => { if (event.key !== "Delete") { RESET_KEY = event.key; localStorage.setItem(RESET_KEY_STORAGE, RESET_KEY); log(`New hotkey set: ${RESET_KEY}`); alert(`New hotkey set to: ${RESET_KEY.toUpperCase()}`); } document.body.removeChild(dialog); document.removeEventListener("keydown", handleNewKey); }; document.addEventListener("keydown", handleNewKey); }; // Automatically click the play button on the map page const attemptPlay = () => { const currentURL = window.location.href; const playTriggered = loadFromStorage(PLAY_TRIGGERED_KEY, false); if (currentURL.includes("/maps/") && playTriggered) { log("Map page detected with playTriggered=true. Attempting to start a new game..."); // Try finding the play button container const playButtonContainer = document.querySelector("div[class*='map-selector_playButtons']"); if (playButtonContainer) { const playButton = playButtonContainer.querySelector("button"); if (playButton) { saveToStorage(PLAY_TRIGGERED_KEY, false); playButton.focus(); setTimeout(() => { playButton.click(); }, 50); } else { log("'Play' button not found inside container.", "warn"); } } else { log("Play button container not found.", "warn"); } } }; // Save the current map URL if on a map page const saveCurrentMap = () => { const currentURL = window.location.href; if (currentURL.includes("/maps/")) { log(`Saving current map URL: ${currentURL}`); saveToStorage(LAST_VISITED_MAP_KEY, currentURL); } }; // Check for URL Changes const observeUrlChanges = () => { let lastUrl = window.location.href; const observer = new MutationObserver(() => { const currentUrl = window.location.href; if (currentUrl !== lastUrl) { log(`URL changed: ${currentUrl}`); lastUrl = currentUrl; // Save the map URL if it's a map page saveCurrentMap(); } }); observer.observe(document.body, { childList: true, subtree: true }); }; // Initialize script const initialize = () => { document.addEventListener("keydown", handleKeyDown); // Add keydown listener attemptPlay(); // Check if play needs to be triggered saveCurrentMap(); // Save the map URL if relevant observeUrlChanges(); // Start observing URL changes }; // Run the script initialize(); })();