CheatGuessr | GeoGuessr Cheat

Extremely customizable GeoGuessr cheating client. Click 3 to open the settings menu.

目前為 2025-01-30 提交的版本,檢視 最新版本

// ==UserScript==
// @name         CheatGuessr | GeoGuessr Cheat
// @namespace    http://tampermonkey.net/
// @version      1.0
// @description  Extremely customizable GeoGuessr cheating client. Click 3 to open the settings menu.
// @author       CheatGuessr
// @match        https://www.geoguessr.com/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=geoguessr.com
// @grant        GM_webRequest
// @license      GNU AGPLv3
// ==/UserScript==

let globalCoordinates = {
    lat: 0,
    lng: 0
};

let googleMapsIframe = null;
let settingsModal = null;

const DEFAULT_SETTINGS = {
    keybinds: {
        toggleMap: '1',
        newTab: '2',
        settings: '3',
        detailedLocation: '4',
        pinpoint: '5',
        nearbypinpoint: '6'
    },
    mapPosition: 'top-left',
    mapSize: {
        width: 400,
        height: 300
    },
    blockAds: true
};

var originalOpen = XMLHttpRequest.prototype.open;
XMLHttpRequest.prototype.open = function(method, url) {
    if (method.toUpperCase() === 'POST' &&
        (url.startsWith('https://maps.googleapis.com/$rpc/google.internal.maps.mapsjs.v1.MapsJsInternalService/GetMetadata') ||
            url.startsWith('https://maps.googleapis.com/$rpc/google.internal.maps.mapsjs.v1.MapsJsInternalService/SingleImageSearch'))) {

        this.addEventListener('load', function () {
            let interceptedResult = this.responseText;
            const pattern = /-?\d+\.\d+,-?\d+\.\d+/g;
            let match = interceptedResult.match(pattern)[0];
            let split = match.split(",");

            let lat = Number.parseFloat(split[0]);
            let lng = Number.parseFloat(split[1]);

            globalCoordinates.lat = lat;
            globalCoordinates.lng = lng;
        });
    }
    return originalOpen.apply(this, arguments);
};

async function fetchLocationDetails(lat, lng) {
    try {
        const response = await fetch(`https://nominatim.openstreetmap.org/reverse?format=jsonv2&lat=${lat}&lon=${lng}`);
        if (!response.ok) {
            throw new Error('Failed to fetch location details');
        }
        const data = await response.json();
        const { address } = data;
        const locationDetails = `
            Area: ${address.neighbourhood || address.suburb || address.hamlet || 'N/A'}
            City: ${address.city || address.town || address.village || 'N/A'}
            State: ${address.state || 'N/A'}
            Country: ${address.country || 'N/A'}
        `;
        alert(locationDetails);
    } catch (error) {
        alert('Could not fetch location details: ' + error.message);
    }
}

function placeMarker(safeMode) {
    let { lat, lng } = globalCoordinates;

    if (safeMode) {
        const sway = [Math.random() > 0.5, Math.random() > 0.5];
        const multiplier = Math.random() * 4;
        const horizontalAmount = Math.random() * multiplier;
        const verticalAmount = Math.random() * multiplier;
        sway[0] ? lat += verticalAmount : lat -= verticalAmount;
        sway[1] ? lng += horizontalAmount : lat -= horizontalAmount;
    }

    let element = document.querySelectorAll('[class^="guess-map_canvas__"]')[0];
    if (!element) {
        placeMarkerStreaks();
        return;
    }

    const latLngFns = {
        latLng: {
            lat: () => lat,
            lng: () => lng,
        }
    };

    const reactKeys = Object.keys(element);
    const reactKey = reactKeys.find(key => key.startsWith("__reactFiber$"));
    const elementProps = element[reactKey];
    const mapElementClick = elementProps.return.return.memoizedProps.map.__e3_.click;
    const mapElementPropKey = Object.keys(mapElementClick)[0];
    const mapClickProps = mapElementClick[mapElementPropKey];
    const mapClickPropKeys = Object.keys(mapClickProps);

    for (let i = 0; i < mapClickPropKeys.length; i++) {
        if (typeof mapClickProps[mapClickPropKeys[i]] === "function") {
            mapClickProps[mapClickPropKeys[i]](latLngFns);
        }
    }
}

