您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
singleplayer 5k counter, counts per game and total, resettable
当前为
// ==UserScript== // @name GeoGuessr 5K Counter // @namespace https://greasyfork.org/en/users/1501889 // @version 1.2 // @description singleplayer 5k counter, counts per game and total, resettable // @author Clemens // @match https://www.geoguessr.com/* // @icon https://www.google.com/s2/favicons?domain=geoguessr.com // @grant GM_getValue // @grant GM_setValue // @grant GM_addStyle // @run-at document-end // @license MIT // ==/UserScript== (function() { 'use strict'; const stats = { total: GM_getValue('geo5k_total', 0), currentGame: GM_getValue('geo5k_current', 0), lastDetection: 0 }; function saveStats() { GM_setValue('geo5k_total', stats.total); GM_setValue('geo5k_current', stats.currentGame); } GM_addStyle(` #geo5k-counter { position: fixed; left: 20px; top: 75vh; background: rgba(30, 30, 30, 0.9); color: #f0f0f0; padding: 12px 16px; border-radius: 8px; font-family: 'Segoe UI', system-ui, -apple-system, sans-serif; font-size: 14px; z-index: 9999; border: 1px solid rgba(255, 255, 255, 0.1); min-width: 180px; cursor: move; user-select: none; backdrop-filter: blur(4px); box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); transition: transform 0.1s ease, box-shadow 0.2s ease; } #geo5k-counter:hover { box-shadow: 0 6px 16px rgba(0, 0, 0, 0.2); } #geo5k-counter.dragging { cursor: grabbing; transform: scale(1.02); box-shadow: 0 8px 24px rgba(0, 0, 0, 0.3); transition: transform 0.05s ease, box-shadow 0.05s ease; } #geo5k-counter-header { font-weight: 600; margin-bottom: 8px; font-size: 15px; color: #58a6ff; display: flex; align-items: center; justify-content: space-between; } #geo5k-counter-header::before { content: "✓"; color: #58a6ff; font-weight: bold; margin-right: 6px; } .geo5k-counter-row { margin: 6px 0; display: flex; justify-content: space-between; } .geo5k-counter-value { font-weight: 500; color: #ffffff; } #geo5k-reset-btn { background: rgba(255, 255, 255, 0.1); color: #ff6b6b; border: none; border-radius: 4px; padding: 2px 8px; font-size: 12px; cursor: pointer; transition: all 0.2s ease; margin-left: 8px; } #geo5k-reset-btn:hover { background: rgba(255, 107, 107, 0.2); color: #ff4d4d; } .geo5k-highlight { animation: geo5k-pulse 0.5s; } @keyframes geo5k-pulse { 0% { transform: scale(1); } 50% { transform: scale(1.1); } 100% { transform: scale(1); } } `); function createDisplay() { if (document.getElementById('geo5k-counter')) return; const display = document.createElement('div'); display.id = 'geo5k-counter'; display.innerHTML = ` <div id="geo5k-counter-header"> <span>5K COUNTER</span> <button id="geo5k-reset-btn" title="Reset Total Count">Reset</button> </div> <div class="geo5k-counter-row"> <span>This Game:</span> <span id="geo5k-current" class="geo5k-counter-value">${stats.currentGame}/5</span> </div> <div class="geo5k-counter-row"> <span>Total:</span> <span id="geo5k-total" class="geo5k-counter-value">${stats.total}</span> </div> `; document.body.appendChild(display); document.getElementById('geo5k-reset-btn').addEventListener('click', function(e) { e.stopPropagation(); if (confirm('Are you sure you want to reset your total 5K count?')) { stats.total = 0; saveStats(); updateDisplay(); } }); let isDragging = false; let offsetX, offsetY; display.addEventListener('mousedown', startDrag); document.addEventListener('mousemove', drag); document.addEventListener('mouseup', endDrag); function startDrag(e) { if (e.button !== 0 || e.target.id === 'geo5k-reset-btn') return; isDragging = true; const rect = display.getBoundingClientRect(); offsetX = e.clientX - rect.left; offsetY = e.clientY - rect.top; display.classList.add('dragging'); e.preventDefault(); } function drag(e) { if (!isDragging) return; let newX = e.clientX - offsetX; let newY = e.clientY - offsetY; const maxX = window.innerWidth - display.offsetWidth; const maxY = window.innerHeight - display.offsetHeight; newX = Math.max(0, Math.min(newX, maxX)); newY = Math.max(0, Math.min(newY, maxY)); display.style.left = `${newX}px`; display.style.top = `${newY}px`; } function endDrag() { if (!isDragging) return; isDragging = false; display.classList.remove('dragging'); } } function updateDisplay() { const currentEl = document.getElementById('geo5k-current'); const totalEl = document.getElementById('geo5k-total'); if (currentEl) currentEl.textContent = `${stats.currentGame}/5`; if (totalEl) totalEl.textContent = stats.total; } function checkFor5K() { const elements = document.body.getElementsByTagName('*'); for (let i = 0; i < elements.length; i++) { const text = elements[i].textContent.trim(); if (text === '5,000' || text === '5000' || text.replace(/\s/g,'') === '5000') { handle5KDetection(elements[i]); return; } } } function handle5KDetection(element) { const now = Date.now(); if (now - stats.lastDetection < 3000) return; stats.lastDetection = now; stats.total++; stats.currentGame++; saveStats(); updateDisplay(); element.classList.add('geo5k-highlight'); setTimeout(() => { element.classList.remove('geo5k-highlight'); }, 500); if (stats.currentGame >= 5) { setTimeout(() => { stats.currentGame = 0; saveStats(); updateDisplay(); }, 3000); } } function checkGameState() { const roundText = document.body.textContent; if (roundText.includes('Round 1/5') || roundText.includes('1 / 5')) { stats.currentGame = 0; saveStats(); updateDisplay(); } } function init() { createDisplay(); updateDisplay(); setInterval(() => { checkFor5K(); checkGameState(); }, 1000); } if (document.readyState === 'complete') { setTimeout(init, 1000); } else { window.addEventListener('load', init); } })();