Geoguessr Location Resolver (Works in all modes)

Features: Automatically score 5000 Points | Score randomly between 4500 and 5000 points | Open in Google Maps

  1. // ==UserScript==
  2. // @name Geoguessr Location Resolver (Works in all modes)
  3. // @namespace http://tampermonkey.net/
  4. // @version 13
  5. // @description Features: Automatically score 5000 Points | Score randomly between 4500 and 5000 points | Open in Google Maps
  6. // @author 0x978
  7. // @match https://www.geoguessr.com/*
  8. // @icon https://www.google.com/s2/favicons?sz=64&domain=geoguessr.com
  9. // @grant GM_webRequest
  10. // ==/UserScript==
  11.  
  12.  
  13. // =================================================================================================================
  14. // 'An idiot admires complexity, a genius admires simplicity'
  15. // Learn how I made this script: https://github.com/0x978/GeoGuessr_Resolver/blob/master/howIMadeTheScript.md
  16. // Contribute things you think will be cool once you learn: https://github.com/0x978/GeoGuessr_Resolver/pulls
  17. // ================================================================================================================
  18.  
  19. let globalCoordinates = { // keep this stored globally, and we'll keep updating it for each API call.
  20. lat: 0,
  21. lng: 0
  22. }
  23.  
  24. let globalPanoID = undefined
  25.  
  26. // Below, I intercept the API call to Google Street view and view the result before it reaches the client.
  27. // Then I simply do some regex over the response string to find the coordinates, which Google gave to us in the response data
  28. // I then update a global variable above, with the correct coordinates, each time we receive a response from Google.
  29.  
  30. var originalOpen = XMLHttpRequest.prototype.open;
  31. XMLHttpRequest.prototype.open = function(method, url) {
  32. // Geoguessr now calls the Google Maps API multiple times each round, with subsequent requests overwriting
  33. // the saved coordinates. Calls to this exact API path seems to be legitimate for now. A better solution than panoID currently?
  34. // Needs testing.
  35. if (method.toUpperCase() === 'POST' &&
  36. (url.startsWith('https://maps.googleapis.com/$rpc/google.internal.maps.mapsjs.v1.MapsJsInternalService/GetMetadata') ||
  37. url.startsWith('https://maps.googleapis.com/$rpc/google.internal.maps.mapsjs.v1.MapsJsInternalService/SingleImageSearch'))) {
  38.  
  39. this.addEventListener('load', function () {
  40. let interceptedResult = this.responseText
  41. const pattern = /-?\d+\.\d+,-?\d+\.\d+/g;
  42. let match = interceptedResult.match(pattern)[0];
  43. let split = match.split(",")
  44.  
  45. let lat = Number.parseFloat(split[0])
  46. let lng = Number.parseFloat(split[1])
  47.  
  48.  
  49. globalCoordinates.lat = lat
  50. globalCoordinates.lng = lng
  51. });
  52. }
  53. // Call the original open function
  54. return originalOpen.apply(this, arguments);
  55. };
  56.  
  57.  
  58. // ====================================Placing Marker====================================
  59.  
  60. function placeMarker(safeMode){
  61. let {lat,lng} = globalCoordinates
  62.  
  63. if (safeMode) { // applying random values to received coordinates.
  64. const sway = [Math.random() > 0.5,Math.random() > 0.5]
  65. const multiplier = Math.random() * 4
  66. const horizontalAmount = Math.random() * multiplier
  67. const verticalAmount = Math.random() * multiplier
  68. sway[0] ? lat += verticalAmount : lat -= verticalAmount
  69. sway[1] ? lng += horizontalAmount : lat -= horizontalAmount
  70. }
  71.  
  72. let element = document.querySelectorAll('[class^="guess-map_canvas__"]')[0]
  73. if(!element){
  74. placeMarkerStreaks()
  75. return
  76. }
  77.  
  78. const latLngFns = {
  79. latLng:{
  80. lat: () => lat,
  81. lng: () => lng,
  82. }
  83. }
  84.  
  85. // Fetching Map Element and Props in order to extract place function
  86. const reactKeys = Object.keys(element)
  87. const reactKey = reactKeys.find(key => key.startsWith("__reactFiber$"))
  88. const elementProps = element[reactKey]
  89. const mapElementClick = elementProps.return.return.memoizedProps.map.__e3_.click
  90. const mapElementPropKey = Object.keys(mapElementClick)[0]
  91. const mapClickProps = mapElementClick[mapElementPropKey]
  92. const mapClickPropKeys = Object.keys(mapClickProps)
  93.  
  94. for(let i = 0; i < mapClickPropKeys.length ;i++){
  95. if(typeof mapClickProps[mapClickPropKeys[i]] === "function"){
  96. mapClickProps[mapClickPropKeys[i]](latLngFns)
  97. }
  98. }
  99. }
  100.  
  101. function placeMarkerStreaks(){
  102. let {lat,lng} = globalCoordinates
  103. let element = document.getElementsByClassName("region-map_mapCanvas__0dWlf")[0]
  104. if(!element){
  105. return
  106. }
  107. const reactKeys = Object.keys(element)
  108. const reactKey = reactKeys.find(key => key.startsWith("__reactFiber$"))
  109. const elementProps = element[reactKey]
  110. const mapElementClick = elementProps.return.return.memoizedProps.map.__e3_.click
  111. const mapElementClickKeys = Object.keys(mapElementClick)
  112. const functionString = "(e.latLng.lat(),e.latLng.lng())}"
  113. const latLngFn = {
  114. latLng:{
  115. lat: () => lat,
  116. lng: () => lng,
  117. }
  118. }
  119.  
  120. // Fetching Map Element and Props in order to extract place function
  121. for(let i = 0; i < mapElementClickKeys.length; i++){
  122. const curr = Object.keys(mapElementClick[mapElementClickKeys[i]])
  123. let func = curr.find(l => typeof mapElementClick[mapElementClickKeys[i]][l] === "function")
  124. let prop = mapElementClick[mapElementClickKeys[i]][func]
  125. if(prop && prop.toString().slice(5) === functionString){
  126. prop(latLngFn)
  127. }
  128. }
  129. }
  130.  
  131. // ====================================Open In Google Maps====================================
  132.  
  133. function mapsFromCoords() { // opens new Google Maps location using coords.
  134.  
  135. const {lat,lng} = globalCoordinates
  136. if (!lat || !lng) {
  137. return;
  138. }
  139.  
  140. if (nativeOpen) {
  141. const nativeOpenCodeIndex = nativeOpen.toString().indexOf('native code')
  142.  
  143. // Reject any attempt to call an overridden window.open, or fail.
  144. // 19 is for chromium-based browsers; 23 is for firefox-based browsers.
  145. if (nativeOpenCodeIndex === 19 || nativeOpenCodeIndex === 23) {
  146. nativeOpen(`https://maps.google.com/?output=embed&q=${lat},${lng}&ll=${lat},${lng}&z=5`);
  147. }
  148. }
  149. }
  150.  
  151. // ====================================Controls,setup, etc.====================================
  152.  
  153. // Usage ping - sends only script version to server to track usage.
  154. fetch(`https://geoguessrping.0x978.com/ping?script_version=13`)
  155.  
  156. const scripts = document.querySelectorAll('script');
  157. scripts.forEach(script => {
  158. if (script.id === "resolver-cheat-detection-script") {
  159. script.remove()
  160. }
  161. });
  162.  
  163. let onKeyDown = (e) => {
  164. if (e.keyCode === 49) {
  165. e.stopImmediatePropagation(); // tries to prevent the key from being hijacked by geoguessr
  166. placeMarker(true)
  167. }
  168. if (e.keyCode === 50) {
  169. e.stopImmediatePropagation();
  170. placeMarker(false)
  171. }
  172. if (e.keyCode === 51) {
  173. e.stopImmediatePropagation();
  174. mapsFromCoords(false)
  175. }
  176. }
  177.  
  178. document.addEventListener("keydown", onKeyDown);

QingJ © 2025

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