GeoGuessr Custom Maps

using modified maps in geoguessr games

Устаревшая версия за 21.09.2024. Перейдите к последней версии.

Чтобы установить этот скрипт, вы сначала должны установить расширение браузера, например Tampermonkey, Greasemonkey или Violentmonkey.

Для установки этого скрипта вам необходимо установить расширение, такое как Tampermonkey.

Чтобы установить этот скрипт, вы сначала должны установить расширение браузера, например Tampermonkey или Violentmonkey.

Чтобы установить этот скрипт, вы сначала должны установить расширение браузера, например Tampermonkey или Userscripts.

Чтобы установить этот скрипт, сначала вы должны установить расширение браузера, например Tampermonkey.

Чтобы установить этот скрипт, вы должны установить расширение — менеджер скриптов.

(у меня уже есть менеджер скриптов, дайте мне установить скрипт!)

Чтобы установить этот стиль, сначала вы должны установить расширение браузера, например Stylus.

Чтобы установить этот стиль, сначала вы должны установить расширение браузера, например Stylus.

Чтобы установить этот стиль, сначала вы должны установить расширение браузера, например Stylus.

Чтобы установить этот стиль, сначала вы должны установить расширение — менеджер стилей.

Чтобы установить этот стиль, сначала вы должны установить расширение — менеджер стилей.

Чтобы установить этот стиль, сначала вы должны установить расширение — менеджер стилей.

(у меня уже есть менеджер стилей, дайте мне установить скрипт!)

// ==UserScript==
// @name         GeoGuessr Custom Maps
// @namespace    https://greasyfork.org/users/1179204
// @description  using modified maps in geoguessr games
// @version      1.0.8
// @author       KaKa
// @license      BSD
// @match        *://www.geoguessr.com/*
// @require      https://update.greasyfork.org/scripts/502813/1423193/Geoguessr%20Tag.js
// @icon         https://www.svgrepo.com/show/392367/interaction-interface-layer-layers-location-map.svg
// ==/UserScript==