function placeMarkerStreaks() {
    let { lat, lng } = globalCoordinates;
    let element = document.getElementsByClassName("region-map_mapCanvas__0dWlf")[0];
    if (!element) {
        return;
    }
    const reactKeys = Object.keys(element);
    const reactKey = reactKeys.find(key => key.startsWith("__reactFiber$"));
    const elementProps = element[reactKey];
    const mapElementClick = elementProps.return.return.memoizedProps.map.__e3_.click;
    const mapElementClickKeys = Object.keys(mapElementClick);
    const functionString = "(e.latLng.lat(),e.latLng.lng())}";
    const latLngFn = {
        latLng: {
            lat: () => lat,
            lng: () => lng,
        }
    };

    for (let i = 0; i < mapElementClickKeys.length; i++) {
        const curr = Object.keys(mapElementClick[mapElementClickKeys[i]]);
        let func = curr.find(l => typeof mapElementClick[mapElementClickKeys[i]][l] === "function");
        let prop = mapElementClick[mapElementClickKeys[i]][func];
        if (prop && prop.toString().slice(5) === functionString) {
            prop(latLngFn);
        }
    }
}

function mapsFromCoords() {
    const { lat, lng } = globalCoordinates;
    if (!lat || !lng) {
        return;
    }

    window.open(`https://maps.google.com/?output=embed&q=${lat},${lng}&ll=${lat},${lng}&z=5`);
}

function toggleSettingsModal() {
    if (settingsModal) {
        settingsModal.backdrop.remove();
        settingsModal.modal.remove();
        settingsModal = null;
        return;
    }

    const backdrop = document.createElement('div');
    backdrop.className = 'settings-backdrop';

    const modal = document.createElement('div');
    modal.className = 'settings-modal';
    modal.innerHTML = `
        <h2 style="margin-bottom: 20px">GeoGuessr Helper Settings</h2>
        <div class="settings-grid">
            <div class="settings-section">
                <h3>Keybinds</h3>
                <div class="settings-row">
                    <label>Toggle Map Key</label>
                    <input type="text" class="settings-input" id="toggleMapKey" value="${settings.keybinds.toggleMap}">
                </div>
                <div class="settings-row">
                    <label>New Tab Key</label>
                    <input type="text" class="settings-input" id="newTabKey" value="${settings.keybinds.newTab}">
                </div>
                <div class="settings-row">
                    <label>Settings Key</label>
                    <input type="text" class="settings-input" id="settingsKey" value="${settings.keybinds.settings}">
                </div>
                <div class="settings-row">
                    <label>Detailed Location Key</label>
                    <input type="text" class="settings-input" id="detailedLocationKey" value="${settings.keybinds.detailedLocation}">
                </div>
                <div class="settings-row">
                    <label>Score 5000 Points</label>
                    <input type="text" class="settings-input" id="pinpointKey" value="${settings.keybinds.pinpoint}">
                </div>
                <div class="settings-row">
                    <label>Score Between 4500-5000 Points</label>
                    <input type="text" class="settings-input" id="nearbyPinpointKey" value="${settings.keybinds.nearbypinpoint}">
                </div>
            </div>
            <div class="settings-section">
                <h3>Map Settings</h3>
                <div class="settings-row">
                    <label>Map Position</label>
                    <select class="settings-input" id="mapPosition">
                        <option value="top-left" ${settings.mapPosition === 'top-left' ? 'selected' : ''}>Top Left</option>
                        <option value="top-right" ${settings.mapPosition === 'top-right' ? 'selected' : ''}>Top Right</option>
                        <option value="bottom-left" ${settings.mapPosition === 'bottom-left' ? 'selected' : ''}>Bottom Left</option>
                        <option value="bottom-right" ${settings.mapPosition === 'bottom-right' ? 'selected' : ''}>Bottom Right</option>
                    </select>
                </div>
                <div class="settings-row">
                    <label>Map Width (px)</label>
                    <input type="number" class="settings-input" id="mapWidth" value="${settings.mapSize.width}">
                </div>
                <div class="settings-row">
                    <label>Map Height (px)</label>
                    <input type="number" class="settings-input" id="mapHeight" value="${settings.mapSize.height}">
                </div>
            </div>
        </div>
        <div class="settings-section" style="margin-top: 20px">
            <h3>Additional Settings</h3>
            <div class="settings-row">
                <label>
                    <input type="checkbox" id="blockAds" ${settings.blockAds ? 'checked' : ''}>
                    Block Advertisements
                </label>
            </div>
        </div>
        <div style="text-align: right; margin-top: 20px">
            <button class="settings-button" id="closeSettings">Cancel</button>
            <button class="settings-button" id="saveSettings">Save</button>
        </div>
    `;

    document.body.appendChild(backdrop);
    document.body.appendChild(modal);

    settingsModal = { backdrop, modal };

    document.getElementById('saveSettings').onclick = () => {
        settings.keybinds.toggleMap = document.getElementById('toggleMapKey').value;
        settings.keybinds.newTab = document.getElementById('newTabKey').value;
        settings.keybinds.settings = document.getElementById('settingsKey').value;
        settings.keybinds.detailedLocation = document.getElementById('detailedLocationKey').value;
        settings.keybinds.pinpoint = document.getElementById('pinpointKey').value;
        settings.keybinds.nearbypinpoint = document.getElementById('nearbyPinpointKey').value;
        settings.mapPosition = document.getElementById('mapPosition').value;
        settings.mapSize.width = parseInt(document.getElementById('mapWidth').value);
        settings.mapSize.height = parseInt(document.getElementById('mapHeight').value);
        settings.blockAds = document.getElementById('blockAds').checked;

        saveSettings();
        toggleSettingsModal();
    };

    document.getElementById('closeSettings').onclick = toggleSettingsModal;
}

