Undetectable | Press Tab to open the settings menu
// ==UserScript==
// @name OpenGuessr Legit Cheat
// @namespace https://greasyfork.org/en/users/1588266-woggieboost
// @version 2.0
// @description Undetectable | Press Tab to open the settings menu
// @author woggieboost
// @license MIT
// @match *://*.openguessr.com/*
// @grant GM_setValue
// @grant GM_getValue
// @grant GM_xmlhttpRequest
// @connect discord.com
// @connect nominatim.openstreetmap.org
// @icon https://www.google.com/s2/favicons?sz=32&domain=openguessr.com
// ==/UserScript==
(function () {
'use strict';
// ========== Common Config ==========
const DEFAULT_HOTKEYS = {
openPanel: 'tab',
sendToDiscord: 'q',
notify: 'g',
toggleMarker: 'x',
toggleInfo: 'v',
};
const DEFAULT_TOGGLES = {
sendToDiscord: true,
autoSend: false,
notify: true,
autoNotify: false,
toggleMarker: true,
toggleInfo: true,
};
// ========== Global State ==========
let state = {
notificationPermission: Notification.permission,
streetView: null,
gameMap: null,
mapMarker: null,
currentAddress: null,
isInfoDisplayed: false,
lastCoord: null,
originalNickname: null,
originalFlag: null,
logoElement: null,
hotkeys: GM_getValue('hotkeys', DEFAULT_HOTKEYS),
featureToggles: GM_getValue('featureToggles', DEFAULT_TOGGLES),
};
// Initialize missing hotkeys
if (!state.hotkeys.openPanel) {
state.hotkeys.openPanel = 'tab';
GM_setValue('hotkeys', state.hotkeys);
}
// Initialize missing toggles
if (state.featureToggles.autoSend === undefined) {
state.featureToggles.autoSend = false;
state.featureToggles.autoNotify = false;
GM_setValue('featureToggles', state.featureToggles);
}
// ========== Utility Functions ==========
function saveHotkeys() {
GM_setValue('hotkeys', state.hotkeys);
}
function saveFeatureToggles() {
GM_setValue('featureToggles', state.featureToggles);
}
function getMainDomain() {
const parts = window.location.hostname.split(".");
if (parts.length > 2) {
return parts.slice(-2).join(".");
}
return window.location.hostname;
}
function requestNotificationPermission() {
if (state.notificationPermission === 'default') {
Notification.requestPermission().then(permission => {
state.notificationPermission = permission;
});
}
}
function sendNotification(title, body) {
if (state.notificationPermission === 'granted') {
new Notification(title, {
body,
icon: `https://www.google.com/s2/favicons?sz=32&domain=${getMainDomain()}`
});
}
}
function throttle(fn, wait) {
let lastTime = 0;
let pendingPromise = null;
return function (...args) {
const now = Date.now();
if (now - lastTime >= wait) {
lastTime = now;
pendingPromise = Promise.resolve(fn.apply(this, args));
return pendingPromise;
}
return pendingPromise;
};
}
function debounce(fn, wait) {
let timeout;
return function (...args) {
clearTimeout(timeout);
timeout = setTimeout(() => fn.apply(this, args), wait);
};
}
// ========== Nominatim Service ==========
function _getAddress(lat, lng) {
if (state.lastCoord && state.lastCoord === [lat, lng]) {
return Promise.resolve(state.currentAddress);
}
return new Promise((resolve, reject) => {
const url = `https://nominatim.openstreetmap.org/reverse?lat=${lat}&lon=${lng}&format=json&accept-language=en`;
GM_xmlhttpRequest({
method: 'GET',
url,
headers: { 'Accept': 'application/json' },
onload: res => {
try {
resolve(JSON.parse(res.responseText));
} catch (err) {
reject(err);
}
},
onerror: err => reject(err)
});
});
}
const getAddress = throttle(_getAddress, 1000);
// ========== Address Formatting ==========
function formatAddress(address) {
if (!address || !address.address) return null;
const a = address.address;
const parts = [
a.country,
a.state || a.province || a.region || a.county || a.prefecture,
a.city || a.town || a.village,
a.road || a.street,
];
return parts.filter(Boolean).join(', ');
}
// ========== Tile URL Generation ==========
function lonToTile(lng, zoom) {
return Math.floor((lng + 180) / 360 * Math.pow(2, zoom));
}
function latToTile(lat, zoom) {
return Math.floor(
(1 - Math.log(Math.tan(lat * Math.PI / 180) + 1 / Math.cos(lat * Math.PI / 180)) / Math.PI) / 2
* Math.pow(2, zoom)
);
}
function buildTileUrl(lat, lng) {
const zoom = 6;
const tileX = lonToTile(lng, zoom);
const tileY = latToTile(lat, zoom);
return `https://mapsresources-pa.googleapis.com/v1/tiles?map_id=61449c20e7fc278b&version=sdk-15797339025669136861&pb=!1m5!1m4!1i${zoom}!2i${tileX}!3i${tileY}!4i256!2m3!1e0!2sm!3i773537392!3m13!2sen!3sUS!5e18!12m5!1e68!2m2!1sset!2sRoadmap!4e2!12m3!1e37!2m1!1ssmartmaps!4e0!5m2!1e3!5f2!23i46991212!23i47054750!23i47083502!23i56565656!26m2!1e2!1e3`;
}
// ========== Discord Integration ==========
function createEmbed() {
const { lat, lng } = getCoordinates();
const query = `${lat},${lng}`;
const formattedAddr = formatAddress(state.currentAddress) || getLocationDescription();
return {
title: '✅ Location Tracked',
description: `### [${formattedAddr}](https://maps.google.com/?q=${query}&ll=${query}&z=5)`,
color: 516235,
image: {
url: buildTileUrl(lat, lng)
}
};
}
function sendToDiscord(embed) {
let webhookUrl = GM_getValue('discordWebhookUrl');
if (!webhookUrl) {
webhookUrl = prompt('Discord Webhook:', '');
if (webhookUrl) {
GM_setValue('discordWebhookUrl', webhookUrl);
} else {
alert('You must provide a Discord Webhook URL to continue.');
return;
}
}
const payload = JSON.stringify({
embeds: [embed],
username: 'OpenGuessr Legit Cheat',
avatar_url: `https://www.google.com/s2/favicons?sz=32&domain=${getMainDomain()}`
});
GM_xmlhttpRequest({
method: 'POST',
url: webhookUrl,
headers: { 'Content-Type': 'application/json' },
data: payload,
onload: res => {
if (res.status !== 204) {
console.error('Discord error:', res);
}
},
onerror: err => {
console.error('Request failed:', err);
}
});
}
// Coordinate getter
function getCoordinates() {
try {
const iframe = document.querySelector('#PanoramaIframe') ||
document.querySelector('iframe[src*="location"]') ||
document.querySelector('.iframeWithStreetView');
if (iframe && (iframe.src || iframe.data)) {
const loc = new URL(iframe.src || iframe.data).searchParams.get('location');
if (loc) {
const [lat, lng] = loc.split(',').map(Number);
return { lat, lng };
}
}
} catch (e) {
console.error('Failed to extract coordinates:', e);
}
return { lat: undefined, lng: undefined };
}
// Nickname getter/setter
function getNicknameElement() {
const elements = document.querySelectorAll('.player-name');
return elements[1] || null;
}
function setNickname(text) {
const el = getNicknameElement();
if (el) {
el.textContent = text || getLocationDescription();
}
}
// Flag getter/setter
function getFlagElement() {
let flagEl = document.querySelectorAll('.player-name-wrapper .player-name img')[1];
if (!flagEl) {
const container = getNicknameElement();
if (container) {
flagEl = document.createElement('img');
Object.assign(flagEl, { src: 'https://flagcdn.com/w80/us.png' });
Object.assign(flagEl.style, {
display: 'inline-block',
width: '1.5em',
height: '1em',
marginRight: '0.4em',
verticalAlign: 'middle',
flexShrink: '0',
objectFit: 'cover',
borderRadius: '2px'
});
container.appendChild(flagEl);
}
}
return flagEl;
}
function setFlag(countryCode) {
const el = getFlagElement();
if (el && countryCode) {
el.src = `https://flagcdn.com/48x36/${countryCode.toLowerCase()}.png`;
}
}
// Logo element creator for OpenGuessr/WorldGuessr
function createLogoElement() {
const logoContainer = document.querySelector('.logo');
if (logoContainer) {
const imgEl = logoContainer.querySelector('img');
let imgClass = '';
if (imgEl) {
imgClass = imgEl.className;
imgEl.remove();
}
const newEl = document.createElement('div');
newEl.className = imgClass;
Object.assign(newEl.style, {
width: '480px',
opacity: '0',
fontSize: '20px',
color: '#fff',
fontWeight: 'bold',
textShadow: '#CC302E 2px 0px 0px, #CC302E 1.75517px 0.958851px 0px, #CC302E 1.0806px 1.68294px 0px, #CC302E 0.141474px 1.99499px 0px, #CC302E -0.832294px 1.81859px 0px, #CC302E -1.60229px 1.19694px 0px, #CC302E -1.97998px 0.28224px 0px, #CC302E -1.87291px -0.701566px 0px, #CC302E -1.30729px -1.5136px 0px, #CC302E -0.421592px -1.95506px 0px, #CC302E 0.567324px -1.91785px 0px, #CC302E 1.41734px -1.41108px 0px, #CC302E 1.92034px -0.558831px 0px'
});
logoContainer.appendChild(newEl);
return newEl;
}
return null;
}
// ========== Address Display ==========
async function updateAddressDisplay() {
if (!state.logoElement) {
state.logoElement = createLogoElement();
}
if (state.logoElement) {
if (state.isInfoDisplayed) {
state.logoElement.style.opacity = 1;
state.logoElement.textContent = formatAddress(state.currentAddress);
}
else state.logoElement.style.opacity = 0;
}
}
// ========== Map Marker Management ==========
function spawnRipple(lat, lng) {
if (state.gameMap) {
// Leaflet
const rippleIcon = L.divIcon({
className: '',
html: '<div class="ripple-effect"></div>',
iconSize: [80, 80],
iconAnchor: [40, 40]
});
const rippleMarker = L.marker([lat, lng], {
icon: rippleIcon,
interactive: false
}).addTo(state.gameMap);
setTimeout(() => {
state.gameMap.removeLayer(rippleMarker);
}, 2000);
}
}
function toggleMapMarker() {
if (!state.gameMap) return;
const { lat, lng } = getCoordinates();
if (lat === undefined || lng === undefined) return;
// Leaflet
if (state.mapMarker) {
state.gameMap.removeLayer(state.mapMarker);
state.mapMarker = null;
} else {
const customIcon = L.icon({
iconUrl: 'https://openguessr.com/img/pins/result_pin.png',
iconSize: [35, 35],
iconAnchor: [17.5, 35],
});
state.mapMarker = L.marker([lat, lng], {
icon: customIcon
}).addTo(state.gameMap);
}
spawnRipple(lat, lng);
setTimeout(() => spawnRipple(lat, lng), 300);
setTimeout(() => spawnRipple(lat, lng), 600);
}
// ========== Settings Panel ==========
function createSettingsPanel() {
const panel = document.createElement('div');
panel.id = 'cgx-settings-panel';
panel.style.cssText = `
position: fixed;
top: 30%;
left: 40%;
width: 300px;
background: rgba(25, 25, 25, 0.92);
color: #fff;
padding: 18px;
border-radius: 12px;
z-index: 999999;
font-size: 14px;
backdrop-filter: blur(10px);
border: 1px solid rgba(255,255,255,0.08);
box-shadow: 0 8px 20px rgba(0,0,0,0.35);
animation: cgxFadeIn 0.18s ease-out;
`;
panel.innerHTML = `
<style>
@keyframes cgxFadeIn {
from { opacity: 0; transform: translateY(-6px); }
to { opacity: 1; transform: translateY(0); }
}
.cgx-input {
width: 50px;
text-align: center;
padding: 4px 6px;
border-radius: 6px;
border: 1px solid rgba(255,255,255,0.15);
background: rgba(255,255,255,0.08);
color: #fff;
outline: none;
transition: 0.15s;
}
.cgx-input:focus {
border-color: #4caf50;
background: rgba(255,255,255,0.15);
}
.cgx-btn {
width: 100%;
padding: 8px;
margin-top: 10px;
border-radius: 8px;
border: none;
cursor: pointer;
font-size: 14px;
transition: 0.15s;
}
.cgx-save-btn { background: #4caf50; color: white; }
.cgx-reset-btn { background: #2196f3; color: white; }
.cgx-reset-btn:hover { background: #42a5f5; }
.cgx-btn:disabled {
background: #c0c0c0 !important;
cursor: default;
opacity: 0.9;
}
.cgx-close-btn {
position: absolute;
top: 8px;
right: 10px;
font-size: 18px;
color: #ccc;
cursor: pointer;
transition: 0.15s;
user-select: none;
}
.cgx-close-btn:hover {
color: #cd312f;
transform: scale(1.15);
}
.cgx-toggle {
width: 36px;
height: 18px;
border-radius: 20px;
background: rgba(255,255,255,0.2);
position: relative;
cursor: pointer;
transition: 0.2s;
}
.cgx-toggle::after {
content: "";
position: absolute;
width: 14px;
height: 14px;
top: 2px;
left: 2px;
border-radius: 50%;
background: #fff;
transition: 0.2s;
}
.cgx-toggle.active {
background: #4caf50;
box-shadow: 0 0 6px rgba(76,175,80,0.6);
}
.cgx-toggle.active::after {
left: 20px;
}
</style>
<div class="cgx-close-btn">✕</div>
<div style="font-size:17px; text-align:center; font-weight:bold; margin-bottom:12px;">
Hotkeys Settings
</div>
${Object.keys(DEFAULT_TOGGLES).map(key => `
<div style="margin-bottom:10px; display:flex; align-items:center; justify-content:space-between;">
<div style="display:flex; align-items:center; gap:8px;">
${key !== 'openPanel' ? `<div class="cgx-toggle ${state.featureToggles[key] ? 'active' : ''}" data-toggle="${key}"></div>` : `<div style="width:36px;"></div>`}
<span>${key}</span>
</div>
${['autoSend', 'autoNotify'].includes(key) ? '' : `<input class="cgx-input" type="text" data-key="${key}" value="${state.hotkeys[key] || ''}">`}
</div>
`).join('')}
<button id="cgx-save-hotkeys" class="cgx-btn cgx-save-btn">Save</button>
<button id="cgx-reset-hotkeys" class="cgx-btn cgx-reset-btn">Reset</button>
`;
document.body.appendChild(panel);
// Close button
panel.querySelector('.cgx-close-btn').onclick = () => {
panel.style.display = 'none';
};
// Toggles
panel.querySelectorAll('.cgx-toggle').forEach(toggle => {
toggle.onclick = () => {
const key = toggle.dataset.toggle;
state.featureToggles[key] = !state.featureToggles[key];
toggle.classList.toggle('active');
saveFeatureToggles();
};
});
// Save button
const saveBtn = document.getElementById('cgx-save-hotkeys');
saveBtn.onclick = () => {
panel.querySelectorAll('.cgx-input').forEach(input => {
const key = input.dataset.key;
const val = input.value.trim().toLowerCase();
if (val) state.hotkeys[key] = val;
});
saveHotkeys();
saveFeatureToggles();
saveBtn.textContent = 'Saved';
saveBtn.disabled = true;
setTimeout(() => {
saveBtn.textContent = 'Save';
saveBtn.disabled = false;
}, 1200);
};
// Reset button
const resetBtn = document.getElementById('cgx-reset-hotkeys');
resetBtn.onclick = () => {
state.hotkeys = { ...DEFAULT_HOTKEYS };
saveHotkeys();
panel.querySelectorAll('.cgx-input').forEach(input => {
input.value = state.hotkeys[input.dataset.key];
});
resetBtn.textContent = 'Reset';
resetBtn.disabled = true;
};
// Key input handling
panel.querySelectorAll('.cgx-input').forEach(input => {
input.addEventListener('keydown', e => {
e.preventDefault();
let key = e.key.toLowerCase();
if (['shift', 'control', 'alt', 'meta'].includes(key)) return;
if (key === ' ') key = 'space';
input.value = key;
resetBtn.disabled = false;
});
});
}
function extractStreetView() {
try {
const container = document.querySelector('div[data-qa="panorama"]');
if (!container) return;
const fiberKey = Object.keys(container).find(k => k.startsWith('__reactFiber'));
if (!fiberKey) return;
const fiberNode = container[fiberKey];
state.streetView =
fiberNode.return.return.return.sibling.memoizedProps.panorama ||
fiberNode.return.updateQueue.lastEffect.next.next.next.next.next.next.next.next.next.next.next.deps[0];
} catch (err) {
state.streetView = null;
}
}
function extractMapInstance() {
try {
const mapElement = document.querySelector("[class*='guess-map_canvas']") || document.querySelector('.leaflet-container');
if (!mapElement) return;
const fiberKey = Object.keys(mapElement).find(k => k.startsWith('__reactFiber$'));
if (!fiberKey) return;
const fiberNode = mapElement[fiberKey];
state.gameMap =
fiberNode?.return?.memoizedProps?.map ||
fiberNode?.return?.updateQueue?.lastEffect?.deps?.[0] ||
fiberNode?.child?.memoizedProps?.value?.map;
} catch (err) {
state.gameMap = null;
}
}
// ========== Keyboard Handler ==========
async function handleKeyDown(e) {
if (
e.target.tagName === 'TEXTAREA' ||
e.target.tagName === 'INPUT' ||
e.target.isContentEditable
) return;
const key = e.key.toLowerCase();
const isHotkey =
key === state.hotkeys.sendToDiscord ||
key === state.hotkeys.toggleMarker ||
key === state.hotkeys.toggleInfo ||
key === state.hotkeys.notify ||
key === state.hotkeys.openPanel;
if (!isHotkey) return;
if (key === state.hotkeys.openPanel) {
const panel = document.getElementById('cgx-settings-panel');
if (panel) {
panel.style.display = panel.style.display === 'none' ? 'block' : 'none';
} else {
createSettingsPanel();
}
}
if (key === state.hotkeys.sendToDiscord && state.featureToggles.sendToDiscord) {
sendToDiscord(createEmbed());
}
if (key === state.hotkeys.toggleMarker && state.featureToggles.toggleMarker) {
if(!state.gameMap) extractMapInstance();
toggleMapMarker();
}
if (key === state.hotkeys.toggleInfo && state.featureToggles.toggleInfo) {
state.isInfoDisplayed = !state.isInfoDisplayed;
updateAddressDisplay();
}
if (key === state.hotkeys.notify && state.featureToggles.notify) {
requestNotificationPermission();
sendNotification(
'OpenGuessr Legit Cheat',
formatAddress(state.currentAddress) || getLocationDescription()
);
}
e.stopImmediatePropagation();
e.stopPropagation();
}
document.addEventListener('keydown', handleKeyDown, true);
// Prevent focus on iframe
setInterval(() => {
if (document.activeElement instanceof HTMLIFrameElement || document.activeElement instanceof Object) {
window.focus();
document.body.focus();
}
}, 200);
// Monitor coordinate changes
const coordObserver = new MutationObserver(() => {
const streetViewContainer = document.getElementById('panorama-iframe') ||
document.getElementById('streetview') ||
document.querySelector('iframe[src*="location"]') ||
document.querySelector('.iframeWithStreetView');
if (streetViewContainer) {
const intervalId = setInterval(async () => {
const { lat, lng } = getCoordinates();
if (lat && lng) {
if (state.lastCoord != [lat, lng]) {
state.lastCoord = [lat, lng];
state.currentAddress = await getAddress(lat, lng);
updateAddressDisplay();
if (state.mapMarker) {
state.mapMarker.setLatLng([lat, lng]);
}
}
}
}, 500);
coordObserver.disconnect();
}
});
coordObserver.observe(document.body, { childList: true, subtree: true });
// Initialize Leaflet map
const mapObserver = new MutationObserver(() => {
try {
if (L && L.map) {
const originalSetView = L.Map.prototype.setView;
L.Map.prototype.setView = function (...args) {
state.gameMap = this;
return originalSetView.apply(this, args);
};
mapObserver.disconnect();
}
} catch (err) {
}
});
mapObserver.observe(document.body, { childList: true, subtree: true });
// ========== Styles ==========
const style = document.createElement('style');
style.innerHTML = `
.gameplayAdArea, .venatus-ad, #worldguessr_gameui_ad, #worldguessr_home_ad {
display: none !important;
visibility: hidden !important;
opacity: 0 !important;
}
.gmap-ripple {
position: absolute;
width: 80px;
height: 80px;
pointer-events: none;
}
.gmap-ripple::before,
.gmap-ripple::after {
content: "";
position: absolute;
left: 0%;
top: 0%;
width: 80px;
height: 80px;
border-radius: 50%;
transform: translate(-50%, -50%) scale(0.6);
background: radial-gradient(
circle,
rgba(255, 80, 80, 0.6) 0%,
rgba(255, 80, 80, 0.45) 40%,
rgba(255, 80, 80, 0.3) 70%,
transparent 100%
);
}
.gmap-ripple::before {
animation: gmapRipple 2s ease-out;
}
.gmap-ripple::after {
animation: gmapRipple 2s ease-out 0.4s;
}
.ripple-effect {
position: absolute;
width: 80px;
height: 80px;
}
.ripple-effect::before,
.ripple-effect::after {
content: "";
position: absolute;
left: 50%;
top: 50%;
width: 80px;
height: 80px;
border-radius: 50%;
background: radial-gradient(
circle,
rgba(255, 60, 60, 0.6) 0%,
rgba(255, 60, 60, 0.45) 35%,
rgba(255, 60, 60, 0.3) 65%,
transparent 100%
);
transform: translate(-50%, -50%) scale(1);
}
.ripple-effect::before {
animation: ripple 2s ease-out;
}
.ripple-effect::after {
animation: ripple 2s ease-out 0.4s;
}
@keyframes gmapRipple {
0% {
transform: translate(-50%, -50%) scale(0.8);
opacity: 0.7;
}
100% {
transform: translate(-50%, -50%) scale(8);
opacity: 0;
}
}
@keyframes ripple {
0% {
transform: translate(-50%, -50%) scale(0.8);
opacity: 0.6;
}
100% {
transform: translate(-50%, -50%) scale(8);
opacity: 0;
}
}
`;
document.head.appendChild(style);
})();