(function() {

    /*=========================================================================Modifiy your guess map here==================================================================================*/

    let customOptions={

        Language:'en',                                  //en,zh,ja,fr,de,es

        Google_StreetView_Layer_Lines_Style:'Default',   // More styles see below

        Google_StreetView_Layer_Shortcut:'V',

        Google_Labels_Layer_Shortcut:'G',

        Google_Terrain_Layer_Shortcut:'T',

        Google_Satellite_Layer_Shortcut:'B',

        Apple_StreetView_Layer_Shortcut:'P',

        Yandex_StreetView_Layer_Shortcut:'Y',

        OpenWeather_Shortcut:'Q',

        OpenWeather_Style:'radar',                      //'radar': Global Precipitation;  'CL':Cloud;  'APM':Pressure;  'TA2'Temperature;  'WS10':Wind Speed;

        OpenWeather_Date:'now',                        // foramt:yyyy-mm-dd, less than one week ago

        Bing_Maps_Style:'r',                           // 'a':satellite(without labels);  'h':hybrid;  'r':roadmap,'sre':terrain

        Map_Tiler_Style:'basic',                       //basic,satellite,bright,landscape,ocean,outdoor,topo,streets,dataviz

        Carto_Style:'light_all',                       //light_all,dark_all

        Thunderforest_Style:'spinal-map'}              //spinal-map,landscape,outdoors,atlas,transport,

    let tileServices=["Google_Maps","OpenStreetMap","Bing_Maps","Map_Tiler","Thunderforest","Carto","Yandex_Maps","Petal_Maps"]

    let colorOptions={

        Default:['1098ad','99e9f2'],

        Crimson:['f03e3e','ffc9c9'],

        Deep_Pink:['d6336c','fcc2d7'],

        Blue_Violet:['ae3ec9','eebefa'],

        Slate_Blue:['7048e8','d0bfff'],

        Royal_Blue:['4263eb','bac8ff'],

        Dodger_Blue: ['1c7ed6','a5d8ff'],

        Sea_Green:['0ca678','96f2d7'],

        Lime_Green:['37b24d','b2f2bb'],

        OliveDrab:['74b816','d8f5a2'],

        Orange:['f59f00','ffec99'],

        Dark_Orange:['f76707','ffd8a8'],

        Brown:['bd5f1b','f7ca9e'],
    }

    /*======================================================================================================================================================================================*/


    let currentMapType='roadmap',currentLayers=[],isGoogleDisplay=true,isSV,opacityControl

    const openWeatherBaseURL = "https://g.sat.owm.io/vane/2.0/weather";
    const radarURL = `https://b.sat.owm.io/maps/2.0/radar/{z}/{x}/{y}?appid=9de243494c0b295cca9337e1e96b00e2&day=${getNow(customOptions.OpenWeather_Date)}`;

    const openWeatherURL = (customOptions.OpenWeather_Style === 'radar')
    ? radarURL
    : `${openWeatherBaseURL}/${customOptions.OpenWeather_Style}/{z}/{x}/{y}?appid=9de243494c0b295cca9337e1e96b00e2&&date=${getTimestamp(customOptions.OpenWeather_Date)}&fill_bound=true`;

    let tileUrls = {
        Petal_Maps: `https://maprastertile-dra.dbankcdn.com/display-service/v1/online-render/getTile/24.07.06.10/{z}/{x}/{y}/?language=${customOptions.Language}&p=46&scale=1&mapType=ROADMAP&presetStyleId=standard&key=CgB6e3x91JxUZ4Ow3JZYVG6r9c9U7rH4ameNQdauHVaVBYGWwy8ueadAtqjs6Yl2z3OwymAEx3JR83vpgPzv4nuC`,
        OpenStreetMap: "https://tile.openstreetmap.org/{z}/{x}/{y}.png",
        Map_Tiler:`https://api.maptiler.com/maps/${customOptions.Map_Tiler_Style}-v2/256/{z}/{x}/{y}.png?key=0epLOAjD7fw17tghcyee`,
        Thunderforest:`https://b.tile.thunderforest.com/${customOptions.Thunderforest_Style}/{z}/{x}/{y}@2x.png?apikey=6a53e8b25d114a5e9216df5bf9b5e9c8`,
        Carto:`https://cartodb-basemaps-3.global.ssl.fastly.net/${customOptions.Carto_Style}/{z}/{x}/{y}.png`,
        Google_StreetView:`https://maps.googleapis.com/maps/vt?pb=%211m5%211m4%211i{z}%212i{x}%213i{y}%214i256%212m8%211e2%212ssvv%214m2%211scc%212s*211m3*211e2*212b1*213e2*212b1*214b1%214m2%211ssvl%212s*212b1%213m17%212sen%213sUS%215e18%2112m4%211e68%212m2%211sset%212sRoadmap%2112m3%211e37%212m1%211ssmartmaps%2112m4%211e26%212m2%211sstyles%212ss.e%3Ag.f%7Cp.c%3A%23${colorOptions[customOptions.Google_StreetView_Layer_Lines_Style][0]}%7Cp.w%3A1%2Cs.e%3Ag.s%7Cp.c%3A%23${colorOptions[customOptions.Google_StreetView_Layer_Lines_Style][1]}%7Cp.w%3A3%215m1%215f1.35`,
        Google_Labels:`https://maps.googleapis.com/maps/vt?pb=!1m5!1m4!1i{z}!2i{x}!3i{y}!4i256!2m1!2sm!3m17!2s${customOptions.Language}!3sUS!5e18!12m4!1e68!2m2!1sset!2sRoadmap!12m3!1e37!2m1!1ssmartmaps!12m4!1e26!2m2!1sstyles!2ss.e:g|p.v:off,s.t:1|s.e:g.s|p.v:off,s.e:l|p.v:on!5m1!5f2`,
        Apple_StreetView:`https://lookmap.eu.pythonanywhere.com/bluelines_raster_2x/{z}/{x}/{y}.png`,
        Yandex_StreetView:`https://core-stv-renderer.maps.yandex.net/2.x/tiles?l=stv&x={x}&y={y}&z={z}&scale=1&v=2024.09.06.19.22-1_24.09.08-0-21241`,
        Yandex_Maps:`https://core-renderer-tiles.maps.yandex.net/tiles?l=map&v=24.09.06-3-b240906182700&x={x}&y={y}&z={z}&scale=1`,
        OpenWeather: openWeatherURL,
    }

    let map,google,gsvLayer,initLayer=tag

    const intervalId = setInterval(() => {
        getMap();
        if (map) {
            clearInterval(intervalId)
            initCustomizer()}
    }, 500);


    function createOpacityControl(controlDiv, layer) {
        controlDiv.style.margin='20px'
        controlDiv.style.backgroundColor = '#fff';
        controlDiv.style.height = '30px';
        controlDiv.style.boxShadow = 'rgba(0, 0, 0, 0.3) 0px 1px 4px -1px';
        controlDiv.style.borderRadius = '5px';

        var opacitySlider = document.createElement('input');

        opacitySlider.setAttribute('type', 'range');
        opacitySlider.setAttribute('min', '0');
        opacitySlider.setAttribute('max', '100');
        opacitySlider.setAttribute('value', '100');
        opacitySlider.setAttribute('step', '1');
        opacitySlider.style.width = '90px';
        opacitySlider.style.height='20px'
        opacitySlider.style.marginTop='5px'
        opacitySlider.addEventListener('input', function() {
            var opacity = opacitySlider.value / 100
            layer.setOpacity(opacity);

        });

        controlDiv.appendChild(opacitySlider);
    }

    function addOpacityControl(m, layer) {
        var opacityControlDiv = document.createElement('div');
        new createOpacityControl(opacityControlDiv, layer);
        opacityControlDiv.id=layer.name
        opacityControlDiv.index = 1;
        m.controls[google.maps.ControlPosition.TOP_RIGHT].push(opacityControlDiv);
    }

    function removeOpacityControl(id) {
        var controls = map.controls[google.maps.ControlPosition.TOP_RIGHT];
        if(controls&&controls.getLength()>0){
            if(!id) controls.removeAt(0)
            else{
                for (var i = 0; i < controls.getLength(); i++) {
                    var control = controls.getAt(i);
                    if (control.id === id) {
                        controls.removeAt(i);
                        break;
                    }
                }
            }
        }
    }

    function getNow(date) {
        if(date!='now'){
            return date
        }
        const now = new Date();
        now.setHours(now.getHours() - 1);
        return now.toISOString().slice(0, 14)+'00';
    }

    function getTimestamp(date){
        var parsedDate
        if (date=== 'now') {
            parsedDate= new Date()
            return Math.floor(parsedDate.getTime() / 1000)
        }
        parsedDate = new Date(date);

        if (isNaN(parsedDate.getTime())) {
            throw new Error('Invalid date format');
        }
        return Math.floor(parsedDate.getTime() / 1000);

    }

    function extractTileCoordinates(url) {
        const regex = /!1i(\d+)!2i(\d+)!3i(\d+)!4i(\d+)/;
        const matches = url.match(regex);

        if (matches && matches.length === 5) {
            const z = matches[1];
            const x = matches[2];
            const y = matches[3];
            return { z, x, y };
        } else {
            return null;
        }
    }
    function getBingTiles(tileX, tileY, zoom,type) {
        var quadKey = tileXYToQuadKey(tileX, tileY, zoom);
        var baseUrl = 'https://ecn.t0.tiles.virtualearth.net/tiles/';

        return baseUrl + type + quadKey + '.jpeg?g=14519';
    }
    function tileXYToQuadKey(tileX, tileY, zoom) {
        var quadKey = '';
        for (var i = zoom; i > 0; i--) {
            var digit = 0;
            var mask = 1 << (i - 1);
            if ((tileX & mask) !== 0) {
                digit += 1;
            }
            if ((tileY & mask) !== 0) {
                digit += 2;
            }
            quadKey += digit.toString();
        }
        return quadKey;
    }


    function setMapLayer(layerName) {
        var tileLayerUrl = tileUrls[layerName];
        var tileLayer
        if (layerName==='Bing_Maps') {
            tileLayer = new google.maps.ImageMapType({
                getTileUrl: function(coord, zoom) {
                    return getBingTiles(coord.x,coord.y,zoom,customOptions.Bing_Maps_Style)
                        .replace('{z}', zoom)
                        .replace('{x}', coord.x)
                        .replace('{y}', coord.y);
                },
                tileSize: new google.maps.Size(256, 256),
                name: layerName,

            });
        }
        else if (tileServices.includes(layerName)){
            tileLayer = new google.maps.ImageMapType({
                getTileUrl: function(coord, zoom) {
                    return tileLayerUrl
                        .replace('{z}', zoom)
                        .replace('{x}', coord.x)
                        .replace('{y}', coord.y);
                },
                tileSize: new google.maps.Size(256, 256),
                name: layerName,
                maxZoom:20
            });
            map.mapTypes.set(layerName, tileLayer);
            map.setMapTypeId(layerName);
        }
        else{
            tileLayer = new google.maps.ImageMapType({
                getTileUrl: function(coord, zoom) {
                    return tileLayerUrl
                        .replace('{z}', zoom)
                        .replace('{x}', coord.x)
                        .replace('{y}', coord.y);
                },
                tileSize: new google.maps.Size(256, 256),
                name: layerName,

            });
        }

        if(!layerName.includes('Google')&&layerName!='Apple_StreetView'&&layerName!='Yandex_StreetView'){
            isGoogleDisplay=false
        }
        if(currentLayers.includes(layerName)){
            removeMapLayer(layerName)
            const index = currentLayers.indexOf(layerName);
            if (index !== -1) {
                currentLayers.splice(index, 1);
            }
            if(!layerName.includes('Google')&&!layerName.includes('Weather')&&!layerName.includes('StreetView')){
                setMapType('roadmap')
                map.overlayMapTypes.clear();
                currentLayers=[]
                isGoogleDisplay=true
            }
        }
        else {
            if (!tileServices.includes(layerName)||layerName==='Bing_Maps')map.overlayMapTypes.push(tileLayer)
            currentLayers.push(layerName)};

        if(layerName.includes('StreetView')){
            if(currentLayers.includes(layerName)){
                addOpacityControl(map,tileLayer)
            }
            else removeOpacityControl(layerName)
        }
    }


    function removeMapLayer(layerName) {
        for (let i = 0; i < map.overlayMapTypes.getLength(); i++) {
            const currentLayer = map.overlayMapTypes.getAt(i);
            if (currentLayer && currentLayer.name === layerName) {
                map.overlayMapTypes.removeAt(i);
                break;
            }
        }
    }

    function getMap(){
        let element = document.getElementsByClassName("guess-map_canvas__cvpqv")[0]
        //if (!element) element=document.getElementsByClassName("coordinate-result-map_map__Yh2Il")[0]
        const keys = Object.keys(element)
        const key = keys.find(key => key.startsWith("__reactFiber$"))
        const props = element[key]
        map=props.return.return.memoizedProps.map
        google=unsafeWindow.google
    }

    function setMapType(customType){
        if (currentMapType!=customType){
            currentMapType=customType
        }
        else{
            currentMapType='roadmap'
        }
        map.setMapTypeId(currentMapType);
    }


    function initCustomizer(){
        let onKeyDown = (e) => {
            if (e.key >= '1' && e.key <= '7') {
                initLayer(`layer:${tileServices[tileIndex]}`)
                if(!map) getMap()
                const tileIndex=parseInt(e.key)
                map.overlayMapTypes.clear();
                removeOpacityControl()
                setMapLayer(tileServices[tileIndex])
                const index = currentLayers.indexOf("Google_Labels");
                if (index !== -1) {
                    currentLayers.splice(index, 1);
                }
            }
            else if (e.key === '0') {
                e.stopImmediatePropagation();
                if(!map) getMap()
                initLayer('layer:Google_Labels')
                map.overlayMapTypes.clear();
                currentLayers=[]
                isGoogleDisplay=true
                removeOpacityControl()
                map.set('styles', [
                    {
                        featureType: 'all',
                        elementType: 'labels',
                        stylers: [{ visibility: 'on' }]
                    }
                ])
                isSV=false
            }
            else if (e.key === customOptions.Google_StreetView_Layer_Shortcut.toLowerCase()|| e.key === customOptions.Google_StreetView_Layer_Shortcut) {
                e.stopImmediatePropagation();
                if(!map) getMap()
                initLayer('layer:Google_StreetView')
                if(!isSV){
                    map.set('styles', [
                        {
                            featureType: 'all',
                            elementType: 'labels',
                            stylers: [{ visibility: 'off' }]
                        }
                    ])
                    isSV=true}
                else{
                    map.set('styles', [
                        {
                            featureType: 'all',
                            elementType: 'labels',
                            stylers: [{ visibility: 'on' }]
                        }
                    ])
                    isSV=false
                }
                setMapLayer('Google_StreetView')
                if (isGoogleDisplay)setMapLayer('Google_Labels')
            }
            else if (e.key === customOptions.Apple_StreetView_Layer_Shortcut.toLowerCase()|| e.key === customOptions.Apple_StreetView_Layer_Shortcut) {
                e.stopImmediatePropagation();
                initLayer('layer:Apple_StreetView')
                if(!map) getMap()
                if(!isSV){
                    map.set('styles', [
                        {
                            featureType: 'all',
                            elementType: 'labels',
                            stylers: [{ visibility: 'off' }]
                        }
                    ])
                    isSV=true}
                else{
                    map.set('styles', [
                        {
                            featureType: 'all',
                            elementType: 'labels',
                            stylers: [{ visibility: 'on' }]
                        }
                    ])
                    isSV=false
                }
                setMapLayer('Apple_StreetView')
                if (isGoogleDisplay)setMapLayer('Google_Labels')
            }

            else if (e.key === customOptions.Yandex_StreetView_Layer_Shortcut.toLowerCase()|| e.key === customOptions.Yandex_StreetView_Layer_Shortcut) {
                e.stopImmediatePropagation();
                initLayer('layer:Yandex_StreetView')
                if(!map) getMap()
                if(!isSV){
                    map.set('styles', [
                        {
                            featureType: 'all',
                            elementType: 'labels',
                            stylers: [{ visibility: 'off' }]
                        }
                    ])
                    isSV=true}
                else{
                    map.set('styles', [
                        {
                            featureType: 'all',
                            elementType: 'labels',
                            stylers: [{ visibility: 'on' }]
                        }
                    ])
                    isSV=false
                }
                setMapLayer('Yandex_StreetView')
                if (isGoogleDisplay)setMapLayer('Google_Labels')
            }
            else if (e.key === customOptions.Google_Labels_Layer_Shortcut.toLowerCase()|| e.key === customOptions.Google_Labels_Layer_Shortcut) {
                e.stopImmediatePropagation();
                if(!map) getMap()
                initLayer('layer:Google_Labels')
                setMapLayer('Google_Labels')
            }
            else if (e.key === customOptions.Google_Terrain_Layer_Shortcut.toLowerCase()|| e.key === customOptions.Google_Terrain_Layer_Shortcut) {
                e.stopImmediatePropagation();
                if(!map) getMap()
                initLayer('layer:terrain')
                setMapType('terrain')
            }
            else if (e.key === customOptions.Google_Satellite_Layer_Shortcut.toLowerCase()|| e.key === customOptions.Google_Satellite_Layer_Shortcut) {
                e.stopImmediatePropagation();
                if(!map) getMap()
                initLayer('layer:satellite')
                setMapType('satellite')
            }
            else if (e.key === customOptions.OpenWeather_Shortcut.toLowerCase()|| e.key === customOptions.OpenWeather_Shortcut) {
                e.stopImmediatePropagation();
                if(!map) getMap()
                initLayer('layer:weather')
                setMapLayer('OpenWeather')
            }
        }

        document.addEventListener("keydown", onKeyDown);
    }

})();