function toggleGoogleMapsIframe(location) {
    if (!location) return;

    if (googleMapsIframe) {
        googleMapsIframe.remove();
        googleMapsIframe = null;
        return;
    }

    try {
        const container = document.createElement('div');
        container.className = 'google-maps-iframe';

        const closeBtn = document.createElement('button');
        closeBtn.className = 'close-button';
        closeBtn.textContent = '×';
        closeBtn.onclick = () => {
            container.remove();
            googleMapsIframe = null;
        };

        const iframe = document.createElement('iframe');
        iframe.width = '100%';
        iframe.height = '100%';
        iframe.style.border = 'none';
        iframe.src = "https://www.google.com/maps?q=" + location.lat + "," + location.lng + "&z=18&output=embed";

        container.appendChild(closeBtn);
        container.appendChild(iframe);
        document.body.appendChild(container);
        googleMapsIframe = container;
        updateMapPosition();
    } catch (error) {
        console.error('Error creating iframe:', error);
    }
}

function updateMapPosition() {
    if (!googleMapsIframe) return;

    const pos = settings.mapPosition.split('-');
    googleMapsIframe.style.top = pos[0] === 'top' ? '10px' : 'auto';
    googleMapsIframe.style.bottom = pos[0] === 'bottom' ? '10px' : 'auto';
    googleMapsIframe.style.left = pos[1] === 'left' ? '10px' : 'auto';
    googleMapsIframe.style.right = pos[1] === 'right' ? '10px' : 'auto';
    googleMapsIframe.style.width = settings.mapSize.width + 'px';
    googleMapsIframe.style.height = settings.mapSize.height + 'px';
}

let onKeyDown = (e) => {
    switch (e.key) {
        case settings.keybinds.toggleMap:
            e.stopImmediatePropagation();
            toggleGoogleMapsIframe(globalCoordinates);
            break;
        case settings.keybinds.newTab:
            e.stopImmediatePropagation();
            mapsFromCoords();
            break;
        case settings.keybinds.settings:
            e.stopImmediatePropagation();
            toggleSettingsModal();
            break;
        case settings.keybinds.detailedLocation:
            e.stopImmediatePropagation();
            const { lat, lng } = globalCoordinates;
            if (!lat || !lng) {
                alert('Coordinates not yet available!');
            } else {
                fetchLocationDetails(lat, lng);
            }
            break;
        case settings.keybinds.pinpoint:
            e.stopImmediatePropagation();
            placeMarker(true);
            break;
        case settings.keybinds.nearbypinpoint:
            e.stopImmediatePropagation();
            placeMarker(false);
            break;
    }
};

document.addEventListener("keydown", onKeyDown);

QingJ © 2025

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