Geoguessr Unity Script

For a full list of features included in this script, see this document https://docs.google.com/document/d/18nLXSQQLOzl4WpUgZkM-mxhhQLY6P3FKonQGp-H0fqI/edit?usp=sharing

As of 2022-01-27. See the latest version.

  1. // ==UserScript==
  2. // @name Geoguessr Unity Script
  3. // @description For a full list of features included in this script, see this document https://docs.google.com/document/d/18nLXSQQLOzl4WpUgZkM-mxhhQLY6P3FKonQGp-H0fqI/edit?usp=sharing
  4. // @version 4.5.1
  5. // @include https://www.geoguessr.com/*
  6. // @run-at document-start
  7. // @license MIT
  8. // @namespace https://greatest.deepsurf.us/users/838374
  9. // ==/UserScript==
  10.  
  11. /**
  12. * Custom your minimap here!
  13. */
  14.  
  15. /**
  16. * 1: replace "roadmap" in the customMode field with any of the options below:
  17. * "roadmap" displays the default road map view. This is the default map type.
  18. * "satellite" displays Google Earth satellite images.
  19. * "hybrid" displays a mixture of normal and satellite views.
  20. * "terrain" displays a physical map based on terrain information.
  21. */
  22.  
  23. let customMode = "terrain";
  24.  
  25. /**
  26. * 2: Go to https://mapstyle.withgoogle.com/ first click "No thanks, take me to the old style wizard"
  27. * then click "MORE OPTIONS" to hide or reveal certain features.
  28. * When you are done, click "FINISH", then "COPY JSON", and replace my settings in custom with your settings below.
  29. */
  30.  
  31. let custom =
  32.  
  33. [
  34. {
  35. "featureType": "administrative",
  36. "stylers": [
  37. {
  38. "visibility": "off"
  39. }
  40. ]
  41. }
  42. ]
  43.  
  44. /**
  45. * End of Minimap customization instruction section
  46. */
  47.  
  48. /**
  49. * Overlay anything on the minimap here!
  50. * 1. overlay an GeoJSON object
  51. * 2. overlay a custom image
  52. */
  53.  
  54. /**
  55. * Overlay an GeoJSON object:
  56. */
  57.  
  58. // change the GeoJson display style.
  59. // strokeOpacity, strokeWeight, fillOpacity takes a value between 0 and 1.
  60. // strokeColor and fillColor supports Hexadecimal color (#00FF00 is green)
  61. // If clickable is set to true, you would not be able to make a guess within the shape
  62.  
  63. let GEOJSON_STYLE =
  64. {
  65. strokeColor: "black",
  66. strokeOpacity: 1,
  67. strokeWeight: 1,
  68. fillColor: "#00FF00",
  69. fillOpacity: 0.2,
  70. clickable: false,
  71. }
  72.  
  73. // set it to true to add your custom GeoJSON by URL
  74.  
  75. let GeoJsonCustomURL = false
  76.  
  77. // replace the URL with your desired link
  78. // For example, search "Germany GeoJson" on Github, find this link (https://github.com/isellsoap/deutschlandGeoJSON/blob/main/4_kreise/4_niedrig.geo.json)
  79. // Then click "Download" to get the raw.githubusercontent.com link (https://raw.githubusercontent.com/isellsoap/deutschlandGeoJSON/main/4_kreise/4_niedrig.geo.json)
  80. // and replace the URL below with that URL.
  81.  
  82. let YOUR_URL = "https://raw.githubusercontent.com/gregoiredavid/france-geojson/master/cantons.geojson"
  83.  
  84. // set it to true to add your custom GeoJSON by copy it to the code below
  85.  
  86. let GeoJsonCustomUser = false
  87.  
  88. // replace with your custom GeoJson, go to https://geojson.io/ to customize it then copy the Json to here
  89.  
  90. let CUSTOM_GEOJSON =
  91.  
  92. {
  93. "type": "FeatureCollection",
  94. "features": [
  95. {
  96. "type": "Feature",
  97. "properties": {},
  98. "geometry": {
  99. "type": "LineString",
  100. "coordinates": [
  101. [
  102. 2.493896484375,
  103. 52.7163309360463
  104. ],
  105. [
  106. 2.4609375,
  107. 53.15994678846807
  108. ],
  109. [
  110. 3.2025146484375,
  111. 53.179703893605385
  112. ],
  113. [
  114. 3.2080078125,
  115. 52.96518371955126
  116. ],
  117. [
  118. 2.48291015625,
  119. 52.948637884883205
  120. ]
  121. ]
  122. }
  123. },
  124. {
  125. "type": "Feature",
  126. "properties": {},
  127. "geometry": {
  128. "type": "LineString",
  129. "coordinates": [
  130. [
  131. 3.218994140625,
  132. 52.05586831074774
  133. ],
  134. [
  135. 3.218994140625,
  136. 52.13685974852633
  137. ],
  138. [
  139. 2.515869140625,
  140. 52.1267438596429
  141. ],
  142. [
  143. 2.515869140625,
  144. 51.77803705914517
  145. ],
  146. [
  147. 3.2354736328125,
  148. 51.78993084774129
  149. ],
  150. [
  151. 3.228607177734375,
  152. 51.96119237712624
  153. ],
  154. [
  155. 2.8571319580078125,
  156. 51.95230623740452
  157. ]
  158. ]
  159. }
  160. },
  161. {
  162. "type": "Feature",
  163. "properties": {
  164. "stroke": "#555555",
  165. "stroke-width": 2,
  166. "stroke-opacity": 1
  167. },
  168. "geometry": {
  169. "type": "LineString",
  170. "coordinates": [
  171. [
  172. 2.5048828125,
  173. 52.619725272670266
  174. ],
  175. [
  176. 2.5103759765625,
  177. 52.274880130680536
  178. ],
  179. [
  180. 2.867431640625,
  181. 52.284962354465726
  182. ],
  183. [
  184. 3.2299804687499996,
  185. 52.29504228453735
  186. ],
  187. [
  188. 3.2135009765625,
  189. 52.63973017532399
  190. ],
  191. [
  192. 2.5096893310546875,
  193. 52.621392697207625
  194. ]
  195. ]
  196. }
  197. }
  198. ]
  199. }
  200.  
  201. /**
  202. * Overlay a custom image:
  203. */
  204.  
  205. // set it to true to add your image overlay
  206.  
  207. let OverlayCustom = false
  208.  
  209. // replace the URL with your desired link
  210.  
  211. let OVERLAY_URL = "https://www.battleface.com/blog/wp-content/uploads/2020/10/patreon-profile-tom-geowizard.jpg"
  212.  
  213. // set the bounds for the image - latitude (North and South), longitude (North and South)
  214.  
  215. let OVERLAY_BOUNDS =
  216. {
  217. north: 53,
  218. west: -3,
  219. south: 51,
  220. east: 1,
  221. };
  222.  
  223. // change the image overlay display style.
  224.  
  225. let OVERLAY_STYLE =
  226. {
  227. fillOpacity: 0.2,
  228. clickable: false,
  229. }
  230.  
  231. /**
  232. * End of Minimap Overlay instruction section
  233. */
  234.  
  235. // API Keys
  236.  
  237. var YANDEX_API_KEY = "b704b5a9-3d67-4d19-b702-ec7807cecfc6";
  238. var KAKAO_API_KEY = "cbacbe41e3a223d794f321de4f3e247b";
  239. const MAPS_API_URL = "https://maps.googleapis.com/maps/api/js"; // removed "?" from the link
  240. var MAPILLARY_API_KEY_LIST =
  241. ["MLY|6723031704435203|5afd537469b114cf814881137ad74b7c",
  242. "MLY|6691659414239148|b45e7e82cde126044cbc2cf5d4a7c9b1",
  243. "MLY|5074369465929308|f7ad2802cbaf26c63f88046a292df68b",
  244. "MLY|7451643761528219|6477f2db0e3928b51e45ec9311983936",
  245. "MLY|4855256237866198|6d0464771831c8a4bf2be095e1e1aabc",
  246. "MLY|4772941976102161|8458d4f08d2e1970cdfe0a4e242c04ff",
  247. "MLY|4492067214235489|94c44703942362ad6f6b70b5d32c3a45",
  248. "MLY|4618251611628426|0cef71d6ec8b997a5ec06ecdeabf11ec",
  249. "MLY|4096846270415982|fa2ce29641503e6ef665f17459633570",
  250. "MLY|4231415756962414|fe353880fd246e8a4a6ae32152f7dbb0",]
  251.  
  252. var MAPILLARY_API_KEY = MAPILLARY_API_KEY_LIST[Math.floor(Math.random() * MAPILLARY_API_KEY_LIST.length)];
  253.  
  254. myLog("Geoguessr Unity Script v4.5.1 by Jupaoqq");
  255. // myLog(MAPILLARY_API_KEY);
  256.  
  257. // Store each player instance
  258.  
  259. let YandexPlayer, KakaoPlayer, GooglePlayer, MapillaryPlayer;
  260. let YANDEX_INJECTED = false;
  261. let BAIDU_INJECTED = false;
  262. let KAKAO_INJECTED = false;
  263. let MAPILLARY_INJECTED = false;
  264.  
  265. // Game mode detection
  266.  
  267. let isBattleRoyale = false;
  268. let isDuel = false;
  269.  
  270. // Player detection and coordinate conversion
  271.  
  272. let nextPlayer = "Google";
  273. let global_lat = 0;
  274. let global_lng = 0;
  275. let global_panoID = null;
  276. let global_BDID, global_BDAh, global_BDBh;
  277. let global_heading = null;
  278. let global_pitch = null;
  279.  
  280. let krCoordinates = [38.75292321084364, 124.2804539232574, 33.18509676203202, 129.597381999198]
  281. let global_radi = 100
  282.  
  283. // Callback variables
  284.  
  285. let eventListenerAttached = false;
  286. let povListenerAttached = false;
  287. let playerLoaded = false;
  288. let teleportLoaded = false;
  289. let syncLoaded = false;
  290.  
  291. // Minimize Yandex API use
  292.  
  293. let yandex_map = false;
  294.  
  295. // Mapillary Image Key
  296.  
  297. let mmKey = 0;
  298.  
  299. // Handle Yandex compass
  300.  
  301. let COMPASS = null;
  302.  
  303. // Handle undo
  304.  
  305. let locHistory = [];
  306. let defaultPanoIdChange = true;
  307.  
  308. // Round check
  309.  
  310. let ROUND = 0;
  311. let CURRENT_ROUND_DATA = null;
  312.  
  313. let switch_call = true;
  314. let one_reset = false;
  315. // let cnt = 0;
  316.  
  317. let cn_tips = false;
  318. var isFirefox = typeof InstallTrigger !== 'undefined';
  319.  
  320. let linksList = []
  321. let fire1 = true;
  322.  
  323. let CNBorder = false;
  324.  
  325. // let NEW_ROUND_LOADED = false;
  326.  
  327. /**
  328. * Helper Functions
  329. */
  330.  
  331. // Pretty print
  332.  
  333. function myLog(...args) {
  334. console.log(...args);
  335. }
  336. function myHighlight(...args) {
  337. console.log(`%c${[...args]}`, "color: dodgerblue; font-size: 24px;");
  338. }
  339.  
  340. // Hex to number conversion for Baidu coordinate conversion
  341.  
  342. function hex2a(hexx) {
  343. var hex = hexx.toString();
  344. var str = '';
  345. for (var i = 0; i < hex.length; i += 2)
  346. str += String.fromCharCode(parseInt(hex.substr(i, 2), 16));
  347. return str;
  348. }
  349.  
  350. // Coordinate computation given heading, distance and current coordinates for teleport
  351.  
  352. function FindPointAtDistanceFrom(lat, lng, initialBearingRadians, distanceKilometres) {
  353. const radiusEarthKilometres = 6371.01;
  354. var distRatio = distanceKilometres / radiusEarthKilometres;
  355. var distRatioSine = Math.sin(distRatio);
  356. var distRatioCosine = Math.cos(distRatio);
  357.  
  358. var startLatRad = DegreesToRadians(lat);
  359. var startLonRad = DegreesToRadians(lng);
  360.  
  361. var startLatCos = Math.cos(startLatRad);
  362. var startLatSin = Math.sin(startLatRad);
  363.  
  364. var endLatRads = Math.asin((startLatSin * distRatioCosine) + (startLatCos * distRatioSine * Math.cos(initialBearingRadians)));
  365.  
  366. var endLonRads = startLonRad
  367. + Math.atan2(
  368. Math.sin(initialBearingRadians) * distRatioSine * startLatCos,
  369. distRatioCosine - startLatSin * Math.sin(endLatRads));
  370.  
  371. return { lat: RadiansToDegrees(endLatRads), lng: RadiansToDegrees(endLonRads) };
  372. }
  373.  
  374. function DegreesToRadians(degrees) {
  375. const degToRadFactor = Math.PI / 180;
  376. return degrees * degToRadFactor;
  377. }
  378.  
  379. function RadiansToDegrees(radians) {
  380. const radToDegFactor = 180 / Math.PI;
  381. return radians * radToDegFactor;
  382. }
  383.  
  384. // Check if two floating point numbers are really really really really close to each other (to 10 decimal points)
  385. function almostEqual (a, b) {
  386. return a.toFixed(10) === b.toFixed(10)
  387. }
  388.  
  389. function almostEqual2 (a, b) {
  390. return a.toFixed(3) === b.toFixed(3)
  391. }
  392.  
  393. // Script injection, extracted from extenssr:
  394. // https://gitlab.com/nonreviad/extenssr/-/blob/main/src/injected_scripts/maps_api_injecter.ts
  395.  
  396. function overrideOnLoad(googleScript, observer, overrider) {
  397. const oldOnload = googleScript.onload
  398. googleScript.onload = (event) => {
  399. const google = unsafeWindow.google
  400. if (google) {
  401. observer.disconnect()
  402. overrider(google)
  403. }
  404. if (oldOnload) {
  405. oldOnload.call(googleScript, event)
  406. }
  407. }
  408. }
  409.  
  410. function grabGoogleScript(mutations) {
  411. for (const mutation of mutations) {
  412. for (const newNode of mutation.addedNodes) {
  413. const asScript = newNode
  414. if (asScript && asScript.src && asScript.src.startsWith('https://maps.googleapis.com/')) {
  415. return asScript
  416. }
  417. }
  418. }
  419. return null
  420. }
  421.  
  422. function injecter(overrider) {
  423. if (document.documentElement)
  424. {
  425. injecterCallback(overrider);
  426. }
  427. else
  428. {
  429. alert("Script didn't load, refresh to try loading the script");
  430. }
  431. // else
  432. // {
  433. // setTimeout(injecter(overrider), 2000);
  434. // }
  435. }
  436.  
  437. function injecterCallback(overrider)
  438. {
  439. new MutationObserver((mutations, observer) => {
  440. const googleScript = grabGoogleScript(mutations)
  441. if (googleScript) {
  442. overrideOnLoad(googleScript, observer, overrider)
  443. }
  444. }).observe(document.documentElement, { childList: true, subtree: true })
  445. }
  446.  
  447. /**
  448. * Creates teleportation and Kakao switch button
  449. *
  450. * @returns Promise
  451. */
  452.  
  453.  
  454.  
  455.  
  456.  
  457. function ArisKakao() {
  458. // let radi = 100;
  459. const google = unsafeWindow.google;
  460.  
  461. // console.log(google);
  462. let curPosition;
  463. let kakao_enabled = true;
  464.  
  465. // Helper Functions
  466.  
  467. function FindPointAtDistanceFrom(startPoint, initialBearingRadians, distanceKilometres) {
  468. const radiusEarthKilometres = 6371.01;
  469. var distRatio = distanceKilometres / radiusEarthKilometres;
  470. var distRatioSine = Math.sin(distRatio);
  471. var distRatioCosine = Math.cos(distRatio);
  472.  
  473. var startLatRad = DegreesToRadians(startPoint.lat);
  474. var startLonRad = DegreesToRadians(startPoint.lng);
  475.  
  476. var startLatCos = Math.cos(startLatRad);
  477. var startLatSin = Math.sin(startLatRad);
  478.  
  479. var endLatRads = Math.asin((startLatSin * distRatioCosine) + (startLatCos * distRatioSine * Math.cos(initialBearingRadians)));
  480.  
  481. var endLonRads = startLonRad
  482. + Math.atan2(
  483. Math.sin(initialBearingRadians) * distRatioSine * startLatCos,
  484. distRatioCosine - startLatSin * Math.sin(endLatRads));
  485.  
  486. return { lat: RadiansToDegrees(endLatRads), lng: RadiansToDegrees(endLonRads) };
  487. }
  488.  
  489. function svCheck(data, status) {
  490. if (status === 'OK') {
  491. // console.log("OK for " + data.location.latLng + " at ID " + data.location.pano);
  492. let l = data.location.latLng.toString().split(',');
  493. let lat = l[0].replaceAll('(', '')
  494. let lng = l[1].replaceAll(')', '')
  495. if (lat == curPosition.lat && lng == curPosition.lng && !switch_call)
  496. {
  497. console.log("Trying more distance");
  498. teleportButton.distance += 100;
  499. teleportButton.innerHTML = "Teleport " + teleportButton.distance + " m";
  500. }
  501. else
  502. {
  503. console.log("Teleport Success");
  504. GooglePlayer.setPosition(data.location.latLng);
  505. GooglePlayer.setPov({
  506. heading: googleKakaoButton.heading,
  507. pitch: 0,
  508. })
  509. // console.log(teleportButton.distance);
  510. if (teleportButton.distance > 150)
  511. {
  512. teleportButton.distance = 100;
  513. teleportButton.innerHTML = "Teleport " + teleportButton.distance + " m";
  514. }
  515. }
  516. switch_call = false;
  517. }
  518. else {
  519. console.log("STATUS NOT OK");
  520. teleportButton.distance += 100;
  521. teleportButton.innerHTML = "Teleport " + teleportButton.distance + " m";
  522. }
  523. }
  524.  
  525.  
  526.  
  527. google.maps.Map = class extends google.maps.Map {
  528. constructor(...args) {
  529. super(...args);
  530. if (GeoJsonCustomURL || GeoJsonCustomUser)
  531. {
  532. if (GeoJsonCustomURL)
  533. {
  534. this.data.loadGeoJson(YOUR_URL);
  535. }
  536. if (GeoJsonCustomUser)
  537. {
  538. this.data.addGeoJson(CUSTOM_GEOJSON);
  539. }
  540. this.data.setStyle(function(feature) {
  541. return GEOJSON_STYLE
  542. });
  543. }
  544. if (OverlayCustom)
  545. {
  546.  
  547. let customOverlay = new google.maps.GroundOverlay(OVERLAY_URL, OVERLAY_BOUNDS, OVERLAY_STYLE);
  548. customOverlay.setMap(this);
  549. }
  550. if (CNBorder)
  551. {
  552. this.data.loadGeoJson("https://raw.githubusercontent.com/Jupaoqq/Jupaoqq.github.io/main/10DD.json");
  553. this.data.setStyle(function(feature) {
  554. return {
  555. clickable: false,
  556. strokeWeight: 1
  557. }
  558. });
  559.  
  560. const imageBounds3 = {
  561. north: NW[0],
  562. west: NW[1],
  563. south: NW[2],
  564. east: NW[3],
  565. };
  566.  
  567. historicalOverlay3 = new google.maps.GroundOverlay(
  568. "https://www.countryflags.com/wp-content/uploads/china-flag-png-large.png",
  569. imageBounds3, {clickable: false, opacity: 1}
  570. );
  571. historicalOverlay3.setMap(this);
  572.  
  573. this.addListener("zoom_changed", () => {
  574. let zo = this.getZoom();
  575. let opc = 1;
  576. // console.log(zo)
  577. if (historicalOverlay)
  578. {
  579. historicalOverlay.setMap(null);
  580. historicalOverlay2.setMap(null);
  581. //historicalOverlay3.setMap(null);
  582. }
  583. let bod = TW[0]
  584. let bod2 = TS[0]
  585. if (zo > 7 && zo < 14)
  586. {
  587. bod = TW[zo - 7];
  588. bod2 = TS[1];
  589. }
  590. if (zo >= 14)
  591. {
  592. opc = 0;
  593. }
  594.  
  595. const imageBounds = {
  596. north: bod[0],
  597. west: bod[1],
  598. south: bod[2],
  599. east: bod[3],
  600. };
  601.  
  602. historicalOverlay = new google.maps.GroundOverlay(
  603. "https://www.countryflags.com/wp-content/uploads/china-flag-png-large.png",
  604. imageBounds, {clickable: false, opacity: opc}
  605. );
  606. historicalOverlay.setMap(this);
  607.  
  608. const imageBounds2 = {
  609. north: bod2[0],
  610. west: bod2[1],
  611. south: bod2[2],
  612. east: bod2[3],
  613. };
  614.  
  615. historicalOverlay2 = new google.maps.GroundOverlay(
  616. "https://www.countryflags.com/wp-content/uploads/china-flag-png-large.png",
  617. imageBounds2, {clickable: false, opacity: 1}
  618. );
  619. historicalOverlay2.setMap(this);
  620.  
  621. });
  622. }
  623. for (let mapDiv of document.getElementsByClassName("preset-minimap")){
  624. google.maps.event.addDomListener(mapDiv, "click", () => {
  625. document.getElementById("Minimap Button").current = mapDiv.id;
  626.  
  627. if (mapDiv.id == "Hybrid")
  628. {
  629. this.setMapTypeId('hybrid');
  630. }
  631. else if (mapDiv.id == "Terrain")
  632. {
  633. this.setMapTypeId('terrain');
  634. }
  635. else if (mapDiv.id == "Satellite")
  636. {
  637. this.setMapTypeId('satellite');
  638. }
  639. else if (mapDiv.id == "Custom")
  640. {
  641. this.setMapTypeId(customMode);
  642. }
  643. else
  644. {
  645. this.setMapTypeId('roadmap');
  646. }
  647. // this.setTilt(45);
  648. for (let ar of presetMinimap)
  649. {
  650. if (ar[1] == mapDiv.id)
  651. {
  652. this.set('styles', ar[0]);
  653. }
  654. }
  655. for (let element of document.getElementsByClassName("preset-minimap")){
  656. if (element.id == document.getElementById("Minimap Button").current)
  657. {
  658. element.style.background = "#ff6600";
  659. }
  660. else
  661. {
  662. element.style.background = "orange";
  663. }
  664. }
  665.  
  666. });
  667. }
  668. }
  669.  
  670. }
  671.  
  672. const svService = new google.maps.StreetViewService();
  673. google.maps.StreetViewPanorama = class extends google.maps.StreetViewPanorama {
  674. constructor(...args) {
  675. super(...args);
  676. GooglePlayer = this;
  677.  
  678. const isGamePage = () => location.pathname.startsWith("/challenge/") || location.pathname.startsWith("/results/") || location.pathname.startsWith("/game/")|| location.pathname.startsWith("/battle-royale/") || location.pathname.startsWith("/duels/") || location.pathname.startsWith("/team-duels/");
  679.  
  680. this.addListener('position_changed', () => {
  681. // Maybe this could be used to update the position in the other players
  682. // so that they are always in sync
  683. try {
  684. if (!isGamePage()) return;
  685. // YearButton.panoId = GooglePlayer.pano;
  686. // YearButton.index = -1;
  687. const lat = this.getPosition().lat();
  688. const lng = this.getPosition().lng();
  689. const { heading } = this.getPov();
  690.  
  691. curPosition = { lat, lng, heading };
  692.  
  693. if (googleKakaoButton.useGoogle)
  694. {
  695. googleKakaoButton.lng = lng;
  696. googleKakaoButton.lat = lat;
  697. googleKakaoButton.heading = heading;
  698. if (!YearButton.list.some(row => row.includes(GooglePlayer.pano)))
  699. {
  700. YearButton.innerHTML = "Time Machine";
  701. YearButton.panoId = GooglePlayer.pano;
  702. YearButton.index = -1;
  703. YearButton.plusminusLock = true;
  704. document.getElementById("plus year").style.backgroundColor = "red";
  705. document.getElementById("plus year").disabled = true;
  706. document.getElementById("minus year").style.backgroundColor = "red";
  707. document.getElementById("minus year").disabled = true;
  708. }
  709. }
  710. googleKakaoButton.useGoogle = true;
  711. teleportButton.google = true;
  712. // console.log("also run");
  713.  
  714. // googleKakaoButton.heading = position.lat;
  715. // console.log(position.heading);
  716. // console.log(googleKakaoButton.lng);
  717. }
  718. catch (e) {
  719. console.error("GeoGuessr Path Logger Error:", e);
  720. }
  721. });
  722. this.addListener('pov_changed', () => {
  723. const { heading, pitch } = this.getPov();
  724. if (KakaoPlayer) {
  725. const vp = KakaoPlayer.getViewpoint();
  726. // Prevent a recursive loop: only update kakao's viewpoint if it got out of sync with google's
  727. if ((!almostEqual(vp.pan, heading) || !almostEqual(vp.tilt, pitch)) && nextPlayer == "Kakao") {
  728. KakaoPlayer.setViewpoint({ pan: heading, tilt: pitch, zoom: vp.zoom });
  729. }
  730. }
  731. });
  732. }
  733. };
  734.  
  735.  
  736. var showButtons = document.createElement("Button");
  737. showButtons.id = "Show Buttons"
  738. showButtons.innerHTML = "Geoguessr Unity Script<br><font size=1>by Jupaoqq<br>v4.5.1</font>";
  739. showButtons.style =
  740. "visibility:hidden;top:6em;right:0.5em;width:6em;height:7em;position:absolute;z-index:99999;background-color: #4CAF50;border: none;color: white;padding: none;text-align: center;vertical-align: text-top;text-decoration: none;display: inline-block;font-size: 16px;";
  741. // document.querySelector(".game-layout__status").appendChild(showButtons)
  742. document.body.appendChild(showButtons);
  743. showButtons.addEventListener("click", () => {
  744. if (hide) {
  745. teleportButton.style.visibility = "";
  746. plusButton.style.visibility = "";
  747. minusButton.style.visibility = "";
  748. resetButton.style.visibility = "";
  749. googleKakaoButton.style.visibility = "";
  750. YearButton.style.visibility = "";
  751. YearplusButton.style.visibility = "";
  752. YearminusButton.style.visibility = "";
  753. MinimapButton.style.visibility = "";
  754. hide = false;
  755. }
  756. else {
  757. teleportButton.style.visibility = "hidden";
  758. plusButton.style.visibility = "hidden";
  759. minusButton.style.visibility = "hidden";
  760. resetButton.style.visibility = "hidden"
  761. googleKakaoButton.style.visibility = "hidden";
  762. YearButton.style.visibility = "hidden";
  763. YearplusButton.style.visibility = "hidden";
  764. YearminusButton.style.visibility = "hidden";
  765. MinimapButton.style.visibility = "hidden";
  766. for (let element of document.getElementsByClassName("preset-minimap")){
  767. element.style.visibility="hidden";
  768. }
  769. hide = true;
  770. }
  771. });
  772.  
  773. var teleportButton = document.createElement("Button");
  774. teleportButton.id = "Main Button";
  775. teleportButton.distance = 100;
  776. teleportButton.google = true;
  777. teleportButton.innerHTML = "Teleport 100m";
  778. teleportButton.style =
  779. "visibility:hidden;top:6em;right:9.5em;width:10em;height:2em;position:absolute;z-index:99999;background-color: #4CAF50;border: none;color: white;padding: none;text-align: center;vertical-align: text-top;text-decoration: none;display: inline-block;font-size: 16px;";
  780. document.body.appendChild(teleportButton);
  781. teleportButton.addEventListener("click", () => {
  782. // console.log("Google Teleport");
  783. if (googleKakaoButton.init)
  784. {
  785. // console.log("run");
  786. googleKakaoButton.init = false;
  787. if (teleportButton.google)
  788. {
  789. googleKakaoButton.useGoogle = true;
  790. teleportButton.google = true;
  791. }
  792. else
  793. {
  794. googleKakaoButton.useGoogle = false;
  795. teleportButton.google = false;
  796. }
  797. }
  798. else
  799. {
  800. // myLog(teleportButton.google)
  801. if (teleportButton.google && GooglePlayer != null)
  802. {
  803. let heading = GooglePlayer.getPov().heading;
  804. let place = FindPointAtDistanceFrom(curPosition, DegreesToRadians(heading), teleportButton.distance * 0.001)
  805. svService.getPanorama({ location: place, radius: 1000 }, svCheck);
  806. }
  807. }
  808. });
  809.  
  810. var plusButton = document.createElement("Button");
  811. plusButton.id = "plus"
  812. plusButton.innerHTML = "+";
  813. plusButton.style =
  814. "visibility:hidden;top:6em;right:7em;width:2em;height:2em;position:absolute;z-index:99999;background-color: #4CAF50;border: none;color: white;padding: none;text-align: center;vertical-align: text-top;text-decoration: none;display: inline-block;font-size: 16px;";
  815. document.body.appendChild(plusButton);
  816. plusButton.addEventListener("click", () => {
  817. if (teleportButton.distance > 21 && teleportButton.distance < 149) {
  818. teleportButton.distance = teleportButton.distance + 25;
  819. }
  820. teleportButton.innerHTML = "Teleport " + teleportButton.distance + " m";
  821. });
  822.  
  823. var minusButton = document.createElement("Button");
  824. minusButton.id = "minus"
  825. minusButton.innerHTML = "-";
  826. minusButton.style =
  827. "visibility:hidden;top:6em;right:20em;width:2em;height:2em;position:absolute;z-index:99999;background-color: #4CAF50;border: none;color: white;padding: none;text-align: center;vertical-align: text-top;text-decoration: none;display: inline-block;font-size: 16px;";
  828. document.body.appendChild(minusButton);
  829. minusButton.addEventListener("click", () => {
  830. if (teleportButton.distance > 26) {
  831. teleportButton.distance = teleportButton.distance - 25;
  832. }
  833. teleportButton.innerHTML = "Teleport " + teleportButton.distance + " m";
  834. });
  835.  
  836. var resetButton = document.createElement("Button");
  837. resetButton.id = "reset"
  838. resetButton.innerHTML = "Reset";
  839. resetButton.style =
  840. "visibility:hidden;top:8.5em;right:17.5em;width:4.5em;height:2em;position:absolute;z-index:99999;background-color: #4CAF50;border: none;color: white;padding: none;text-align: center;vertical-align: text-top;text-decoration: none;display: inline-block;font-size: 16px;";
  841. document.body.appendChild(resetButton);
  842. resetButton.addEventListener("click", () => {
  843. teleportButton.distance = 100;
  844. teleportButton.innerHTML = "Teleport " + teleportButton.distance + " m";
  845. });
  846.  
  847. var googleKakaoButton = document.createElement("Button");
  848. googleKakaoButton.id = "switch";
  849. googleKakaoButton.init = false;
  850. googleKakaoButton.nextPlayer = "Google";
  851. googleKakaoButton.useGoogle = false;
  852. googleKakaoButton.lng = 0
  853. googleKakaoButton.lat = 0
  854. googleKakaoButton.heading = 0
  855. googleKakaoButton.innerHTML = "Switch Coverage";
  856. googleKakaoButton.small_canvas = false;
  857. googleKakaoButton.style =
  858. "visibility:hidden;top:8.5em;right:7em;width:10em;height:2em;position:absolute;z-index:99999;background-color: #4CAF50;border: none;color: white;padding: none;text-align: center;vertical-align: text-top;text-decoration: none;display: inline-block;font-size: 16px;";
  859. document.body.appendChild(googleKakaoButton);
  860. googleKakaoButton.addEventListener("click", () => {
  861. let GOOGLE_MAPS_CANVAS1 = document.querySelector(".game-layout__panorama-canvas");
  862. let GOOGLE_MAPS_CANVAS2 = document.querySelector(".br-game-layout__panorama-canvas");
  863. let GOOGLE_MAPS_CANVAS3 = document.querySelector(".inactive");
  864. let duel = false;
  865.  
  866. let GOOGLE_MAPS_CANVAS = null;
  867. if (GOOGLE_MAPS_CANVAS1 !== null)
  868. {
  869. GOOGLE_MAPS_CANVAS = GOOGLE_MAPS_CANVAS1;
  870. }
  871. else if (GOOGLE_MAPS_CANVAS2 !== null)
  872. {
  873. GOOGLE_MAPS_CANVAS = GOOGLE_MAPS_CANVAS2;
  874. }
  875.  
  876.  
  877. if (GOOGLE_MAPS_CANVAS3 !== null)
  878. {
  879. duel = true;
  880. }
  881.  
  882. let KAKAO_MAPS_CANVAS = document.getElementById("roadview");
  883. let YANDEX_MAPS_CANVAS = document.querySelector(".ymaps-2-1-79-panorama-screen");
  884. let MAPILLARY_MAPS_CANVAS = document.getElementById("mly")
  885. let BAIDU_MAPS_CANVAS = document.getElementById("PanoramaMap");
  886. // if (googleKakaoButton.nextPlayer !== "Baidu") {
  887. if (googleKakaoButton.useGoogle == false) {
  888. if (duel)
  889. {
  890. document.getElementById("default_player").className = "game-panorama_panoramaCanvas__PNKve";
  891. if (googleKakaoButton.nextPlayer == "Kakao")
  892. {
  893. document.getElementById("roadview").className = "inactive";
  894. }
  895. else
  896. {
  897. MAPILLARY_MAPS_CANVAS.className = "inactive";
  898. MAPILLARY_MAPS_CANVAS.style.visibility = "hidden";
  899. }
  900. }
  901. else
  902. {
  903. GOOGLE_MAPS_CANVAS.style.visibility = "";
  904. if (googleKakaoButton.nextPlayer == "Kakao")
  905. {
  906. KAKAO_MAPS_CANVAS.style.visibility = "hidden";
  907. }
  908. else if (googleKakaoButton.nextPlayer == "Yandex")
  909. {
  910. YANDEX_MAPS_CANVAS.style.visibility = "hidden";
  911. }
  912. else if (googleKakaoButton.nextPlayer == "Baidu")
  913. {
  914. BAIDU_MAPS_CANVAS.style.visibility = "hidden";
  915. }
  916. else if (googleKakaoButton.nextPlayer == "Mapillary" || googleKakaoButton.nextPlayer == "Google")
  917. {
  918. MAPILLARY_MAPS_CANVAS.style.visibility = "hidden";
  919. }
  920.  
  921. }
  922. const lat = GooglePlayer.getPosition().lat();
  923. const lng = GooglePlayer.getPosition().lng();
  924. switch_call = true;
  925. if (!almostEqual2(lat, googleKakaoButton.lat) || !almostEqual2(lat, googleKakaoButton.lng)) {
  926. svService.getPanorama({ location: { lat: googleKakaoButton.lat, lng: googleKakaoButton.lng }, radius: 1000 }, svCheck);
  927. }
  928. googleKakaoButton.useGoogle = true;
  929. teleportButton.google = true;
  930. googleKakaoButton.init = false;
  931. console.log("use Google");
  932. }
  933. else {
  934. if (duel)
  935. {
  936. document.getElementById("default_player").className = "inactive";
  937. if (googleKakaoButton.nextPlayer == "Kakao")
  938. {
  939. document.getElementById("roadview").className = "game-panorama_panorama__3b2wI";
  940. }
  941. else
  942. {
  943. MAPILLARY_MAPS_CANVAS.className = "game-panorama_panorama__3b2wI";
  944. MAPILLARY_MAPS_CANVAS.style.visibility = "";
  945. MapillaryPlayer.resize();
  946. //window.dispatchEvent(new Event('resize'));
  947. // document.querySelector(".mapillary-canvas").style.;
  948. // mapillary-canvas
  949. }
  950.  
  951. }
  952. else
  953. {
  954. GOOGLE_MAPS_CANVAS.style.visibility = "hidden";
  955. if (googleKakaoButton.nextPlayer == "Kakao")
  956. {
  957. KAKAO_MAPS_CANVAS.style.visibility = "";
  958. }
  959. else if (googleKakaoButton.nextPlayer == "Yandex")
  960. {
  961. YANDEX_MAPS_CANVAS.style.visibility = "";
  962. }
  963. else if (googleKakaoButton.nextPlayer == "Baidu")
  964. {
  965. BAIDU_MAPS_CANVAS.style.visibility = "";
  966. }
  967. else if (googleKakaoButton.nextPlayer == "Mapillary" || googleKakaoButton.nextPlayer == "Google" )
  968. {
  969. MAPILLARY_MAPS_CANVAS.style.visibility = "";
  970. }
  971. }
  972. googleKakaoButton.useGoogle = false;
  973. teleportButton.google = false;
  974. googleKakaoButton.init = true;
  975. console.log("use Others");
  976. }
  977. // }
  978. // else {
  979. // googleKakaoButton.useGoogle = false;
  980. // teleportButton.google = false;
  981. // console.log("use Others");
  982. // }
  983.  
  984. });
  985.  
  986. var YearplusButton = document.createElement("Button");
  987. YearplusButton.id = "plus year"
  988. YearplusButton.innerHTML = "+";
  989. YearplusButton.style =
  990. "visibility:hidden;top:11em;right:7em;width:2em;height:2em;position:absolute;z-index:99999;background-color: #4CAF50;border: none;color: white;padding: none;text-align: center;vertical-align: text-top;text-decoration: none;display: inline-block;font-size: 16px;";
  991. document.body.appendChild(YearplusButton);
  992. YearplusButton.addEventListener("click", () => {
  993. if (YearButton.index < YearButton.list.length - 1 && !YearButton.plusminusLock) {
  994. YearButton.index = YearButton.index + 1;
  995. GooglePlayer.setPano(YearButton.list[YearButton.index][0]);
  996. YearButton.innerHTML = "<font size=2>[" + (YearButton.index + 1) + "] " + YearButton.list[YearButton.index][1] + "</font>";
  997. // myLog(YearButton.index)
  998. }
  999. GenBtnColor();
  1000.  
  1001. });
  1002.  
  1003. var YearminusButton = document.createElement("Button");
  1004. YearminusButton.id = "minus year"
  1005. YearminusButton.innerHTML = "-";
  1006. YearminusButton.style =
  1007. "visibility:hidden;top:11em;right:20em;width:2em;height:2em;position:absolute;z-index:99999;background-color: #4CAF50;border: none;color: white;padding: none;text-align: center;vertical-align: text-top;text-decoration: none;display: inline-block;font-size: 16px;";
  1008. document.body.appendChild(YearminusButton);
  1009. YearminusButton.addEventListener("click", () => {
  1010. if (YearButton.index > 0 && !YearButton.plusminusLock) {
  1011. YearButton.index = YearButton.index - 1;
  1012. GooglePlayer.setPano(YearButton.list[YearButton.index][0]);
  1013. YearButton.innerHTML = "<font size=2>[" + (YearButton.index + 1) + "] " + YearButton.list[YearButton.index][1] + "</font>";
  1014. // myLog(YearButton.index)
  1015. }
  1016. GenBtnColor();
  1017. });
  1018.  
  1019. function svCheck2(data, status) {
  1020. let l = []
  1021. if (status === 'OK') {
  1022. // console.log("OK for " + data.location.latLng + " at ID " + data.location.pano);
  1023. // myLog(data.time)
  1024. for (const alt of data.time) {
  1025. let date = Object.values(alt).find((value) => value instanceof Date)
  1026.  
  1027. l.push([alt.pano, date.toDateString()]);
  1028. }
  1029. // myLog(l);
  1030. YearButton.list = l
  1031. YearButton.index = l.length - 1;
  1032. YearButton.innerHTML = "<font size=2>[" + (YearButton.index + 1) + "] " + YearButton.list[YearButton.index][1] + "</font>";
  1033. GenBtnColor();
  1034. YearButton.plusminusLock = false;
  1035. // YearminusButton.click()
  1036. // YearButton.innerHTML = "Default Date";
  1037. }
  1038. }
  1039.  
  1040. var YearButton = document.createElement("Button");
  1041. YearButton.id = "Date Button";
  1042. YearButton.plusminusLock = true;
  1043. YearButton.panoId = 0;
  1044. YearButton.index = -1;
  1045. YearButton.list = [];
  1046. YearButton.innerHTML = "Time Machine";
  1047. YearButton.style =
  1048. "visibility:hidden;top:11em;right:9.5em;width:10em;height:2em;position:absolute;z-index:99999;background-color: #4CAF50;border: none;color: white;padding: none;text-align: center;vertical-align: text-top;text-decoration: none;display: inline-block;font-size: 16px;";
  1049. document.body.appendChild(YearButton);
  1050. YearButton.addEventListener("click", () => {
  1051. // myLog(YearButton.index)
  1052. if (YearButton.panoId != 0)
  1053. {
  1054. if(YearButton.index == -1)
  1055. {
  1056. svService.getPanorama({pano: YearButton.panoId}, svCheck2);
  1057. }
  1058. else
  1059. {
  1060. YearButton.index = YearButton.list.length - 1;
  1061. GooglePlayer.setPano(YearButton.list[YearButton.index][0]);
  1062. YearButton.innerHTML = "<font size=2>[" + (YearButton.index + 1) + "] " + YearButton.list[YearButton.index][1] + "</font>";
  1063. GenBtnColor();
  1064. }
  1065. }
  1066. else
  1067. {
  1068. YearButton.panoId = GooglePlayer.pano;
  1069. svService.getPanorama({pano: YearButton.panoId}, svCheck2);
  1070. }
  1071. });
  1072.  
  1073. // Battle Royale UI optimization
  1074.  
  1075. let hide = true;
  1076.  
  1077. var MinimapButton = document.createElement("Button");
  1078. MinimapButton.id = "Minimap Button";
  1079. MinimapButton.innerHTML = "Minimap Options";
  1080. MinimapButton.current = "Default";
  1081. MinimapButton.childVisible = false;
  1082. MinimapButton.style =
  1083. "visibility:hidden;top:13.5em;right:7em;width:15em;height:2em;position:absolute;z-index:99999;background-color: #4CAF50;border: none;color: white;padding: none;text-align: center;vertical-align: text-top;text-decoration: none;display: inline-block;font-size: 16px;";
  1084. document.body.appendChild(MinimapButton);
  1085. MinimapButton.addEventListener("click", () => {
  1086. if (MinimapButton.childVisible)
  1087. {
  1088. for (let element of document.getElementsByClassName("preset-minimap")){
  1089. element.style.visibility="hidden";
  1090. }
  1091. MinimapButton.childVisible = false;
  1092. }
  1093. else
  1094. {
  1095. for (let element of document.getElementsByClassName("preset-minimap")){
  1096. element.style.visibility="";
  1097. }
  1098. MinimapButton.childVisible = true;
  1099. }
  1100.  
  1101. });
  1102.  
  1103.  
  1104. let HeightCount = 0
  1105. for (let a of presetMinimap)
  1106. {
  1107. let aButton = document.createElement("Button");
  1108. aButton.id = a[1];
  1109. aButton.className = "preset-minimap";
  1110. aButton.innerHTML = a[1];
  1111. aButton.style =
  1112. "visibility:hidden;top:" + (15.6 + HeightCount * 1.6).toString() + "em;right:10em;width:9em;height:1.5em;position:absolute;z-index:99999;background-color: orange;border: none;color: white;padding: none;text-align: center;vertical-align: text-top;text-decoration: none;display: inline-block;font-size: 16px;";
  1113. document.body.appendChild(aButton);
  1114. HeightCount++;
  1115. }
  1116.  
  1117. console.log("Buttons Loaded");
  1118. }
  1119.  
  1120. function GenBtnColor()
  1121. {
  1122. if (document.getElementById("Date Button").index == document.getElementById("Date Button").list.length - 1)
  1123. {
  1124. document.getElementById("plus year").style.backgroundColor = "red";
  1125. document.getElementById("plus year").disabled = true;
  1126. }
  1127. else
  1128. {
  1129. document.getElementById("plus year").style.backgroundColor = "#4CAF50";
  1130. document.getElementById("plus year").disabled = false;
  1131. }
  1132. if (document.getElementById("Date Button").index == 0)
  1133. {
  1134. document.getElementById("minus year").style.backgroundColor = "red";
  1135. document.getElementById("minus year").disabled = true;
  1136. }
  1137. else
  1138. {
  1139. document.getElementById("minus year").style.backgroundColor = "#4CAF50";
  1140. document.getElementById("minus year").disabled = false;
  1141. }
  1142. }
  1143.  
  1144. /**
  1145. * Handle Keyboard inputs
  1146. */
  1147.  
  1148. function kBoard()
  1149. {
  1150. document.addEventListener('keydown', logKey);
  1151. }
  1152.  
  1153. function logKey(e) {
  1154. // myLog(e.code);
  1155. if (e.code == "Space")
  1156. {
  1157. setHidden(true);
  1158. }
  1159. if (e.code == "Digit1")
  1160. {
  1161. setHidden(false);
  1162. document.getElementById("Show Buttons").click();
  1163. }
  1164. else if (e.code == "Digit3")
  1165. {
  1166. document.getElementById("Main Button").click();
  1167. }
  1168. else if (e.code == "Digit2")
  1169. {
  1170. document.getElementById("minus").click();
  1171. }
  1172. else if (e.code == "Digit4")
  1173. {
  1174. document.getElementById("plus").click();
  1175.  
  1176. }
  1177. else if (e.code == "Digit5")
  1178. {
  1179. document.getElementById("reset").click();
  1180. }
  1181. else if (e.code == "Digit6")
  1182. {
  1183. document.getElementById("switch").click();
  1184. }
  1185. else if (e.code == "Digit7")
  1186. {
  1187. document.getElementById("minus year").click();
  1188. }
  1189. else if (e.code == "Digit8")
  1190. {
  1191. document.getElementById("Date Button").click();
  1192. }
  1193. else if (e.code == "Digit9")
  1194. {
  1195. document.getElementById("plus year").click();
  1196. }
  1197. else if (e.code == "Digit0")
  1198. {
  1199. if (document.getElementById("Show Buttons").style.visibility == "hidden")
  1200. {
  1201. document.getElementById("Show Buttons").style.visibility = "";
  1202. }
  1203. else
  1204. {
  1205. document.getElementById("Show Buttons").style.visibility = "hidden";
  1206. }
  1207. }
  1208. }
  1209.  
  1210.  
  1211. /**
  1212. * Hide or reveal the buttons, and disable buttons if such feature is not available
  1213. */
  1214.  
  1215. function setHidden(cond)
  1216. {
  1217. // myLog("Sethidden")
  1218. if (cond)
  1219. {
  1220. if (document.getElementById("Show Buttons") != null)
  1221. {
  1222. document.getElementById("Show Buttons").style.visibility = "hidden";
  1223. if (document.getElementById("Main Button") != null)
  1224. {
  1225. document.getElementById("plus").style.visibility = "hidden";
  1226. document.getElementById("minus").style.visibility = "hidden";
  1227. document.getElementById("reset").style.visibility = "hidden";
  1228. document.getElementById("Main Button").style.visibility = "hidden";
  1229. document.getElementById("switch").style.visibility = "hidden";
  1230. document.getElementById("Date Button").style.visibility = "hidden";
  1231. document.getElementById("plus year").style.visibility = "hidden";
  1232. document.getElementById("minus year").style.visibility = "hidden";
  1233. document.getElementById("Minimap Button").style.visibility = "hidden";
  1234. for (let element of document.getElementsByClassName("preset-minimap")){
  1235. element.style.visibility="hidden";
  1236. }
  1237. }
  1238. }
  1239. }
  1240. else
  1241. {
  1242. if (document.getElementById("Show Buttons") != null)
  1243. {
  1244. document.getElementById("Show Buttons").style.visibility = "";
  1245. }
  1246. }
  1247. }
  1248.  
  1249. function setDisable(cond) {
  1250. if (document.getElementById("Main Button") != null) {
  1251. if (cond == "NMPZ") {
  1252. document.getElementById("plus").style.backgroundColor = "red";
  1253. document.getElementById("plus").disabled = true;
  1254. document.getElementById("minus").style.backgroundColor = "red";
  1255. document.getElementById("minus").disabled = true;
  1256. document.getElementById("reset").style.backgroundColor = "red";
  1257. document.getElementById("reset").disabled = true;
  1258. if (nextPlayer == "Kakao")
  1259. {
  1260. document.getElementById("switch").style.backgroundColor = "#4CAF50";
  1261. document.getElementById("switch").disabled = false;
  1262. }
  1263. else
  1264. {
  1265. document.getElementById("switch").style.backgroundColor = "red";
  1266. document.getElementById("switch").disabled = true;
  1267. }
  1268. document.getElementById("switch").innerHTML = "Switch Coverage";
  1269. document.getElementById("Main Button").disabled = true;
  1270. document.getElementById("Main Button").style.backgroundColor = "red";
  1271.  
  1272. document.getElementById("Date Button").style.backgroundColor = "#4CAF50";
  1273. document.getElementById("Date Button").disabled = false;
  1274. }
  1275. else if (cond == "Google") {
  1276.  
  1277. document.getElementById("plus").style.backgroundColor = "#4CAF50";
  1278. document.getElementById("plus").disabled = false;
  1279. document.getElementById("minus").style.backgroundColor = "#4CAF50";
  1280. document.getElementById("minus").disabled = false;
  1281. document.getElementById("reset").style.backgroundColor = "#4CAF50";
  1282. document.getElementById("reset").disabled = false;
  1283. document.getElementById("switch").style.backgroundColor = "#4CAF50";
  1284. document.getElementById("switch").disabled = false;
  1285. document.getElementById("switch").innerHTML = "Switch Coverage";
  1286. document.getElementById("Main Button").disabled = false;
  1287. document.getElementById("Main Button").style.backgroundColor = "#4CAF50";
  1288. document.getElementById("Date Button").style.backgroundColor = "#4CAF50";
  1289. document.getElementById("Date Button").disabled = false;
  1290. }
  1291. else if (cond == "Baidu") {
  1292. document.getElementById("plus").style.backgroundColor = "red";
  1293. document.getElementById("plus").disabled = true;
  1294. document.getElementById("minus").style.backgroundColor = "red";
  1295. document.getElementById("minus").disabled = true;
  1296. document.getElementById("reset").style.backgroundColor = "red";
  1297. document.getElementById("reset").disabled = true;
  1298. document.getElementById("switch").style.backgroundColor = "#4CAF50";
  1299. document.getElementById("switch").disabled = false;
  1300. document.getElementById("switch").innerHTML = "Switch Coverage";
  1301. document.getElementById("Main Button").disabled = true;
  1302. document.getElementById("Main Button").style.backgroundColor = "red";
  1303. document.getElementById("Date Button").style.backgroundColor = "red";
  1304. document.getElementById("Date Button").disabled = true;
  1305. }
  1306. else if (cond == "Kakao" || cond == "Yandex" || cond == "Mapillary") {
  1307. document.getElementById("plus").style.backgroundColor = "#4CAF50";
  1308. document.getElementById("plus").disabled = false;
  1309. document.getElementById("minus").style.backgroundColor = "#4CAF50";
  1310. document.getElementById("minus").disabled = false;
  1311. document.getElementById("reset").style.backgroundColor = "#4CAF50";
  1312. document.getElementById("reset").disabled = false;
  1313. document.getElementById("switch").style.backgroundColor = "#4CAF50";
  1314. document.getElementById("switch").disabled = false;
  1315. document.getElementById("switch").innerHTML = "Switch Coverage";
  1316. document.getElementById("Main Button").disabled = false;
  1317. document.getElementById("Main Button").style.backgroundColor = "#4CAF50";
  1318. document.getElementById("Date Button").style.backgroundColor = "red";
  1319. document.getElementById("Date Button").disabled = true;
  1320. }
  1321. document.getElementById("plus year").style.backgroundColor = "red";
  1322. document.getElementById("plus year").disabled = true;
  1323. document.getElementById("minus year").style.backgroundColor = "red";
  1324. document.getElementById("minus year").disabled = true;
  1325. // else if (cond == "Mapillary") {
  1326. // document.getElementById("plus").style.backgroundColor = "red";
  1327. // document.getElementById("plus").disabled = true;
  1328. // document.getElementById("minus").style.backgroundColor = "red";
  1329. // document.getElementById("minus").disabled = true;
  1330. // document.getElementById("reset").style.backgroundColor = "red";
  1331. // document.getElementById("reset").disabled = true;
  1332. // document.getElementById("switch").style.backgroundColor = "#4CAF50";
  1333. // document.getElementById("switch").disabled = false
  1334. // document.getElementById("switch").innerHTML = "Switch Coverage";
  1335. // document.getElementById("Main Button").disabled = true;
  1336. // document.getElementById("Main Button").style.backgroundColor = "red";
  1337. // }
  1338.  
  1339. }
  1340. }
  1341.  
  1342.  
  1343. /**
  1344. * This observer stays alive while the script is running
  1345. */
  1346.  
  1347. function launchObserver() {
  1348. ArisKakao();
  1349. BYKTeleport();
  1350. SyncListener();
  1351. kBoard();
  1352. myHighlight("Main Observer");
  1353. const OBSERVER = new MutationObserver((mutations, observer) => {
  1354. detectGamePage();
  1355. });
  1356. observerCallback(OBSERVER)
  1357. }
  1358. function observerCallback(obs)
  1359. {
  1360. if (obs)
  1361. {
  1362. obs.observe(document.head, { attributes: true, childList: true, subtree: true });
  1363. }
  1364. else
  1365. {
  1366. setTimeout(observerCallback, 250);
  1367. }
  1368. }
  1369.  
  1370. /**
  1371. * Once the Google Maps API was loaded we can do more stuff
  1372. */
  1373.  
  1374. injecter(() => {
  1375. launchObserver();
  1376. })
  1377.  
  1378.  
  1379. /**
  1380. * Check whether the current page is a game, if so which game mode
  1381. */
  1382.  
  1383. function detectGamePage() {
  1384. if (document.querySelector(".game-layout__panorama-message") !== null && !one_reset)
  1385. {
  1386. one_reset = true;
  1387. myLog("Hide fail to load panorama canvas");
  1388. document.querySelector(".game-layout__panorama-message").style.visibility = "hidden";
  1389. }
  1390. let toLoad = !playerLoaded && !YandexPlayer && !KakaoPlayer && !MapillaryPlayer && !YANDEX_INJECTED && !KAKAO_INJECTED && !MAPILLARY_INJECTED
  1391. const PATHNAME = window.location.pathname;
  1392. if (PATHNAME.startsWith("/game/") || PATHNAME.startsWith("/challenge/")) {
  1393. // myLog("Game page");
  1394. isBattleRoyale = false;
  1395. isDuel = false;
  1396. if (toLoad) {
  1397. loadPlayers();
  1398. }
  1399. waitLoad();
  1400. }
  1401. else if (PATHNAME.startsWith("/battle-royale/")) {
  1402. if (document.querySelector(".br-game-layout") == null) {
  1403. // myLog("Battle Royale Lobby");
  1404. rstValues();
  1405. }
  1406. else {
  1407. // myLog("Battle Royale");
  1408. isBattleRoyale = true;
  1409. isDuel = false;
  1410. if (toLoad) {
  1411. loadPlayers();
  1412. }
  1413. waitLoad();
  1414. }
  1415. }
  1416. else if (PATHNAME.startsWith("/duels/") || PATHNAME.startsWith("/team-duels/")) {
  1417. if (document.querySelector(".game_layout__TO_jf") == null) {
  1418. // myLog("Battle Royale Lobby");
  1419. rstValues();
  1420. }
  1421. else {
  1422. // myLog("Duels");
  1423. isBattleRoyale = true;
  1424. isDuel = true;
  1425. if (toLoad) {
  1426. loadPlayers();
  1427. }
  1428. waitLoad();
  1429. }
  1430. }
  1431. else {
  1432. rstValues();
  1433. //myLog("Not a Game page");
  1434. }
  1435. }
  1436.  
  1437. function rstValues()
  1438. {
  1439. ROUND = 0;
  1440. YandexPlayer = null;
  1441. KakaoPlayer = null;
  1442. MapillaryPlayer = null;
  1443.  
  1444. BAIDU_INJECTED = false;
  1445. YANDEX_INJECTED = false;
  1446. KAKAO_INJECTED = false;
  1447. MAPILLARY_INJECTED = false;
  1448.  
  1449. nextPlayer = "Google"
  1450. global_lat = 0;
  1451. global_lng = 0;
  1452. global_panoID = null;
  1453. global_BDAh = null;
  1454. global_BDBh = null;
  1455. global_BDID = null;
  1456.  
  1457. COMPASS = null;
  1458. eventListenerAttached = false;
  1459. povListenerAttached = false;
  1460. playerLoaded = false;
  1461. locHistory = [];
  1462. one_reset = false;
  1463. setHidden(true);
  1464. yandex_map = false;
  1465. mmKey = 0;
  1466. CURRENT_ROUND_DATA = null;
  1467.  
  1468. linksList = [];
  1469. }
  1470.  
  1471. /**
  1472. * Wait for various players to load
  1473. */
  1474.  
  1475. function waitLoad() {
  1476. if (!YandexPlayer || !KakaoPlayer || !MapillaryPlayer || !YANDEX_INJECTED || !KAKAO_INJECTED || !MAPILLARY_INJECTED) {
  1477. let teleportButton = document.getElementById("Main Button");
  1478. let plusButton = document.getElementById("plus");
  1479. let minusButton = document.getElementById("minus");
  1480. let resetButton = document.getElementById("reset");
  1481. let googleKakaoButton = document.getElementById("switch");
  1482. let showButtons = document.getElementById("Show Buttons");
  1483. let YearButton = document.getElementById("Date Button");
  1484. let YearminusButton = document.getElementById("minus year");
  1485. let YearplusButton = document.getElementById("plus year");
  1486. let MinimapButton = document.getElementById("Minimap Button");
  1487. if (document.querySelector(".br-game-layout__panorama-canvas") != null)
  1488. {
  1489. teleportButton.style.top = "2px";
  1490. plusButton.style.top = "2px";
  1491. minusButton.style.top = "2px";
  1492. resetButton.style.top = "calc(2.5em + 2px)";
  1493. googleKakaoButton.style.top = "calc(2.5em + 2px)";
  1494. showButtons.style.top = "2px";
  1495. YearButton.style.top = "calc(5em + 2px)";
  1496. YearminusButton.style.top = "calc(5em + 2px)";
  1497. YearplusButton.style.top = "calc(5em + 2px)";
  1498. MinimapButton.style.top = "calc(7.5em + 2px)";
  1499.  
  1500. teleportButton.style.right = "calc(9.5em + 300px)";
  1501. plusButton.style.right = "calc(7em + 300px)";
  1502. minusButton.style.right = "calc(20em + 300px)";
  1503. resetButton.style.right = "calc(17.5em + 300px)";
  1504. googleKakaoButton.style.right = "calc(7em + 300px)";
  1505. showButtons.style.right = "300px";
  1506. YearButton.style.right = "calc(9.5em + 300px)";
  1507. YearminusButton.style.right = "calc(20em + 300px)";
  1508. YearplusButton.style.right = "calc(7em + 300px)";
  1509. MinimapButton.style.right = "calc(7em + 300px)";
  1510.  
  1511. let hC = 0
  1512. for (let mapDiv of document.getElementsByClassName("preset-minimap")){
  1513. mapDiv.style.top = "calc(" + (10 + hC * 1.6).toString() + "em + 2px)";
  1514. mapDiv.style.right = "calc(10em + 300px)";
  1515. hC++;
  1516. }
  1517. }
  1518. else if (document.querySelector(".game-panorama_panorama__rdhFg") != null)
  1519. {
  1520. teleportButton.style.top = "8em";
  1521. plusButton.style.top = "8em";
  1522. minusButton.style.top = "8em";
  1523. resetButton.style.top = "10.5em";
  1524. googleKakaoButton.style.top = "10.5em";
  1525. showButtons.style.top = "8em";
  1526. YearButton.style.top = "13em";
  1527. YearminusButton.style.top = "13em";
  1528. YearplusButton.style.top = "13em";
  1529. MinimapButton.style.top = "15.5em";
  1530.  
  1531. teleportButton.style.right = "9.5em";
  1532. plusButton.style.right = "7em";
  1533. minusButton.style.right = "20em";
  1534. resetButton.style.right = "17.5em";
  1535. googleKakaoButton.style.right = "7em";
  1536. showButtons.style.right = "0.5em";
  1537. YearButton.style.right = "9.5em";
  1538. YearminusButton.style.right = "20em";
  1539. YearplusButton.style.right = "7em";
  1540. MinimapButton.style.right = "7em";
  1541. let hC = 0
  1542. for (let mapDiv of document.getElementsByClassName("preset-minimap")){
  1543. mapDiv.style.top = (18 + (hC * 1.6)).toString() + "em";
  1544. mapDiv.style.right = "10em";
  1545. hC++;
  1546. }
  1547. }
  1548. else
  1549. {
  1550. teleportButton.style.top = "6em";
  1551. plusButton.style.top = "6em";
  1552. minusButton.style.top = "6em";
  1553. resetButton.style.top = "8.5em";
  1554. googleKakaoButton.style.top = "8.5em";
  1555. showButtons.style.top = "6em";
  1556. YearButton.style.top = "1em";
  1557. YearminusButton.style.top = "11em";
  1558. YearplusButton.style.top = "11em";
  1559. MinimapButton.style.top = "13.5em";
  1560.  
  1561. teleportButton.style.right = "9.5em";
  1562. plusButton.style.right = "7em";
  1563. minusButton.style.right = "20em";
  1564. resetButton.style.right = "17.5em";
  1565. googleKakaoButton.style.right = "7em";
  1566. showButtons.style.right = "0.5em";
  1567. YearButton.style.right = "9.5em";
  1568. YearminusButton.style.right = "20em";
  1569. YearplusButton.style.right = "7em";
  1570. MinimapButton.style.right = "7em";
  1571. let hC = 0
  1572. for (let mapDiv of document.getElementsByClassName("preset-minimap")){
  1573. mapDiv.style.top = (15.6 + (hC * 1.6)).toString() + "em";
  1574. mapDiv.style.right = "10em";
  1575. hC++;
  1576. }
  1577. }
  1578.  
  1579. setTimeout(waitLoad, 250);
  1580. } else {
  1581. checkRound();
  1582. }
  1583. }
  1584.  
  1585. /**
  1586. * Checks for round changes
  1587. */
  1588.  
  1589. function checkRound() {
  1590. // myLog("Check Round");
  1591. if (!isBattleRoyale) {
  1592. // myLog("Check Round");
  1593. let currentRound = getRoundFromPage();
  1594. if (ROUND != currentRound) {
  1595. fire1 = true;
  1596. document.getElementById("switch").init = true;
  1597. myHighlight("New round");
  1598. ROUND = currentRound;
  1599. // NEW_ROUND_LOADED = true;
  1600. COMPASS = null;
  1601. locHistory = [];
  1602. one_reset = false;
  1603. getMapData();
  1604. nextButtonCallback();
  1605. }
  1606. }
  1607. else {
  1608. getMapData();
  1609. }
  1610. }
  1611.  
  1612. /**
  1613. * Add listeners if buttons have been created
  1614. */
  1615.  
  1616. function finalDetail()
  1617. {
  1618. let target = document.querySelector("a[data-qa='play-same-map']");
  1619. if (target)
  1620. {
  1621. var div = document.createElement("div");
  1622. div.classList.add("buttons_buttons__0B3SB")
  1623. document.querySelector('.result-layout_content__jAHfP').appendChild(div);
  1624. for (var rd of linksList)
  1625. {
  1626. let cl = target.cloneNode( true );
  1627. let tx = "View R" + rd[0] + " in " + rd[1];
  1628. cl.querySelector('.button_label__kpJrA').innerHTML = tx;
  1629. cl.removeAttribute('data-qa');
  1630. cl.addEventListener("click", (e) => {
  1631. window.open(rd[2]);
  1632. })
  1633. cl.style = "top:10px;right:-10px;";
  1634. div.appendChild(cl);
  1635. }
  1636. }
  1637. else
  1638. {
  1639. setTimeout(finalDetail, 500);
  1640. }
  1641. }
  1642.  
  1643. function nextButtonCallback()
  1644. {
  1645. let nextButton = document.querySelector("button[data-qa='close-round-result']");
  1646. if (nextButton != null && fire1)
  1647. {
  1648. fire1 = false;
  1649. nextButton.addEventListener("click", (e) => {
  1650. if (document.getElementById("Show Buttons") != null && !cn_tips && ROUND !== 5)
  1651. {
  1652. myLog("try to show show buttons")
  1653. document.getElementById("Show Buttons").style.visibility = "";
  1654. }
  1655. if (ROUND == 5)
  1656. {
  1657. myLog("Game Finished")
  1658. if (linksList)
  1659. {
  1660. finalDetail();
  1661. }
  1662. }
  1663. })
  1664.  
  1665. if (nextPlayer !== "Google")
  1666. {
  1667. myLog("Clone buttons");
  1668. let clone = document.querySelector("button[data-qa='close-round-result']").cloneNode( true );
  1669. let tx = "View Location in " + nextPlayer;
  1670. clone.querySelector('.button_label__kpJrA').innerHTML = tx;
  1671. clone.setAttribute('id', "LinkBtn");
  1672. clone.removeAttribute('data-qa');
  1673. let urlStr = ""
  1674. if (nextPlayer == "Baidu")
  1675. {
  1676. urlStr = "https://map.baidu.com/?panotype=street&pid=" + global_BDID + "&panoid=" + global_BDID + "&from=api";
  1677. }
  1678. else if (nextPlayer == "Kakao")
  1679. {
  1680. urlStr = "https://map.kakao.com/link/roadview/" + global_lat + "," + global_lng;
  1681. }
  1682. else if (nextPlayer == "Mapillary")
  1683. {
  1684. urlStr = "https://www.mapillary.com/app/?pKey=" + mmKey + "&focus=photo";
  1685. }
  1686. else if (nextPlayer == "Yandex")
  1687. {
  1688. urlStr = "https://yandex.com/maps/?&panorama%5Bdirection%5D=16%2C0&panorama%5Bpoint%5D=" + global_lng + "%2C" + global_lat;
  1689. }
  1690. linksList.push([ROUND, nextPlayer, urlStr]);
  1691. clone.addEventListener("click", (e) => {
  1692. window.open(urlStr);
  1693. })
  1694. if (ROUND == 5)
  1695. {
  1696. clone.style = "top:10px;";
  1697. }
  1698. else
  1699. {
  1700. clone.style = "right:-10px;";
  1701. }
  1702. document.querySelector('.round-result_actions__5j26U').appendChild(clone);
  1703. }
  1704. }
  1705. else
  1706. {
  1707. setTimeout(nextButtonCallback, 500);
  1708. }
  1709. }
  1710.  
  1711. function guessButtonCallback()
  1712. {
  1713. let guessButton = document.querySelector("button[data-qa='perform-guess']");
  1714. if (guessButton != null)
  1715. {
  1716.  
  1717. guessButton.addEventListener("click", (e) => {
  1718. if (document.getElementById("Show Buttons") != null)
  1719. {
  1720. myLog("try to hide show buttons")
  1721. document.getElementById("Show Buttons").style.visibility = "hidden";
  1722. setHidden(true);
  1723. }
  1724. })
  1725. }
  1726. else
  1727. {
  1728. setTimeout(guessButtonCallback, 500);
  1729. }
  1730. }
  1731.  
  1732. /**
  1733. * Load different streetview players
  1734. */
  1735.  
  1736. function injectYandex()
  1737. {
  1738. injectYandexScript().then(() => {
  1739. myLog("Ready to inject Yandex player");
  1740. injectYandexPlayer();
  1741. }).catch((error) => {
  1742. myLog(error);
  1743. });
  1744. }
  1745.  
  1746. function tutorialPosition(flag)
  1747. {
  1748. let teleportButton = document.getElementById("Main Button");
  1749. let plusButton = document.getElementById("plus");
  1750. let minusButton = document.getElementById("minus");
  1751. let resetButton = document.getElementById("reset");
  1752. let googleKakaoButton = document.getElementById("switch");
  1753. let showButtons = document.getElementById("Show Buttons");
  1754. let YearButton = document.getElementById("Date Button");
  1755. let YearminusButton = document.getElementById("minus year");
  1756. let YearplusButton = document.getElementById("plus year");
  1757. // document.getElementById("Show Buttons").style.visibility = "hidden";
  1758. if (flag)
  1759. {
  1760. teleportButton.style.top = "20em";
  1761. plusButton.style.top = "20em";
  1762. minusButton.style.top = "20em";
  1763. resetButton.style.top = "22.5em";
  1764. googleKakaoButton.style.top = "22.5em";
  1765. showButtons.style.top = "20em";
  1766. YearButton.style.top = "25em";
  1767. YearminusButton.style.top = "25em";
  1768. YearplusButton.style.top = "25em";
  1769. }
  1770. else
  1771. {
  1772. teleportButton.style.top = "6em";
  1773. plusButton.style.top = "6em";
  1774. minusButton.style.top = "6em";
  1775. resetButton.style.top = "8.5em";
  1776. googleKakaoButton.style.top = "8.5em";
  1777. showButtons.style.top = "6em";
  1778. YearButton.style.top = "11em";
  1779. YearminusButton.style.top = "11em";
  1780. YearplusButton.style.top = "11em";
  1781.  
  1782. }
  1783.  
  1784. }
  1785.  
  1786. function loadPlayers() {
  1787. playerLoaded = true;
  1788. if (!isBattleRoyale)
  1789. {
  1790. getSeed().then((data) => {
  1791. // myLog(data);
  1792. if (data.mapName.includes("A United World") || data.mapName.includes("byk"))
  1793. {
  1794. myLog("A United World");
  1795. injectYandex();
  1796. }
  1797. else if (data.mapName.includes("Yandex"))
  1798. {
  1799. yandex_map = true;
  1800. myLog("Is Yandex Map");
  1801. injectYandex();
  1802. }
  1803. else{
  1804. // YANDEX_API_KEY = "";
  1805. YANDEX_INJECTED = true;
  1806. YandexPlayer = "YD";
  1807. myLog("Not a Yandex map");
  1808. }
  1809. if (!data.mapName.includes("China Tips for each province"))
  1810. {
  1811. cn_tips = false;
  1812. document.getElementById("Show Buttons").style.visibility = "";
  1813. setHidden(false);
  1814. }
  1815. else
  1816. {
  1817. cn_tips = true;
  1818. guaranteeUI();
  1819. }
  1820. }).catch((error) => {
  1821. myLog(error);
  1822. });
  1823. }
  1824. else
  1825. {
  1826. injectYandex();
  1827. }
  1828.  
  1829. initializeCanvas();
  1830.  
  1831.  
  1832.  
  1833.  
  1834. }
  1835.  
  1836. function guaranteeUI()
  1837. {
  1838. // myLog("UI")
  1839. if (document.getElementById("GH-ui") !== null)
  1840. {
  1841. document.getElementById("GH-ui").style.display = "block";
  1842. }
  1843. else
  1844. {
  1845. setTimeout(guaranteeUI, 500);
  1846. }
  1847. }
  1848.  
  1849. /**
  1850. * Handles Return to start and undo
  1851. */
  1852.  
  1853. function handleReturnToStart() {
  1854. let rtsButton = document.querySelector("button[data-qa='return-to-start']");
  1855. if (rtsButton != null) {
  1856. myLog("handleReturnToStart listener attached");
  1857. rtsButton.addEventListener("click", (e) => {
  1858. if (nextPlayer != "Baidu")
  1859. {
  1860. goToLocation();
  1861. }
  1862. else
  1863. {
  1864. document.getElementById("PanoramaMap").src = "https://map.baidu.com/?panotype=street&pid=" + global_BDID + "&panoid=" + global_BDID + "&from=api";
  1865. }
  1866. const elementClicked = e.target;
  1867. elementClicked.setAttribute('listener', 'true');
  1868. myLog("Return to start");
  1869. });
  1870. guessButtonCallback();
  1871. setTimeout(function () {goToLocation();}, 1000);
  1872. }
  1873. else
  1874. {
  1875. setTimeout(handleReturnToStart, 500);
  1876. }
  1877. }
  1878.  
  1879. function handleUndo() {
  1880. let undoButton = document.querySelector("button[data-qa='undo-move']");
  1881. if (undoButton != null)
  1882. {
  1883. myLog("Attach undo");
  1884. undoButton.addEventListener("click", (e) => {
  1885. if (locHistory.length > 0) {
  1886. goToUndoMove();
  1887. myLog("Undo Move");
  1888. }
  1889. })
  1890. }
  1891. else
  1892. {
  1893. setTimeout(handleUndo, 500);
  1894. }
  1895.  
  1896. }
  1897.  
  1898. /**
  1899. * Load game information
  1900. */
  1901.  
  1902. function getMapData() {
  1903. // myHighlight("Seed data");
  1904. getSeed().then((data) => {
  1905. // myHighlight("Seed data");
  1906. // myLog(data);
  1907. if (isBattleRoyale) {
  1908. if ((document.querySelector(".br-game-layout") == null && document.querySelector(".version3-in-game_layout__Hi_Iw") == null) || typeof data.gameId == typeof undefined) {
  1909. // myLog("Battle Royale Lobby");
  1910. }
  1911. else
  1912. {
  1913. let origin = false;
  1914. if (!CURRENT_ROUND_DATA) {
  1915. CURRENT_ROUND_DATA = data
  1916. origin = true;
  1917. }
  1918.  
  1919. if (origin || !(data.currentRoundNumber === CURRENT_ROUND_DATA.currentRoundNumber)) {
  1920. // myHighlight("Battle Royale New round");
  1921. document.getElementById("switch").init = true;
  1922. // NEW_ROUND_LOADED = true;
  1923. COMPASS = null;
  1924. locHistory = [];
  1925. one_reset = false;
  1926. setHidden(false);
  1927. if (!origin) {
  1928. CURRENT_ROUND_DATA = data;
  1929. }
  1930. locationCheck(data);
  1931. // myLog(data);
  1932. if (data.currentRoundNumber == 1)
  1933. {
  1934. setTimeout(function () {goToLocation();}, 3000);
  1935. }
  1936. else
  1937. {
  1938. goToLocation();
  1939. }
  1940. handleReturnToStart();
  1941. if (isDuel)
  1942. {
  1943. handleUndo();
  1944. hideButtons();
  1945. }
  1946. handleMinimapCallback();
  1947.  
  1948. }
  1949. }
  1950. }
  1951. else {
  1952. if (!cn_tips)
  1953. {
  1954. document.getElementById("Show Buttons").style.visibility = "";
  1955. tutorialPosition(false);
  1956. }
  1957. else
  1958. {
  1959. document.getElementById("Show Buttons").style.visibility = "hidden";
  1960. tutorialPosition(true);
  1961. }
  1962. locationCheck(data);
  1963. if (data.currentRoundNumber == 1)
  1964. {
  1965. setTimeout(function () {goToLocation();}, 3000);
  1966. }
  1967. else
  1968. {
  1969. goToLocation();
  1970. }
  1971. handleReturnToStart();
  1972. handleUndo();
  1973. hideButtons();
  1974. handleMinimapCallback();
  1975. }
  1976.  
  1977.  
  1978.  
  1979. }).catch((error) => {
  1980. myLog(error);
  1981. });
  1982. }
  1983.  
  1984. function handleMinimapCallback()
  1985. {
  1986. let trueCond = true;
  1987. let timeoutTime = 250;
  1988. if (isBattleRoyale) {
  1989. if (isDuel)
  1990. {
  1991. if (document.querySelector(".overlay_overlay__AR02x"))
  1992. {
  1993. trueCond = false;
  1994. }
  1995. else
  1996. {
  1997. trueCond = true;
  1998. }
  1999. }
  2000. else
  2001. {
  2002. if (document.querySelector(".popup__content"))
  2003. {
  2004. trueCond = false;
  2005. }
  2006. else
  2007. {
  2008. trueCond = true;
  2009. }
  2010. }
  2011. timeoutTime = 2500;
  2012. }
  2013.  
  2014. if (trueCond)
  2015. {
  2016. let cur = document.getElementById("Minimap Button").current;
  2017. myLog(cur)
  2018. for (let mapDiv of document.getElementsByClassName("preset-minimap")){
  2019. if (cur == mapDiv.id)
  2020. {
  2021. setTimeout(function () {mapDiv.click();}, 500);
  2022. setTimeout(function () {mapDiv.click();}, 1000);
  2023. setTimeout(function () {mapDiv.click();}, 3000);
  2024. }
  2025. }
  2026. }
  2027. else
  2028. {
  2029. setTimeout(handleMinimapCallback, 250);
  2030. }
  2031. }
  2032.  
  2033. /**
  2034. * Hide unnecessary buttons for non-Google coverages
  2035. */
  2036.  
  2037. function hideButtons() {
  2038. let CHECKPOINT = document.querySelector("button[data-qa='set-checkpoint']");
  2039. let ZOOM_IN = document.querySelector("button[data-qa='pano-zoom-in']");
  2040. let ZOOM_OUT = document.querySelector("button[data-qa='pano-zoom-out']");
  2041.  
  2042. if (CHECKPOINT != null)
  2043. {
  2044. if (nextPlayer === "Google") {
  2045.  
  2046. CHECKPOINT.style.visibility = "";
  2047. ZOOM_IN.style.visibility = "";
  2048. ZOOM_OUT.style.visibility = "";
  2049. myLog("Buttons Unhidden");
  2050.  
  2051. }
  2052. else {
  2053.  
  2054. CHECKPOINT.style.visibility = "hidden";
  2055. ZOOM_IN.style.visibility = "hidden";
  2056. ZOOM_OUT.style.visibility = "hidden";
  2057. myLog("Buttons Hidden");
  2058.  
  2059. }
  2060. }
  2061. else
  2062. {
  2063. setTimeout(hideButtons, 250);
  2064. }
  2065. }
  2066.  
  2067. /**
  2068. * Check which player to use for the next location
  2069. */
  2070.  
  2071. function locationCheck(data) {
  2072. // console.log(data);
  2073. let round;
  2074. if (isBattleRoyale) {
  2075. if (isDuel)
  2076. {
  2077. round = data.rounds[data.currentRoundNumber - 1].panorama;
  2078. }
  2079. else
  2080. {
  2081. round = data.rounds[data.currentRoundNumber - 1];
  2082. }
  2083. }
  2084. else {
  2085. round = data.rounds[data.round - 1];
  2086. }
  2087. global_lat = round.lat;
  2088. global_lng = round.lng;
  2089. global_panoID = round.panoId;
  2090. global_heading = round.heading;
  2091. global_pitch = round.pitch;
  2092. // myLog(global_lat);
  2093. // myLog(global_lng);
  2094. // myLog(krCoordinates);
  2095.  
  2096. nextPlayer = "Google";
  2097.  
  2098. if ( krCoordinates[0] > global_lat && krCoordinates[2] < global_lat && krCoordinates[1] < global_lng && krCoordinates[3] > global_lng)
  2099. {
  2100. nextPlayer = "Kakao";
  2101. }
  2102. else if (yandex_map)
  2103. {
  2104. nextPlayer = "Yandex";
  2105. }
  2106. else
  2107. {
  2108. if (global_panoID) {
  2109. let locInfo = hex2a(global_panoID);
  2110. // myLog(locInfo)
  2111. let mapType = locInfo.substring(0, 5);
  2112. if (mapType === "BDMAP") {
  2113. nextPlayer = "Baidu";
  2114. let coord = locInfo.substring(5);
  2115.  
  2116. if(coord.includes('BDAh'))
  2117. {
  2118. global_BDID = coord.split('BDAh')[0].replace("panoId","");
  2119. let tem = coord.split('BDAh')[1];
  2120. global_BDAh = tem.split('BDBh')[0];
  2121. global_BDBh = tem.split('BDBh')[1];
  2122. }
  2123. else
  2124. {
  2125. global_BDID = coord.replace("panoId","");
  2126. }
  2127. // myLog(global_BDID)
  2128. // myLog(global_BDAh)
  2129. // myLog(global_BDBh)
  2130. // global_lat = coord.split(",")[0];
  2131. // global_lng = coord.split(",")[1];
  2132. // myLog(global_lat);
  2133. }
  2134. else if (mapType === "MLMAP") {
  2135. nextPlayer = "Mapillary";
  2136. mmKey = locInfo.substring(5);
  2137. }
  2138. else if (mapType === "YDMAP" ) {
  2139. nextPlayer = "Yandex";
  2140. }
  2141. }
  2142. }
  2143.  
  2144. // Disable buttons if NM, NMPZ
  2145.  
  2146. if(!isBattleRoyale)
  2147. {
  2148. if (data.forbidMoving || data.forbidRotating || data.forbidZooming)
  2149. {
  2150. setDisable("NMPZ");
  2151. }
  2152. else
  2153. {
  2154. setDisable(nextPlayer);
  2155. }
  2156. }
  2157. else
  2158. {
  2159. if (data.movementOptions.forbidMoving || data.movementOptions.forbidRotating || data.movementOptions.forbidZooming)
  2160. {
  2161. setDisable("NMPZ");
  2162. }
  2163. else
  2164. {
  2165. setDisable(nextPlayer);
  2166. }
  2167. }
  2168.  
  2169. myLog(nextPlayer);
  2170. injectCanvas();
  2171. }
  2172.  
  2173.  
  2174. /**
  2175. * setID for canvas
  2176. */
  2177.  
  2178. function initializeCanvas() {
  2179. let GAME_CANVAS = "";
  2180. let DUEL_CANVAS = "";
  2181. //myLog("Is duels");
  2182. //myLog(duels);
  2183.  
  2184. if (isBattleRoyale) {
  2185. if (isDuel) {
  2186. GAME_CANVAS = document.querySelector(".game-panorama_panorama__rdhFg");
  2187. DUEL_CANVAS = document.querySelector(".game-panorama_panoramaCanvas__PNKve");
  2188. }
  2189. else
  2190. {
  2191. GAME_CANVAS = document.querySelector(".br-game-layout__panorama-wrapper");
  2192. DUEL_CANVAS = "dummy";
  2193. }
  2194. }
  2195. else {
  2196. GAME_CANVAS = document.querySelector(".game-layout__canvas");
  2197. DUEL_CANVAS = "dummy";
  2198. }
  2199. if (GAME_CANVAS && DUEL_CANVAS)
  2200. {
  2201. myLog("Canvas injected");
  2202. GAME_CANVAS.id = "player";
  2203. if (isDuel) {
  2204. DUEL_CANVAS.id = "default_player";
  2205. }
  2206. injectBaiduScript();
  2207. injectMapillaryPlayer();
  2208. injectKakaoScript().then(() => {
  2209. myLog("Ready to inject Kakao player");
  2210. }).catch((error) => {
  2211. myLog(error);
  2212. });
  2213. }
  2214. else
  2215. {
  2216. setTimeout(initializeCanvas, 250);
  2217. }
  2218.  
  2219. }
  2220.  
  2221. /**
  2222. * Hide or show players based on where the next location is
  2223. */
  2224.  
  2225. function injectCanvas() {
  2226. if (isDuel)
  2227. {
  2228. canvasSwitch();
  2229. }
  2230. else
  2231. {
  2232. Google();
  2233. Baidu();
  2234. Kakao();
  2235. Yandex();
  2236. Mapillary();
  2237. }
  2238. ZoomControls();
  2239. }
  2240.  
  2241. // for duels (class ID change)
  2242.  
  2243. function canvasSwitch()
  2244. {
  2245. if (document.querySelector(".compass") !== null && document.querySelector("button[data-qa='undo-move']") !== null)
  2246. {
  2247. let GOOGLE_MAPS_CANVAS = document.querySelector(".game-panorama_panoramaCanvas__PNKve");
  2248. document.querySelector(".ymaps-2-1-79-panorama-screen").style.position = "absolute";
  2249. if (nextPlayer === "Google") {
  2250. document.getElementById("default_player").className = "game-panorama_panoramaCanvas__PNKve";
  2251. document.getElementById("PanoramaMap").className = "inactive";
  2252. document.getElementById("roadview").className = "inactive";
  2253. document.querySelector(".ymaps-2-1-79-panorama-screen").style.visibility = "hidden";
  2254. document.getElementById("Main Button").google = true;
  2255. document.getElementById("switch").nextPlayer = "Google";
  2256. document.getElementById("switch").useGoogle = true;
  2257. document.getElementById("default_player").style.position = "absolute";
  2258. document.querySelector(".compass").style.visibility = "";
  2259. document.querySelector("button[data-qa='undo-move']").visibility = "";
  2260. myLog("Google Duel Canvas loaded");
  2261. }
  2262. else if (nextPlayer === "Baidu")
  2263. {
  2264. document.getElementById("default_player").className = "inactive";
  2265. document.getElementById("PanoramaMap").className = "game-panorama_panorama__rdhFg";
  2266. document.getElementById("roadview").className = "inactive";
  2267. document.getElementById("mly").style.visibility = "hidden";
  2268. document.querySelector(".ymaps-2-1-79-panorama-screen").style.visibility = "hidden";
  2269. document.getElementById("Main Button").google = false;
  2270. document.getElementById("switch").nextPlayer = "Baidu";
  2271. document.getElementById("switch").useGoogle = false;
  2272. document.getElementById("PanoramaMap").style.position = "absolute";
  2273. document.querySelector(".compass").style.visibility = "hidden";
  2274. document.querySelector("button[data-qa='undo-move']").visibility = "hidden";
  2275. myLog("Baidu Duel Canvas loaded");
  2276. }
  2277. else if (nextPlayer === "Kakao")
  2278. {
  2279. document.getElementById("default_player").className = "inactive";
  2280. document.getElementById("PanoramaMap").className = "inactive";
  2281. document.getElementById("roadview").className = "game-panorama_panorama__rdhFg";
  2282. document.getElementById("mly").style.visibility = "hidden";
  2283. document.querySelector(".ymaps-2-1-79-panorama-screen").style.visibility = "hidden";
  2284. document.getElementById("Main Button").google = false;
  2285. document.getElementById("switch").nextPlayer = "Kakao";
  2286. document.getElementById("switch").useGoogle = false;
  2287. document.getElementById("roadview").style.position = "absolute";
  2288. document.querySelector(".compass").style.visibility = "";
  2289. document.querySelector("button[data-qa='undo-move']").visibility = "";
  2290. myLog("Kakao Duel Canvas loaded");
  2291. }
  2292. else if (nextPlayer === "Yandex")
  2293. {
  2294. document.getElementById("default_player").className = "inactive";
  2295. document.getElementById("PanoramaMap").className = "inactive";
  2296. document.getElementById("roadview").className = "inactive";
  2297. document.getElementById("mly").style.visibility = "hidden";
  2298. document.querySelector(".ymaps-2-1-79-panorama-screen").style.visibility = "";
  2299. document.getElementById("Main Button").google = false;
  2300. document.getElementById("switch").nextPlayer = "Yandex";
  2301. document.getElementById("switch").useGoogle = false;
  2302. document.querySelector(".ymaps-2-1-79-panorama-screen").style.position = "absolute";
  2303. document.querySelector(".compass").style.visibility = "";
  2304. document.querySelector("button[data-qa='undo-move']").visibility = "";
  2305. myLog("Yandex Duel Canvas loaded");
  2306. }
  2307. else if (nextPlayer === "Mapillary")
  2308. {
  2309. document.getElementById("default_player").className = "inactive";
  2310. document.getElementById("PanoramaMap").className = "inactive";
  2311. document.getElementById("roadview").className = "inactive";
  2312. document.getElementById("mly").style.visibility = "";
  2313. document.querySelector(".ymaps-2-1-79-panorama-screen").style.visibility = "hidden";
  2314. document.getElementById("Main Button").google = false;
  2315. document.getElementById("switch").nextPlayer = "Mapillary";
  2316. document.getElementById("switch").useGoogle = false;
  2317. document.getElementById("mly").style.position = "absolute";
  2318. document.querySelector(".compass").style.visibility = "hidden";
  2319. document.querySelector("button[data-qa='undo-move']").visibility = "";
  2320. myLog("Mapillary Duel Canvas loaded");
  2321. }
  2322. }
  2323. else
  2324. {
  2325. setTimeout(canvasSwitch, 250);
  2326. }
  2327. }
  2328.  
  2329. // for Battle Royale and classic (change visibility)
  2330.  
  2331. function Google() {
  2332. let GOOGLE_MAPS_CANVAS = ""
  2333. if (isBattleRoyale) {
  2334. GOOGLE_MAPS_CANVAS = document.querySelector(".br-game-layout__panorama-canvas");
  2335. }
  2336. else {
  2337. GOOGLE_MAPS_CANVAS = document.querySelector(".game-layout__panorama-canvas");
  2338. }
  2339. if (nextPlayer === "Google") {
  2340. GOOGLE_MAPS_CANVAS.style.visibility = "";
  2341. document.getElementById("Main Button").google = true;
  2342. document.getElementById("switch").nextPlayer = "Google";
  2343. document.getElementById("switch").useGoogle = true;
  2344. myLog("Google Canvas loaded");
  2345. }
  2346. else {
  2347. GOOGLE_MAPS_CANVAS.style.visibility = "hidden";
  2348. document.getElementById("Main Button").google = false;
  2349. myLog("Google Canvas hidden");
  2350. }
  2351.  
  2352. }
  2353.  
  2354. function Baidu() {
  2355. let BAIDU_MAPS_CANVAS = document.getElementById("PanoramaMap");
  2356. // myLog("Baidu canvas");
  2357. if (BAIDU_MAPS_CANVAS !== null && document.querySelector(".compass") !== null && document.querySelector("button[data-qa='undo-move']") !== null)
  2358. {
  2359. BAIDU_MAPS_CANVAS.style.position = "absolute";
  2360. if (nextPlayer === "Baidu") {
  2361. BAIDU_MAPS_CANVAS.style.visibility = "";
  2362. document.getElementById("switch").nextPlayer = "Baidu";
  2363. document.getElementById("switch").useGoogle = false;
  2364. document.querySelector(".compass").style.visibility = "hidden";
  2365. document.querySelector("button[data-qa='undo-move']").style.visibility = "hidden";
  2366. myLog("Baidu Canvas loaded");
  2367. }
  2368. else {
  2369. document.querySelector(".compass").style.visibility = "";
  2370. document.querySelector("button[data-qa='undo-move']").style.visibility = "";
  2371. BAIDU_MAPS_CANVAS.style.visibility = "hidden";
  2372. myLog("Baidu Canvas hidden");
  2373. }
  2374. }
  2375. else
  2376. {
  2377. setTimeout(Baidu, 250);
  2378. }
  2379.  
  2380. }
  2381.  
  2382. function Kakao() {
  2383. let KAKAO_MAPS_CANVAS = document.getElementById("roadview");
  2384. // myLog("Kakao canvas");
  2385. document.getElementById("roadview").style.position = "absolute";
  2386. if (KAKAO_MAPS_CANVAS != null)
  2387. {
  2388. if (nextPlayer === "Kakao") {
  2389. KAKAO_MAPS_CANVAS.style.visibility = "";
  2390. document.getElementById("switch").nextPlayer = "Kakao";
  2391. document.getElementById("switch").useGoogle = false;
  2392. myLog("Kakao Canvas loaded");
  2393. }
  2394. else {
  2395. KAKAO_MAPS_CANVAS.style.visibility = "hidden";
  2396. myLog("Kakao Canvas hidden");
  2397. }
  2398. }
  2399. else
  2400. {
  2401. setTimeout(Kakao, 250);
  2402. }
  2403.  
  2404. }
  2405.  
  2406. function Yandex() {
  2407. let YANDEX_MAPS_CANVAS = document.querySelector(".ymaps-2-1-79-panorama-screen");
  2408. if (YANDEX_MAPS_CANVAS != null)
  2409. {
  2410. // myLog("Yandex canvas");
  2411. document.querySelector(".ymaps-2-1-79-panorama-screen").style.position = "absolute";
  2412. // myLog("Yandex canvas");
  2413. /* myLog(YANDEX_MAPS_CANVAS); */
  2414. if (nextPlayer === "Yandex") {
  2415. YANDEX_MAPS_CANVAS.style.visibility = "";
  2416. document.getElementById("switch").nextPlayer = "Yandex";
  2417. document.getElementById("switch").useGoogle = false;
  2418. myLog("Yandex Canvas loaded");
  2419. }
  2420. else {
  2421. YANDEX_MAPS_CANVAS.style.visibility = "hidden";
  2422. myLog("Yandex Canvas hidden");
  2423. }
  2424. }
  2425. else
  2426. {
  2427. setTimeout(Yandex, 250);
  2428. }
  2429.  
  2430. }
  2431.  
  2432. function Mapillary()
  2433. {
  2434.  
  2435. let MAPILLARY_MAPS_CANVAS = document.getElementById("mly");
  2436. if (MAPILLARY_MAPS_CANVAS != null)
  2437. {
  2438. // myLog("Mapillary canvas");
  2439. MAPILLARY_MAPS_CANVAS.style.position = "absolute";
  2440. if (nextPlayer === "Mapillary") {
  2441. MAPILLARY_MAPS_CANVAS.style.visibility = "";
  2442. document.getElementById("switch").nextPlayer = "Mapillary";
  2443. document.getElementById("switch").useGoogle = false;
  2444. myLog("Mapillary Canvas loaded");
  2445. }
  2446. else {
  2447. MAPILLARY_MAPS_CANVAS.style.visibility = "hidden";
  2448. myLog("Mapillary Canvas hidden");
  2449. }
  2450. }
  2451. else
  2452. {
  2453. setTimeout(Mapillary, 250);
  2454. }
  2455.  
  2456. }
  2457.  
  2458. /**
  2459. * Adjust button placement
  2460. */
  2461.  
  2462. function ZoomControls() {
  2463. let style = `
  2464. .ymaps-2-1-79-panorama-gotoymaps {display: none !important;}
  2465. .game-layout__controls {bottom: 8rem !important; left: 1rem !important;}
  2466. `;
  2467.  
  2468. let style_element = document.createElement("style");
  2469. style_element.innerHTML = style;
  2470. document.body.appendChild(style_element);
  2471. }
  2472.  
  2473. /**
  2474. * Updates the compass to match Yandex Panorama facing
  2475. */
  2476. function updateCompass() {
  2477. if (!COMPASS) {
  2478. let compass = document.querySelector("img.compass__indicator");
  2479. if (compass != null) {
  2480. COMPASS = compass;
  2481. let direction = YandexPlayer.getDirection()[0] * -1;
  2482. COMPASS.setAttribute("style", `transform: rotate(${direction}deg);`);
  2483. }
  2484. }
  2485. else {
  2486. let direction = YandexPlayer.getDirection()[0] * -1;
  2487. COMPASS.setAttribute("style", `transform: rotate(${direction}deg);`);
  2488. }
  2489. }
  2490.  
  2491. /**
  2492. * Open next location in streetview player given next player and next coordinate
  2493. */
  2494.  
  2495. function goToLocation() {
  2496. myLog("Going to location");
  2497. if (nextPlayer === "Yandex") {
  2498. let options = {};
  2499. YandexPlayer.moveTo([global_lat, global_lng], options);
  2500. YandexPlayer.setDirection([0, 16]);
  2501. YandexPlayer.setSpan([10, 67]);
  2502. }
  2503. else if (nextPlayer === "Baidu") {
  2504. if (document.getElementById("PanoramaMap") !== null)
  2505. {
  2506. let urlStr2 = "https://map.baidu.com/?panotype=street&pid=" + global_BDID + "&panoid=" + global_BDID + "&from=api";
  2507. let urlStr = "https://map.baidu.com/@" + global_BDAh + "," + global_BDBh + "#panoid=" + global_BDID + "&panotype=street&l=12&tn=B_NORMAL_MAP&sc=0&newmap=1&shareurl=1&pid=" + global_BDID;
  2508. // myLog(urlStr)
  2509. if (global_BDAh != null)
  2510. {
  2511. document.getElementById("PanoramaMap").src = urlStr;
  2512. }
  2513. else
  2514. {
  2515. document.getElementById("PanoramaMap").src = urlStr2;
  2516. }
  2517. }
  2518. else
  2519. {
  2520. setTimeout(goToLocation, 250);
  2521. }
  2522. // let a = new BMap.Point(global_lng, global_lat);
  2523. // BaiduPlayer.setPov({ heading: -40, pitch: 6 });
  2524. // BaiduPlayer.setPosition(a);
  2525. }
  2526. else if (nextPlayer === "Kakao") {
  2527. var roadviewClient = new kakao.maps.RoadviewClient();
  2528. var position = new kakao.maps.LatLng(global_lat, global_lng);
  2529. roadviewClient.getNearestPanoId(position, 500, function (panoId) {
  2530. KakaoPlayer.setPanoId(panoId, position);
  2531. KakaoPlayer.setViewpoint({ pan: global_heading, tilt: global_pitch, zoom: -3 })
  2532. });
  2533. }
  2534. else if (nextPlayer === "Mapillary") {
  2535. MapillaryPlayer.moveTo(mmKey).then(
  2536. image => { //myLog(image);
  2537. },
  2538. error => { myLog(error); });
  2539. }
  2540. else if (nextPlayer === "Google") {
  2541. handleMapillary({lat: global_lat, lng: global_lng}, {meters: 500, limit: 500});
  2542. }
  2543. document.getElementById("switch").lat = global_lat;
  2544. document.getElementById("switch").lng = global_lng;
  2545. }
  2546.  
  2547. /**
  2548. * Handle undo using the location history of the current round
  2549. */
  2550.  
  2551. function goToUndoMove(data) {
  2552. /* myLog(global_lat);
  2553. myLog(global_lng); */
  2554. let options = {};
  2555. let prevStep = null;
  2556. if (locHistory.length === 1) {
  2557. prevStep = locHistory[0];
  2558. }
  2559. else {
  2560. prevStep = locHistory.pop();
  2561. }
  2562. // myLog(prevStep);
  2563. // myLog(locHistory)
  2564. if (nextPlayer === "Yandex") {
  2565. defaultPanoIdChange = false;
  2566. YandexPlayer.moveTo([prevStep[0], prevStep[1]], options);
  2567. YandexPlayer.setDirection([prevStep[2], prevStep[3]]);
  2568. YandexPlayer.setSpan([10, 67]);
  2569. document.getElementById("switch").lat = prevStep[0];
  2570. document.getElementById("switch").lng = prevStep[1];
  2571. }
  2572. else if (nextPlayer === "Kakao") {
  2573. let btn = document.querySelector("button[data-qa='undo-move']");
  2574. btn.disabled = false;
  2575. btn.classList.remove('styles_disabled__W_k45');
  2576. defaultPanoIdChange = false;
  2577. let position = new kakao.maps.LatLng(prevStep[0], prevStep[1]);
  2578. KakaoPlayer.setPanoId(prevStep[2], position);
  2579. document.getElementById("switch").lat = prevStep[0];
  2580. document.getElementById("switch").lng = prevStep[1];
  2581. document.getElementById("switch").useGoogle = false;
  2582. document.getElementById("Main Button").google = false;
  2583. // myLog("Undo 1 step");
  2584. // myLog(locHistory);
  2585. }
  2586. else if (nextPlayer === "Baidu") {
  2587. // myLog(prevStep[1]);
  2588. // let position = new BMap.Point(prevStep[1], prevStep[0]);
  2589. // let pov = { heading: prevStep[2], pitch: prevStep[3] };
  2590. // BaiduPlayer.setPosition(position);
  2591. // BaiduPlayer.setPov(pov);
  2592. // document.getElementById("switch").lat = prevStep[1];
  2593. // document.getElementById("switch").lng = prevStep[0];
  2594. }
  2595. else if (nextPlayer === "Mapillary" ) {
  2596. // myLog(prevStep[1]);
  2597.  
  2598. MapillaryPlayer.moveTo(prevStep[2]).then(
  2599. image => {
  2600. //myLog(image);
  2601. document.getElementById("switch").lat = prevStep[1];
  2602. document.getElementById("switch").lng = prevStep[0];
  2603. },
  2604. error => { myLog(error); });
  2605. }
  2606.  
  2607. }
  2608.  
  2609. function BYKTeleport()
  2610. {
  2611. let teleportButtonBYK = document.getElementById("Main Button");
  2612. if (teleportButtonBYK)
  2613. {
  2614. teleportButtonBYK.addEventListener("click", () => {
  2615. if (!teleportButtonBYK.google)
  2616. {
  2617. // myLog("non-Google Teleport");
  2618. let prevStep = null;
  2619. if (locHistory.length === 1) {
  2620. prevStep = locHistory[0];
  2621. }
  2622. else {
  2623. prevStep = locHistory[locHistory.length - 1];
  2624. }
  2625. // myLog(prevStep);
  2626. let options = {};
  2627. let place, position, pID;
  2628. if (nextPlayer === "Yandex") {
  2629. place = FindPointAtDistanceFrom(prevStep[0], prevStep[1], DegreesToRadians(prevStep[2]), teleportButtonBYK.distance * 0.001);
  2630. YandexPlayer.setDirection([prevStep[2], prevStep[3]]);
  2631. YandexPlayer.moveTo([place.lat, place.lng], options);
  2632. YandexPlayer.setSpan([10, 67]);
  2633. // locHistory.push([place.lat, place.lng, prevStep[2], prevStep[3]]);
  2634. }
  2635. else if (nextPlayer === "Kakao") {
  2636. // place = FindPointAtDistanceFrom(prevStep[0], prevStep[1], DegreesToRadians(prevStep[3]), teleportButtonBYK.distance * 0.001);
  2637. // position = new kakao.maps.LatLng(place.lat, place.lng);
  2638. // pID = KakaoPlayer.getViewpointWithPanoId();
  2639. // KakaoPlayer.setPanoId(pID.panoId, position);
  2640. // locHistory.push([place.lat, place.lng, pID.panoId, prevStep[3]]);
  2641. var roadviewClient = new kakao.maps.RoadviewClient();
  2642. place = FindPointAtDistanceFrom(prevStep[0], prevStep[1], DegreesToRadians(prevStep[3]), teleportButtonBYK.distance * 0.001);
  2643. position = new kakao.maps.LatLng(place.lat, place.lng);
  2644. roadviewClient.getNearestPanoId(position, 500, function (panoId) {
  2645. KakaoPlayer.setPanoId(panoId, position);
  2646. // myLog("Teleport 1 step");
  2647. // myLog(locHistory);
  2648. // locHistory.push([place.lat, place.lng, panoId, prevStep[3]]);
  2649. });
  2650. }
  2651. else if (nextPlayer === "Baidu") {
  2652. // place = FindPointAtDistanceFrom(prevStep[0], prevStep[1], DegreesToRadians(prevStep[2]), teleportButtonBYK.distance * 0.001);
  2653. // position = new BMap.Point(place.lng, place.lat);
  2654. // let pov = { heading: prevStep[2], pitch: prevStep[3] };
  2655. // BaiduPlayer.setPosition(position);
  2656. // BaiduPlayer.setPov(pov);
  2657.  
  2658. // locHistory.push([place.lat, place.lng, prevStep[2], prevStep[3]]);
  2659. }
  2660. else if (nextPlayer === "Mapillary" || nextPlayer === "Google") {
  2661. place = FindPointAtDistanceFrom(prevStep[0], prevStep[1], DegreesToRadians(prevStep[2]), teleportButtonBYK.distance * 0.001);
  2662. handleMapillary(place, {meters: 500, limit: 500});
  2663. // locHistory.push([place.lat, place.lng, prevStep[2], prevStep[3]]);
  2664. }
  2665. document.getElementById("switch").lat = place.lat;
  2666. document.getElementById("switch").lng = place.lng;
  2667. if (teleportButtonBYK.distance > 150)
  2668. {
  2669. teleportButtonBYK.distance = 100;
  2670. teleportButtonBYK.innerHTML = "Teleport " + teleportButtonBYK.distance + " m";
  2671. }
  2672. }
  2673. });
  2674. }
  2675. else
  2676. {
  2677. }
  2678. }
  2679.  
  2680. function SyncListener()
  2681. {
  2682. let googleKakaoButton = document.getElementById("switch");
  2683. googleKakaoButton.addEventListener("click", () => {
  2684. if (googleKakaoButton.useGoogle == false) {
  2685. // googleKakaoButton.useGoogle = true;
  2686. if (googleKakaoButton.nextPlayer === "Yandex") {
  2687. let options = {};
  2688. YandexPlayer.moveTo([googleKakaoButton.lat, googleKakaoButton.lng], options);
  2689. YandexPlayer.setDirection([document.getElementById("switch").heading, 0]);
  2690.  
  2691. // document.getElementById("switch").nextPlayer = "Yandex";
  2692. }
  2693. else if (googleKakaoButton.nextPlayer === "Kakao") {
  2694. let roadviewClient = new kakao.maps.RoadviewClient();
  2695. // myLog(googleKakaoButton.lat);
  2696. let position = new kakao.maps.LatLng(googleKakaoButton.lat, googleKakaoButton.lng);
  2697. roadviewClient.getNearestPanoId(position, 500, function (panoId) {
  2698. KakaoPlayer.setPanoId(panoId, position);
  2699. });
  2700. KakaoPlayer.setViewpoint({
  2701. pan: document.getElementById("switch").heading,
  2702. tilt: 0,
  2703. zoom: 0
  2704. });
  2705. // document.getElementById("switch").nextPlayer = "Kakao";
  2706. }
  2707. else if (googleKakaoButton.nextPlayer === "Mapillary" || googleKakaoButton.nextPlayer === "Google") {
  2708. // document.getElementById("switch").nextPlayer = "Kakao";
  2709. handleMapillary({lat: googleKakaoButton.lat, lng: googleKakaoButton.lng}, {meters: 100, limit: 100});
  2710. }
  2711. }
  2712. });
  2713.  
  2714. }
  2715.  
  2716. /**
  2717. * Gets the seed data for the current game
  2718. *
  2719. * @returns Promise with seed data as object
  2720. */
  2721. function getSeed() {
  2722. // myLog("getSeed called");
  2723. return new Promise((resolve, reject) => {
  2724. let token = getToken();
  2725. let URL;
  2726. let cred = ""
  2727.  
  2728. const PATHNAME = window.location.pathname;
  2729.  
  2730. if (PATHNAME.startsWith("/game/")) {
  2731. URL = `https://www.geoguessr.com/api/v3/games/${token}`;
  2732. }
  2733. else if (PATHNAME.startsWith("/challenge/")) {
  2734. URL = `https://www.geoguessr.com/api/v3/challenges/${token}/game`;
  2735. }
  2736. else if (PATHNAME.startsWith("/battle-royale/")) {
  2737. URL = `https://game-server.geoguessr.com/api/battle-royale/${token}`;
  2738. }
  2739. else if (PATHNAME.startsWith("/duels/") || PATHNAME.startsWith("/team-duels/")) {
  2740. URL = `https://game-server.geoguessr.com/api/duels/${token}`;
  2741. }
  2742. if (isBattleRoyale) {
  2743. fetch(URL, {
  2744. // Include credentials to GET from the endpoint
  2745. credentials: 'include'
  2746. })
  2747. .then((response) => response.json())
  2748. .then((data) => {
  2749. resolve(data);
  2750. })
  2751. .catch((error) => {
  2752. reject(error);
  2753. });
  2754. }
  2755. else {
  2756. fetch(URL)
  2757. .then((response) => response.json())
  2758. .then((data) => {
  2759. resolve(data);
  2760. })
  2761. .catch((error) => {
  2762. reject(error);
  2763. });
  2764. }
  2765. });
  2766. }
  2767.  
  2768. /**
  2769. * Gets the token from the current URL
  2770. *
  2771. * @returns token
  2772. */
  2773. function getToken() {
  2774. const PATHNAME = window.location.pathname;
  2775. if (PATHNAME.startsWith("/game/")) {
  2776. return PATHNAME.replace("/game/", "");
  2777. }
  2778. else if (PATHNAME.startsWith("/challenge/")) {
  2779. return PATHNAME.replace("/challenge/", "");
  2780. }
  2781. else if (PATHNAME.startsWith("/battle-royale/")) {
  2782. return PATHNAME.replace("/battle-royale/", "");
  2783. }
  2784. else if (PATHNAME.startsWith("/duels/")) {
  2785. return PATHNAME.replace("/duels/", "");
  2786. }
  2787. else if (PATHNAME.startsWith("/team-duels/")) {
  2788. return PATHNAME.replace("/team-duels/", "");
  2789. }
  2790. }
  2791.  
  2792. /**
  2793. * Gets the round number from the ongoing game from the page itself
  2794. *
  2795. * @returns Round number
  2796. */
  2797. function getRoundFromPage() {
  2798. const roundData = document.querySelector("div[data-qa='round-number']");
  2799. if (roundData) {
  2800. let roundElement = roundData.querySelector("div:last-child");
  2801. if (roundElement) {
  2802. let round = parseInt(roundElement.innerText.charAt(0));
  2803. if (!isNaN(round) && round >= 1 && round <= 5) {
  2804. return round;
  2805. }
  2806. }
  2807. }
  2808. else {
  2809. return ROUND;
  2810. }
  2811. }
  2812.  
  2813.  
  2814. /**
  2815. * Injects Yandex Script
  2816. */
  2817. function injectYandexScript() {
  2818. return new Promise((resolve, reject) => {
  2819. if (!YANDEX_INJECTED) {
  2820. if (YANDEX_API_KEY === "") {
  2821. myLog("No Yandex Key")
  2822. reject();
  2823. }
  2824. else {
  2825. const SCRIPT = document.createElement("script");
  2826. SCRIPT.type = "text/javascript";
  2827. SCRIPT.async = true;
  2828. SCRIPT.onload = () => {
  2829. ymaps.ready(() => {
  2830. YANDEX_INJECTED = true;
  2831. myHighlight("Yandex API Loaded");
  2832. resolve();
  2833. });
  2834. }
  2835. SCRIPT.src = `https://api-maps.yandex.ru/2.1/?lang=en_US&apikey=${YANDEX_API_KEY}`;
  2836. document.body.appendChild(SCRIPT);
  2837. }
  2838. }
  2839. else {
  2840. resolve();
  2841. }
  2842. });
  2843. }
  2844.  
  2845. /**
  2846. * Injects Yandex Player and calls handleReturnToStart
  2847. */
  2848. function injectYandexPlayer() {
  2849. let lat = 41.321861;
  2850. let lng = 69.212920;
  2851.  
  2852. let options = {
  2853. "direction": [0, 16],
  2854. "span": [10, 67],
  2855. "controls": ["zoomControl"]
  2856. };
  2857. ymaps.panorama.createPlayer("player", [lat, lng], options)
  2858. .done((player) => {
  2859. YandexPlayer = player;
  2860. YandexPlayer.events.add("directionchange", (e) => {
  2861. updateCompass();
  2862. let pov = YandexPlayer.getDirection();
  2863. if (locHistory.length > 0 && nextPlayer == "Yandex") {
  2864. document.getElementById("switch").heading = pov[0];
  2865. locHistory[locHistory.length - 1][2] = pov[0];
  2866. locHistory[locHistory.length - 1][3] = pov[1];
  2867. }
  2868. });
  2869. YandexPlayer.events.add("panoramachange", (e) => {
  2870. if (defaultPanoIdChange) {
  2871. let num = YandexPlayer.getPanorama().getPosition();
  2872. let pov = YandexPlayer.getDirection();
  2873. // myLog(num);
  2874. // myLog(pov);
  2875. if (nextPlayer == "Yandex")
  2876. {
  2877. locHistory.push([num[0], num[1], pov[0], pov[1]]);
  2878. document.getElementById("switch").lat = num[0];
  2879. document.getElementById("switch").lng = num[1];
  2880. }
  2881. let btn = document.querySelector("button[data-qa='undo-move']");
  2882. if (locHistory.length > 1) {
  2883. btn.disabled = false;
  2884. btn.classList.remove('styles_disabled__W_k45');
  2885. }
  2886. // myLog(locHistory);
  2887. }
  2888. defaultPanoIdChange = true;
  2889.  
  2890. });
  2891. myLog("Yandex Player injected");
  2892. });
  2893.  
  2894. }
  2895.  
  2896.  
  2897. /**
  2898. * Injects Baidu script
  2899. */
  2900.  
  2901. function reportWindowSize() {
  2902. let iframeC = document.getElementById("PanoramaMap");
  2903. if (iframeC)
  2904. {
  2905. iframeC.style.top = '-60px';
  2906. iframeC.style.height = (window.innerHeight + 200) + 'px';
  2907. iframeC.style.right = '-55px';
  2908. iframeC.style.width = (window.innerWidth + 55) + 'px';
  2909. }
  2910. }
  2911.  
  2912. window.onresize = reportWindowSize;
  2913.  
  2914. function injectBaiduScript() {
  2915. myLog("Iframe")
  2916. const iframe = document.createElement('iframe');
  2917.  
  2918. // iframe.src = "https://map.baidu.com/"
  2919. iframe.frameBorder = 0;
  2920. iframe.style.position = "absolute";
  2921. iframe.id = "PanoramaMap";
  2922. if (!isFirefox)
  2923. {
  2924. iframe.style.top = '-60px';
  2925. iframe.style.height = (window.innerHeight + 200) + 'px';
  2926. }
  2927. else
  2928. {
  2929. iframe.style.top = '-60px';
  2930. iframe.style.height = (window.innerHeight + 219) + 'px';
  2931. }
  2932.  
  2933. if (!isFirefox)
  2934. {
  2935. iframe.style.right = '-55px';
  2936. iframe.style.width = (window.innerWidth + 55) + 'px';
  2937. }
  2938. else
  2939. {
  2940. iframe.style.right = '-15px';
  2941. iframe.style.width = (window.innerWidth + 15) + 'px';
  2942. }
  2943.  
  2944.  
  2945.  
  2946. if (isBattleRoyale) {
  2947. if (isDuel)
  2948. {
  2949. iframe.className = "inactive"
  2950. }
  2951. else
  2952. {
  2953. iframe.className = "br-game-layout__panorama"
  2954. }
  2955. }
  2956. else {
  2957. iframe.className = "game-layout__panorama"
  2958. }
  2959. var div = document.getElementById("player");
  2960. div.style.overflow = "hidden";
  2961. div.appendChild(iframe);
  2962. }
  2963.  
  2964. /**
  2965. * Injects Kakao script
  2966. */
  2967.  
  2968. function injectKakaoScript() {
  2969. return new Promise((resolve, reject) => {
  2970. if (!KAKAO_INJECTED) {
  2971. if (KAKAO_API_KEY === "") {
  2972. myLog("No Kakao Key")
  2973. }
  2974. else {
  2975.  
  2976. let canvas = document.createElement("kmap");
  2977. if (isBattleRoyale) {
  2978. if (isDuel)
  2979. {
  2980. canvas.innerHTML = `
  2981. <div id="roadview" class="inactive" style="zIndex: 99999,position: "absolute", top: 0, left: 0, width: '100%', height: '100%',"> </div>
  2982. `;
  2983. }
  2984. else
  2985. {
  2986. canvas.innerHTML = `
  2987. <div id="roadview" class="br-game-layout__panorama" style="zIndex: 99999,position: "absolute", top: 0, left: 0, width: '100%', height: '100%',"> </div>
  2988. `;
  2989. }
  2990. }
  2991. else {
  2992. canvas.innerHTML = `
  2993. <div id="roadview" class="game-layout__panorama" style="zIndex: 99999,position: "absolute", top: 0, left: 0, width: '100%', height: '100%',"> </div>
  2994. `;
  2995. }
  2996.  
  2997. var div = document.getElementById("player");
  2998. div.appendChild(canvas);
  2999.  
  3000. const SCRIPT = document.createElement("script");
  3001. SCRIPT.async = true;
  3002. // SCRIPT.type = "text/javascript";
  3003. SCRIPT.src = `//dapi.kakao.com/v2/maps/sdk.js?appkey=${KAKAO_API_KEY}&autoload=false`;
  3004. document.body.appendChild(SCRIPT);
  3005. SCRIPT.onload = () => {
  3006. kakao.maps.load(function () {
  3007. var position = new kakao.maps.LatLng(33.450701, 126.560667);
  3008. let roadviewContainer = document.getElementById('roadview');
  3009. KakaoPlayer = new kakao.maps.Roadview(roadviewContainer);
  3010. var panoId = 1023434522;
  3011. KakaoPlayer.setPanoId(panoId, position);
  3012. KAKAO_INJECTED = true;
  3013. // Remove the compass from Kakao
  3014. kakao.maps.event.addListener(KakaoPlayer, 'init', () => {
  3015. const compassContainer = roadviewContainer.querySelector('div[id*="_box_util_"]');
  3016. if (compassContainer) compassContainer.style.display = 'none';
  3017. });
  3018. kakao.maps.event.addListener(KakaoPlayer, 'panoid_changed', function() {
  3019. if (defaultPanoIdChange && KakaoPlayer) {
  3020. let latlng = KakaoPlayer.getPosition();
  3021. let lat = latlng.getLat();
  3022. let lng = latlng.getLng();
  3023. let pID = KakaoPlayer.getViewpointWithPanoId();
  3024. if (nextPlayer == "Kakao" && lat != 33.45047613915499)
  3025. {
  3026. // myLog("push");
  3027. locHistory.push([lat, lng, pID.panoId, pID.pan]);
  3028. document.getElementById("switch").lat = lat;
  3029. document.getElementById("switch").lng = lng;
  3030. document.getElementById("switch").heading = pID.pan;
  3031. }
  3032. let btn = document.querySelector("button[data-qa='undo-move']");
  3033. if (locHistory.length > 1 && (btn != null)) {
  3034. btn.disabled = false;
  3035. btn.classList.remove('styles_disabled__W_k45');
  3036. }
  3037. // myLog(locHistory);
  3038. }
  3039. defaultPanoIdChange = true;
  3040. });
  3041. kakao.maps.event.addListener(KakaoPlayer, 'viewpoint_changed', function() {
  3042. // myLog("pov_listener attached");
  3043. let pID = KakaoPlayer.getViewpointWithPanoId();
  3044. if (locHistory.length > 0 && nextPlayer == "Kakao") {
  3045. document.getElementById("switch").heading = pID.pan;
  3046. locHistory[locHistory.length - 1][3] = pID.pan;
  3047. }
  3048. if (GooglePlayer) {
  3049. const { heading, pitch } = GooglePlayer.getPov()
  3050. if ((!almostEqual(pID.pan, heading) || !almostEqual(pID.tilt, pitch)) && nextPlayer == "Kakao") {
  3051. // Updating the google street view POV will update the compass
  3052. GooglePlayer.setPov({ heading: pID.pan, pitch: pID.tilt })
  3053. }
  3054. }
  3055. // myLog(locHistory);
  3056. })
  3057. myHighlight("Kakao API Loaded");
  3058. resolve();
  3059. });
  3060. };
  3061.  
  3062. }
  3063. }
  3064. else {
  3065. resolve();
  3066. }
  3067. });
  3068. }
  3069.  
  3070.  
  3071.  
  3072. function injectMapillaryPlayer() {
  3073. return new Promise((resolve, reject) => {
  3074. if (!MAPILLARY_INJECTED) {
  3075. if (MAPILLARY_API_KEY === "") {
  3076. let canvas = document.getElementById("player");
  3077. myLog("No Mapillary Key")
  3078. }
  3079. else {
  3080. const SCRIPT = document.createElement("script");
  3081. SCRIPT.type = "text/javascript";
  3082. SCRIPT.async = true;
  3083. SCRIPT.src = `https://unpkg.com/mapillary-js@4.0.0/dist/mapillary.js`;
  3084. document.body.appendChild(SCRIPT);
  3085. document.querySelector('head').innerHTML += '<link href="https://unpkg.com/mapillary-js@4.0.0/dist/mapillary.css" rel="stylesheet"/>';
  3086. let canvas = document.createElement("mmap");
  3087. if (isBattleRoyale) {
  3088. if (isDuel)
  3089. {
  3090.  
  3091. canvas.innerHTML = `<div id="mly" class="inactive" style="zIndex: 99999, position: 'absolute', top: 0, left: 0, width: '100%', height: '100%'"></div>`;
  3092. }
  3093. else
  3094. {
  3095. canvas.innerHTML = `<div id="mly" class="br-game-layout__panorama" style="zIndex: 99999, position: 'absolute', top: 0, left: 0, width: '100%', height: '100%'"></div>`;
  3096. }
  3097. }
  3098. else {
  3099. canvas.innerHTML = `<div id="mly" class="game-layout__panorama" style="zIndex: 99999, position: 'absolute', top: 0, left: 0, width: '100%', height: '100%'"></div>`;
  3100. }
  3101.  
  3102. var div = document.getElementById("player");
  3103. div.appendChild(canvas);
  3104.  
  3105. SCRIPT.addEventListener('load', () => {
  3106. myHighlight("Mapillary API Loaded");
  3107. // resolve(BMap);
  3108. var {Viewer} = mapillary;
  3109.  
  3110. MapillaryPlayer = new Viewer({
  3111. accessToken: MAPILLARY_API_KEY,
  3112. container: 'mly', // the ID of our container defined in the HTML body
  3113. });
  3114.  
  3115. MapillaryPlayer.on('image', async (event) => {
  3116. // cnt = cnt + 1;
  3117. // myLog(cnt);
  3118. let image = event.image;
  3119. let pos = image.originalLngLat;
  3120. let cond = true;
  3121. for (const element of locHistory) {
  3122. if (element[2] == image.id)
  3123. {
  3124. cond = false;
  3125. }
  3126. }
  3127. if (cond)
  3128. {
  3129. document.getElementById("switch").lat = pos.lat;
  3130. document.getElementById("switch").lng = pos.lng;
  3131. document.getElementById("switch").heading = image.compassAngle;
  3132. // myLog(pos);
  3133. locHistory.push([pos.lat, pos.lng, image.id, image.compassAngle]);
  3134. }
  3135. let btn = document.querySelector("button[data-qa='undo-move']");
  3136. if (btn !== null && locHistory.length > 1)
  3137. {
  3138. btn.disabled = false;
  3139. btn.classList.remove('styles_disabled__W_k45');
  3140. }
  3141. });
  3142.  
  3143. MAPILLARY_INJECTED = true;
  3144. resolve();
  3145. })
  3146.  
  3147.  
  3148. }
  3149. }
  3150. else {
  3151. resolve();
  3152. }
  3153. });
  3154. }
  3155.  
  3156.  
  3157. function handleMapillary(latlng, options)
  3158. {
  3159. myLog("handleMapillary")
  3160. handleMapillaryHelper(latlng, options).then((data) => {
  3161. //myLog(data.data)
  3162. let idToSet = 0;
  3163. let curDist = 100000000;
  3164. for (const element of data.data) {
  3165. // myLog(element)
  3166. if (element.hasOwnProperty("computed_geometry"))
  3167. {
  3168. try {
  3169. let rCord = element.computed_geometry["coordinates"];
  3170. let dist = distance(latlng.lat,latlng.lng,rCord[1],rCord[0])
  3171. if (dist < curDist)
  3172. {
  3173. idToSet = element.id;
  3174. curDist = dist
  3175. }
  3176. } catch (e) {
  3177. myLog("Error")
  3178. }
  3179. }
  3180. }
  3181. if (idToSet !== 0)
  3182. {
  3183. MapillaryPlayer.moveTo(idToSet).then(
  3184. image => { //myLog(image);
  3185. },
  3186. error => { myLog(error); });
  3187. }}).catch((error) => {
  3188. myLog(error);
  3189. });
  3190. }
  3191.  
  3192. function handleMapillaryHelper(latlng, options)
  3193. {
  3194. return new Promise((resolve, reject) => {
  3195. // myLog("1")
  3196. let bbox = getBBox(latlng, options.meters);
  3197. let URL = "https://graph.mapillary.com/images?access_token={0}&fields=id,computed_geometry&bbox={1}&limit={2}".replace('{0}', MAPILLARY_API_KEY).replace('{1}', bbox).replace('{2}', options.limit)
  3198. // myLog(URL)
  3199. fetch(URL)
  3200. .then((response) => {resolve(response.json())})
  3201. .catch((error) => {myLog(error);});
  3202. });
  3203. }
  3204.  
  3205. function moveFrom(coords, angle, distance){
  3206. const R_EARTH = 6378.137;
  3207. const M = (1 / ((2 * Math.PI / 360) * R_EARTH)) / 1000;
  3208. let radianAngle = -angle * Math.PI / 180;
  3209. let x = 0 + (distance * Math.cos(radianAngle));
  3210. let y = 0 + (distance * Math.sin(radianAngle));
  3211.  
  3212. let newLat = coords.lat + (y * M);
  3213. let newLng = coords.lng + (x * M) / Math.cos(coords.lat * (Math.PI / 180));
  3214. return { lat: newLat, lng: newLng };
  3215. }
  3216.  
  3217. function getBBox(coordinates, meters){
  3218. let SW = moveFrom(coordinates, 135, meters);
  3219. let NE = moveFrom(coordinates, 315, meters);
  3220. return `${SW.lng},${SW.lat},${NE.lng},${NE.lat}`;
  3221. }
  3222.  
  3223.  
  3224. function distance(lat1, lon1, lat2, lon2) {
  3225. var p = 0.017453292519943295; // Math.PI / 180
  3226. var c = Math.cos;
  3227. var a = 0.5 - c((lat2 - lat1) * p)/2 +
  3228. c(lat1 * p) * c(lat2 * p) *
  3229. (1 - c((lon2 - lon1) * p))/2;
  3230.  
  3231. return 1000 * 12742 * Math.asin(Math.sqrt(a)); // 2 * R; R = 6371 km
  3232. }
  3233.  
  3234.  
  3235. /**
  3236. * Minimap presets
  3237. */
  3238.  
  3239. let water_name_only =
  3240. [
  3241. {
  3242. "elementType": "geometry",
  3243. "stylers": [
  3244. {
  3245. "visibility": "off"
  3246. }
  3247. ]
  3248. },
  3249. {
  3250. "featureType": "administrative",
  3251. "stylers": [
  3252. {
  3253. "visibility": "off"
  3254. }
  3255. ]
  3256. },
  3257. {
  3258. "featureType": "landscape",
  3259. "stylers": [
  3260. {
  3261. "visibility": "off"
  3262. }
  3263. ]
  3264. },
  3265. {
  3266. "featureType": "poi",
  3267. "stylers": [
  3268. {
  3269. "visibility": "off"
  3270. }
  3271. ]
  3272. },
  3273. {
  3274. "featureType": "road",
  3275. "stylers": [
  3276. {
  3277. "visibility": "off"
  3278. }
  3279. ]
  3280. },
  3281. {
  3282. "featureType": "transit",
  3283. "stylers": [
  3284. {
  3285. "visibility": "off"
  3286. }
  3287. ]
  3288. }
  3289. ]
  3290. let country_name_only =
  3291. [
  3292. {
  3293. "elementType": "geometry",
  3294. "stylers": [
  3295. {
  3296. "visibility": "off"
  3297. }
  3298. ]
  3299. },
  3300. {
  3301. "featureType": "administrative",
  3302. "stylers": [
  3303. {
  3304. "visibility": "off"
  3305. }
  3306. ]
  3307. },
  3308. {
  3309. "featureType": "administrative.country",
  3310. "elementType": "labels",
  3311. "stylers": [
  3312. {
  3313. "visibility": "on"
  3314. }
  3315. ]
  3316. },
  3317. {
  3318. "featureType": "landscape",
  3319. "stylers": [
  3320. {
  3321. "visibility": "off"
  3322. }
  3323. ]
  3324. },
  3325. {
  3326. "featureType": "poi",
  3327. "stylers": [
  3328. {
  3329. "visibility": "off"
  3330. }
  3331. ]
  3332. },
  3333. {
  3334. "featureType": "road",
  3335. "stylers": [
  3336. {
  3337. "visibility": "off"
  3338. }
  3339. ]
  3340. },
  3341. {
  3342. "featureType": "transit",
  3343. "stylers": [
  3344. {
  3345. "visibility": "off"
  3346. }
  3347. ]
  3348. },
  3349. {
  3350. "featureType": "water",
  3351. "stylers": [
  3352. {
  3353. "visibility": "off"
  3354. }
  3355. ]
  3356. }
  3357. ]
  3358.  
  3359. let no_label_or_terrain =
  3360. [
  3361. {
  3362. "elementType": "geometry",
  3363. "stylers": [
  3364. {
  3365. "visibility": "off"
  3366. }
  3367. ]
  3368. },
  3369. {
  3370. "featureType": "administrative",
  3371. "stylers": [
  3372. {
  3373. "visibility": "off"
  3374. }
  3375. ]
  3376. },
  3377. {
  3378. "featureType": "landscape",
  3379. "stylers": [
  3380. {
  3381. "visibility": "off"
  3382. }
  3383. ]
  3384. },
  3385. {
  3386. "featureType": "poi",
  3387. "stylers": [
  3388. {
  3389. "visibility": "off"
  3390. }
  3391. ]
  3392. },
  3393. {
  3394. "featureType": "road",
  3395. "stylers": [
  3396. {
  3397. "visibility": "off"
  3398. }
  3399. ]
  3400. },
  3401. {
  3402. "featureType": "transit",
  3403. "stylers": [
  3404. {
  3405. "visibility": "off"
  3406. }
  3407. ]
  3408. },
  3409. {
  3410. "featureType": "water",
  3411. "stylers": [
  3412. {
  3413. "visibility": "on"
  3414. }
  3415. ]
  3416. },
  3417. {
  3418. "featureType": "water",
  3419. "elementType": "labels",
  3420. "stylers": [
  3421. {
  3422. "visibility": "off"
  3423. }
  3424. ]
  3425. }
  3426. ]
  3427.  
  3428. let no_label =
  3429. [
  3430. {
  3431. "elementType": "labels",
  3432. "stylers": [
  3433. {
  3434. "visibility": "off"
  3435. }
  3436. ]
  3437. },
  3438. {
  3439. "featureType": "administrative",
  3440. "stylers": [
  3441. {
  3442. "visibility": "off"
  3443. }
  3444. ]
  3445. }
  3446. ]
  3447.  
  3448. let default_preset = []
  3449.  
  3450. let presetMinimap = [[default_preset, "Default"],
  3451. [water_name_only, "Oceanman"],
  3452. [country_name_only, "Impossible"],
  3453. [no_label_or_terrain, "Streaks"],
  3454. [no_label, "Easy 5K"],
  3455. [default_preset, "Satellite"],
  3456. [default_preset, "Terrain"],
  3457. [default_preset, "Hybrid"],
  3458. [custom, "Custom", customMode]]
  3459.  
  3460.  
  3461. /**
  3462. * Display map per local laws and regulations
  3463. */
  3464.  
  3465. let historicalOverlay, historicalOverlay2, historicalOverlay3;
  3466. let TW = [[24.80, 119.00, 22.00, 123.20],
  3467. [24.20, 119.90, 22.90, 121.85],
  3468. [24.00, 120.90, 23.80, 121.20],
  3469. [23.93, 121.03, 23.85, 121.15],
  3470. [23.92, 121.055, 23.89, 121.10],
  3471. [23.92, 121.055, 23.89, 121.10],
  3472. [23.92, 121.055, 23.89, 121.10],
  3473. ]
  3474.  
  3475. let TS = [[30.40, 93.40, 28, 97.20],
  3476. [29.40, 94.55, 28.20, 96.45]]
  3477.  
  3478. let NW = [36.20, 77.70, 34.40, 80.70]