// ==UserScript==
// @name GeoGuessr God Mode - Ultimate Cheat Toolkit
// @namespace http://tampermonkey.net/
// @version 1.0
// @description Complete GeoGuessr cheat with answer revealer, auto-guess, coordinate extractor, Street View metadata, and more
// @author GeoHacker
// @match https://www.geoguessr.com/*
// @grant GM_xmlhttpRequest
// @grant GM_getValue
// @grant GM_setValue
// @license CC-BY-NC-4.0
// @run-at document-start
// ==/UserScript==
(function() {
'use strict';
let currentAnswer = null;
let googleMapsKey = GM_getValue('google_maps_key', '');
let settings = {
autoReveal: GM_getValue('auto_reveal', false),
showOnMap: GM_getValue('show_on_map', true),
extractMetadata: GM_getValue('extract_metadata', false)
};
// Wait for page to fully load
let initInterval = setInterval(() => {
if (document.readyState === 'complete') {
clearInterval(initInterval);
setTimeout(init, 1000);
}
}, 100);
function init() {
console.log('🌍 GeoGuessr God Mode: Initializing...');
// Try to extract answer from page data
extractAnswerFromPage();
// Create GUI
createGUI();
// Set up mutation observer to detect new rounds
observePageChanges();
console.log('🌍 GeoGuessr God Mode: Ready!');
}
function extractAnswerFromPage() {
try {
// Method 1: Extract from __NEXT_DATA__ script tag
const nextDataScript = document.getElementById('__NEXT_DATA__');
if (nextDataScript) {
const data = JSON.parse(nextDataScript.textContent);
// Navigate through the data structure to find coordinates
const game = data?.props?.pageProps?.game;
const rounds = game?.rounds;
if (rounds && rounds.length > 0) {
// Find current round
const currentRound = game.round || 0;
const roundData = rounds[currentRound];
if (roundData && roundData.lat && roundData.lng) {
currentAnswer = {
lat: roundData.lat,
lng: roundData.lng,
panoId: roundData.panoId || null,
heading: roundData.heading || null,
pitch: roundData.pitch || null,
zoom: roundData.zoom || null
};
console.log('🎯 Answer found:', currentAnswer);
updateGUI();
if (settings.autoReveal) {
showNotification('Answer coordinates extracted! 🎯');
}
if (settings.extractMetadata && googleMapsKey) {
fetchStreetViewMetadata();
}
return true;
}
}
}
// Method 2: Try to extract from React fiber
const gameContainer = document.querySelector('[data-qa="close-round-result"]')?.parentElement;
if (gameContainer && gameContainer._reactRootContainer) {
// Try to access React internal state
console.log('🔍 Searching React fiber...');
}
} catch (e) {
console.log('⚠️ Could not extract answer:', e.message);
}
return false;
}
function fetchStreetViewMetadata() {
if (!currentAnswer || !googleMapsKey) return;
const url = `https://maps.googleapis.com/maps/api/streetview/metadata?location=${currentAnswer.lat},${currentAnswer.lng}&key=${googleMapsKey}`;
GM_xmlhttpRequest({
method: 'GET',
url: url,
onload: function(response) {
try {
const data = JSON.parse(response.responseText);
if (data.status === 'OK') {
currentAnswer.metadata = {
panoId: data.pano_id,
date: data.date,
copyright: data.copyright,
exactLat: data.location.lat,
exactLng: data.location.lng
};
console.log('📸 Street View metadata:', currentAnswer.metadata);
updateGUI();
}
} catch (e) {
console.log('⚠️ Failed to fetch metadata:', e);
}
}
});
}
function observePageChanges() {
// Watch for page changes to detect new rounds
const observer = new MutationObserver(() => {
setTimeout(extractAnswerFromPage, 500);
});
observer.observe(document.body, {
childList: true,
subtree: true
});
}
function createGUI() {
const gui = document.createElement('div');
gui.id = 'geo-god-mode';
gui.innerHTML = `
<div class="geo-header">
<span>🌍 God Mode</span>
<button id="geo-minimize">−</button>
</div>
<div class="geo-content">
<!-- Answer Display -->
<div class="geo-section">
<div class="geo-section-header">
<span>🎯 Answer Coordinates</span>
</div>
<div class="geo-section-content">
<div id="answer-display" class="answer-box">
<p>Waiting for round to load...</p>
</div>
<div class="geo-row">
<button id="copy-coords" class="geo-btn" disabled>📋 Copy Coordinates</button>
<button id="open-google-maps" class="geo-btn" disabled>🗺 Open in Google Maps</button>
</div>
<div class="geo-row">
<button id="auto-guess" class="geo-btn" disabled>🎯 Auto Guess (Perfect)</button>
</div>
</div>
</div>
<!-- Street View Metadata -->
<div class="geo-section">
<div class="geo-section-header">
<span>📸 Street View Info</span>
</div>
<div class="geo-section-content">
<div id="metadata-display" class="metadata-box">
<p><small>Enter Google Maps API key in settings to enable</small></p>
</div>
</div>
</div>
<!-- Quick Actions -->
<div class="geo-section">
<div class="geo-section-header">
<span>⚡ Quick Actions</span>
</div>
<div class="geo-section-content">
<div class="geo-row">
<button id="show-on-map" class="geo-btn">📍 Show Answer on Map</button>
</div>
<div class="geo-row">
<button id="reverse-search" class="geo-btn">🔍 Reverse Image Search</button>
</div>
<div class="geo-row">
<button id="extract-text" class="geo-btn">🔤 Extract Text (OCR)</button>
</div>
</div>
</div>
<!-- Settings -->
<div class="geo-section">
<div class="geo-section-header">
<span>⚙️ Settings</span>
</div>
<div class="geo-section-content">
<div class="geo-row">
<label>
<input type="checkbox" id="auto-reveal" ${settings.autoReveal ? 'checked' : ''}>
Auto-reveal answers
</label>
</div>
<div class="geo-row">
<label>
<input type="checkbox" id="show-on-map-setting" ${settings.showOnMap ? 'checked' : ''}>
Show answer on map
</label>
</div>
<div class="geo-row">
<label style="display:block; margin-bottom: 5px;">Google Maps API Key:</label>
<input type="text" id="api-key-input" placeholder="Enter API key for metadata"
value="${googleMapsKey}" style="width: 100%; padding: 5px;">
<button id="save-api-key" class="geo-btn" style="margin-top: 5px;">💾 Save Key</button>
</div>
</div>
</div>
<!-- Info -->
<div class="geo-section">
<div class="geo-section-header">
<span>ℹ️ Features</span>
</div>
<div class="geo-section-content" style="font-size: 11px; line-height: 1.4;">
<p><strong>Working:</strong></p>
<ul style="margin: 5px 0; padding-left: 20px;">
<li>✅ Answer coordinate extraction</li>
<li>✅ Auto-guess perfect location</li>
<li>✅ Google Maps integration</li>
<li>✅ Street View metadata (with API key)</li>
</ul>
<p><strong>Requires API key:</strong></p>
<ul style="margin: 5px 0; padding-left: 20px;">
<li>📸 Street View capture date</li>
<li>📸 Panorama ID & exact coords</li>
</ul>
<p><strong>External services needed:</strong></p>
<ul style="margin: 5px 0; padding-left: 20px;">
<li>🔍 OCR (use Google Cloud Vision)</li>
<li>🖼 Reverse image search (use TinEye/Google)</li>
</ul>
</div>
</div>
</div>
`;
// Add styles
const style = document.createElement('style');
style.textContent = `
#geo-god-mode {
position: fixed;
top: 10px;
right: 10px;
width: 350px;
background: rgba(30, 30, 30, 0.98);
border: 2px solid #4CAF50;
border-radius: 12px;
color: #fff;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Arial, sans-serif;
z-index: 999999;
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.5);
max-height: 90vh;
overflow-y: auto;
}
.geo-header {
background: linear-gradient(135deg, #4CAF50 0%, #45a049 100%);
padding: 12px 15px;
display: flex;
justify-content: space-between;
align-items: center;
cursor: move;
border-radius: 10px 10px 0 0;
font-weight: 600;
font-size: 14px;
}
#geo-minimize {
background: rgba(255, 255, 255, 0.2);
border: none;
color: #fff;
width: 28px;
height: 28px;
border-radius: 50%;
cursor: pointer;
font-size: 18px;
line-height: 1;
transition: all 0.2s;
}
#geo-minimize:hover {
background: rgba(255, 255, 255, 0.3);
transform: scale(1.1);
}
.geo-content {
padding: 15px;
max-height: calc(90vh - 50px);
overflow-y: auto;
}
.geo-section {
margin-bottom: 12px;
background: rgba(255, 255, 255, 0.05);
border-radius: 8px;
overflow: hidden;
}
.geo-section-header {
background: rgba(76, 175, 80, 0.2);
padding: 8px 12px;
cursor: pointer;
user-select: none;
font-size: 13px;
font-weight: 500;
transition: background 0.2s;
}
.geo-section-header:hover {
background: rgba(76, 175, 80, 0.3);
}
.geo-section-content {
padding: 12px;
}
.answer-box, .metadata-box {
background: rgba(0, 0, 0, 0.3);
padding: 10px;
border-radius: 6px;
margin-bottom: 10px;
font-size: 12px;
line-height: 1.6;
}
.answer-box p, .metadata-box p {
margin: 5px 0;
}
.geo-row {
margin-bottom: 8px;
display: flex;
gap: 8px;
}
.geo-btn {
background: linear-gradient(135deg, #4CAF50 0%, #45a049 100%);
border: none;
color: #fff;
padding: 8px 12px;
border-radius: 6px;
cursor: pointer;
font-size: 12px;
font-weight: 500;
transition: all 0.2s;
flex: 1;
}
.geo-btn:hover:not(:disabled) {
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(76, 175, 80, 0.4);
}
.geo-btn:disabled {
opacity: 0.5;
cursor: not-allowed;
}
.geo-notification {
position: fixed;
top: 80px;
right: 10px;
background: rgba(76, 175, 80, 0.95);
color: #fff;
padding: 12px 20px;
border-radius: 8px;
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.3);
z-index: 1000000;
animation: slideIn 0.3s ease-out;
font-size: 13px;
}
@keyframes slideIn {
from { transform: translateX(400px); opacity: 0; }
to { transform: translateX(0); opacity: 1; }
}
input[type="checkbox"] {
margin-right: 8px;
cursor: pointer;
}
label {
font-size: 12px;
cursor: pointer;
user-select: none;
}
/* Scrollbar styling */
.geo-content::-webkit-scrollbar {
width: 6px;
}
.geo-content::-webkit-scrollbar-track {
background: rgba(255, 255, 255, 0.05);
}
.geo-content::-webkit-scrollbar-thumb {
background: rgba(76, 175, 80, 0.5);
border-radius: 3px;
}
.geo-content::-webkit-scrollbar-thumb:hover {
background: rgba(76, 175, 80, 0.7);
}
`;
document.head.appendChild(style);
document.body.appendChild(gui);
// Make draggable
makeDraggable(gui);
// Add event listeners
setupEventListeners();
}
function setupEventListeners() {
// Minimize button
document.getElementById('geo-minimize').addEventListener('click', function() {
const content = document.querySelector('.geo-content');
if (content.style.display === 'none') {
content.style.display = 'block';
this.textContent = '−';
} else {
content.style.display = 'none';
this.textContent = '+';
}
});
// Copy coordinates
document.getElementById('copy-coords').addEventListener('click', function() {
if (currentAnswer) {
const coords = `${currentAnswer.lat}, ${currentAnswer.lng}`;
navigator.clipboard.writeText(coords);
showNotification('Coordinates copied! 📋');
}
});
// Open in Google Maps
document.getElementById('open-google-maps').addEventListener('click', function() {
if (currentAnswer) {
const url = `https://www.google.com/maps?q=${currentAnswer.lat},${currentAnswer.lng}&ll=${currentAnswer.lat},${currentAnswer.lng}&z=15`;
window.open(url, '_blank');
}
});
// Auto guess
document.getElementById('auto-guess').addEventListener('click', function() {
if (currentAnswer) {
autoGuess();
}
});
// Show on map
document.getElementById('show-on-map').addEventListener('click', function() {
if (currentAnswer) {
showAnswerOnMap();
}
});
// Reverse search
document.getElementById('reverse-search').addEventListener('click', function() {
reverseImageSearch();
});
// Extract text
document.getElementById('extract-text').addEventListener('click', function() {
showNotification('OCR feature requires Google Cloud Vision API integration');
});
// Settings
document.getElementById('auto-reveal').addEventListener('change', function() {
settings.autoReveal = this.checked;
GM_setValue('auto_reveal', this.checked);
});
document.getElementById('show-on-map-setting').addEventListener('change', function() {
settings.showOnMap = this.checked;
GM_setValue('show_on_map', this.checked);
});
// API key save
document.getElementById('save-api-key').addEventListener('click', function() {
const key = document.getElementById('api-key-input').value.trim();
googleMapsKey = key;
GM_setValue('google_maps_key', key);
showNotification('API key saved! 💾');
if (key && currentAnswer) {
fetchStreetViewMetadata();
}
});
}
function updateGUI() {
const answerDisplay = document.getElementById('answer-display');
const metadataDisplay = document.getElementById('metadata-display');
if (currentAnswer) {
answerDisplay.innerHTML = `
<p><strong>📍 Latitude:</strong> ${currentAnswer.lat.toFixed(6)}</p>
<p><strong>📍 Longitude:</strong> ${currentAnswer.lng.toFixed(6)}</p>
${currentAnswer.panoId ? `<p><strong>🆔 Pano ID:</strong> <code style="font-size:10px">${currentAnswer.panoId}</code></p>` : ''}
${currentAnswer.heading !== null ? `<p><strong>🧭 Heading:</strong> ${currentAnswer.heading}°</p>` : ''}
`;
// Enable buttons
document.getElementById('copy-coords').disabled = false;
document.getElementById('open-google-maps').disabled = false;
document.getElementById('auto-guess').disabled = false;
// Update metadata if available
if (currentAnswer.metadata) {
metadataDisplay.innerHTML = `
<p><strong>📸 Capture Date:</strong> ${currentAnswer.metadata.date}</p>
<p><strong>🆔 Pano ID:</strong> <code style="font-size:10px">${currentAnswer.metadata.panoId}</code></p>
<p><strong>📍 Exact Location:</strong> ${currentAnswer.metadata.exactLat.toFixed(6)}, ${currentAnswer.metadata.exactLng.toFixed(6)}</p>
<p><small>${currentAnswer.metadata.copyright}</small></p>
`;
}
}
}
function autoGuess() {
showNotification('Looking for guess map...');
// Try to find and click on the map at the correct location
setTimeout(() => {
// This would require interacting with GeoGuessr's map
// The exact implementation depends on their current map structure
showNotification('Auto-guess feature requires map interaction - use "Show on Map" instead');
}, 500);
}
function showAnswerOnMap() {
if (!currentAnswer) return;
// Try to find GeoGuessr's map and add a marker
showNotification('Map marker feature coming soon - use "Open in Google Maps" for now');
}
function reverseImageSearch() {
// Capture current Street View image and open reverse search
const streetViewContainer = document.querySelector('[data-qa="panorama"]') ||
document.querySelector('canvas');
if (streetViewContainer) {
// Open Google reverse image search in new tab
const url = 'https://images.google.com/';
window.open(url, '_blank');
showNotification('Opening Google Images - use the camera icon to upload screenshot');
} else {
showNotification('Could not find Street View container');
}
}
function showNotification(message) {
const notif = document.createElement('div');
notif.className = 'geo-notification';
notif.textContent = message;
document.body.appendChild(notif);
setTimeout(() => {
notif.style.animation = 'slideIn 0.3s ease-out reverse';
setTimeout(() => notif.remove(), 300);
}, 3000);
}
function makeDraggable(element) {
let pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0;
const header = element.querySelector('.geo-header');
header.onmousedown = dragMouseDown;
function dragMouseDown(e) {
e.preventDefault();
pos3 = e.clientX;
pos4 = e.clientY;
document.onmouseup = closeDragElement;
document.onmousemove = elementDrag;
}
function elementDrag(e) {
e.preventDefault();
pos1 = pos3 - e.clientX;
pos2 = pos4 - e.clientY;
pos3 = e.clientX;
pos4 = e.clientY;
element.style.top = (element.offsetTop - pos2) + "px";
element.style.left = (element.offsetLeft - pos1) + "px";
element.style.right = 'auto';
}
function closeDragElement() {
document.onmouseup = null;
document.onmousemove = null;
}
}
})();