Localized map and map labels for Geoguessr

Replaces default map and map labels on Geoguessr with localized ones.

  1. // ==UserScript==
  2. // @name Localized map and map labels for Geoguessr
  3. // @namespace geoguessr_anon
  4. // @version 1.5.0
  5. // @description Replaces default map and map labels on Geoguessr with localized ones.
  6. // @author Anon
  7. // @license WTFPL
  8. // @match https://*.geoguessr.com/*
  9. // @match https://maps.googleapis.com/maps/api/*
  10. // @require https://openuserjs.org/src/libs/sizzle/GM_config.js
  11. // @grant GM.webRequest
  12. // @grant GM_getValue
  13. // @grant GM_setValue
  14. // @grant GM_addStyle
  15. // @run-at document-start
  16. // ==/UserScript==
  17. var address = (window.location.href);
  18. var valid_address = RegExp('https://www.geoguessr\.com[^.].*');
  19. //console.log(valid_address.test(address));
  20. //console.log(valid_address);
  21. //console.log(address);
  22. //--- Abort the script if top-level page isn't geoguessr.
  23. if (!valid_address.test(address)) {
  24. return
  25. };
  26.  
  27. var langcodes = document.createElement('a');
  28. langcodes.textContent = 'Language Code';
  29. langcodes.href = 'https://developers.google.com/maps/faq#languagesupport';
  30. langcodes.target = 'blank';
  31. var regioncodes = document.createElement('a');
  32. regioncodes.textContent = "Region Code (use the tags with type 'region')";
  33. regioncodes.href = 'https://www.iana.org/assignments/language-subtag-registry/language-subtag-registry';
  34. regioncodes.target = 'blank';
  35. //--- Initialize our config menu.
  36. GM_config.init(
  37. {
  38. 'id': 'geo_mapconfig',
  39. 'title': 'Geoguessr Language/Region Settings',
  40. 'fields':
  41. {
  42. 'Language':
  43. {
  44. 'label': langcodes,
  45. 'type': 'text',
  46. 'title': 'Enter a two-letter language code.',
  47. 'default': 'en'
  48. },
  49. 'Region':
  50. {
  51. 'label': regioncodes,
  52. 'type': 'text',
  53. 'title': 'Enter a two-letter region code.',
  54. 'default': 'us'
  55. },
  56. 'Show':
  57. {
  58. 'label': 'Start with config open',
  59. 'type': 'checkbox',
  60. 'title': 'Uncheck this to hide the config window on startup',
  61. 'default': 'true'
  62. },
  63. }
  64. });
  65.  
  66. 'use strict';
  67. var map_lang = GM_config.get('Language');
  68. var map_reg = GM_config.get('Region');
  69. //--- Intercept the google maps API request and change the language and region codes to what was configured.
  70. GM.webRequest([
  71. { selector: 'https://maps.googleapis.com/maps/api/js?key=*&v=*&libraries=places,drawing&language=*&region=*', action: { redirect: { from: "(.+)([A-Za-z0-9_]{39})(&v=)([0-9.]{1,4})(&libraries=places,drawing)(&language=)(?:..)(&region=)(?:..)", to: "$1$2$3$4$5$6" + map_lang + "$7" + map_reg } } },
  72. ]//, function(info, message, details) {
  73. //console.log(info, message, details);
  74. //}
  75. );
  76. //--- Open the config on first launch.
  77. if (GM_config.get('Show') == true) {
  78. GM_config.open('geo_mapconfig');
  79. }
  80.  
  81. //--- Wait for page to be fully loaded before adding our config button.
  82. window.addEventListener ("load", pageFullyLoaded);
  83. function pageFullyLoaded () {
  84. var zNode = document.createElement ('div');
  85. zNode.innerHTML = '<button id="myButton" type="button">Map Language</button>';
  86. zNode.setAttribute ('id', 'myContainer');
  87. document.body.appendChild (zNode);
  88.  
  89. //--- Activate the newly added button.
  90. document.getElementById ("myButton").addEventListener (
  91. "click", ButtonClickAction, false
  92. );
  93.  
  94. function ButtonClickAction (zEvent) {
  95. //--- Open the config when it's clicked.
  96. GM_config.open('geo_mapconfig')
  97. }
  98.  
  99. //--- Style the button. It's not perfect but it's good enough, feel free to fix it if you're good at this kind of stuff.
  100. GM_addStyle ( `
  101. #myContainer {
  102. position: absolute;
  103. top: 19px;
  104. left: 32px;
  105. opacity: 1.0;
  106. z-index: 1100;
  107. }
  108. #myButton {
  109. cursor: pointer;
  110. background: #6cb928;
  111. font-family: neo-sans;
  112. font-size: 0.75rem;
  113. font-style: italic;
  114. font-weight: 700;
  115. padding: 0.4rem 1rem;
  116. color: white;
  117. border: 0px;
  118. margin: 0px;
  119. opacity: 1.0;
  120. border-radius: 3.75rem;
  121. align-items: center;
  122. justify-content: center;
  123. text-transform: uppercase;
  124. transition-duration: 0s;
  125. }
  126. #myButton:hover {
  127. transform: scale(1.06);
  128. }
  129. ` );
  130. }
  131.  
  132. //USEFUL LINKS//
  133. // List of Google Maps API language codes can be found here (determines the language of labels on your map):
  134. // https://developers.google.com/maps/faq#languagesupport
  135.  
  136. // List of Google Maps API region codes can be found here (determines the regional variation of your map):
  137. // https://www.iana.org/assignments/language-subtag-registry/language-subtag-registry
  138. // Note: Use the tags with type 'region'
  139.  
  140. //NOTES//
  141. // If you change language settings during a game, you'll need to refresh the page before the changes show.
  142. // If you're playing competitive or something, this could potentially be seen as cheating, so keep that in mind, and okay it with whomever beforehand. :)
  143. // I've only tested this using Firefox/Tampermonkey, YMMV with other browsers/userscript engines (GM_webRequest is not amazingly documented).
  144.  
  145. //CHANGELOG//
  146. // 1.4:
  147. // Should now work on all gamemodes.
  148. // Should now work with all geoguessr UI languages (though I think they might have removed the option entirely as I can't find it to test).
  149. // Simplified configuration somewhat.
  150.  
  151. // 1.4.1:
  152. // Works with the new map version (coulda had the new version the entire time, now I think about it).
  153. // Should now work without needing to F5 after entering a game from some pages.
  154.  
  155. // 1.5.0:
  156. // No longer requires an API key to be supplied by the user.
  157. // Now has a configuration mechanism.
  158. // Now has a fancy button in the top-left (I know it's not completely identical to the native buttons, but I'm a novice and it's close enough).
  159. // Uploaded to Greasy Fork镜像, no more ugly pastebins!
  160.  
  161. // To-do:
  162. // More elegant way to restrict it to GeoGuessr.
  163. // It might run on other pages that have google maps iframes due to the @match for the google maps API, which seems to be required to get GM_webRequest to work.
  164. // Right now it aborts the script if it detects the page it's running on isn't GeoGuessr, but the script still technically ran something.

QingJ © 2025

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