Geoguessr Baidu Yandex Kakao Script with Aris

Play Geoguessr with Yandex and Baidu streetviews. Credit to kommu and MrAmericanMike to the original Yandex Script. Thanks to Alok, Mapper for advise for map making.

目前为 2021-12-09 提交的版本。查看 最新版本

  1. // ==UserScript==
  2. // @name Geoguessr Baidu Yandex Kakao Script with Aris
  3. // @description Play Geoguessr with Yandex and Baidu streetviews. Credit to kommu and MrAmericanMike to the original Yandex Script. Thanks to Alok, Mapper for advise for map making.
  4. // @version 3.0.0b
  5. // @include https://www.geoguessr.com/*
  6. // @run-at document-start
  7. // @license MIT
  8. // @namespace https://greasyfork.org/users/838374
  9. // ==/UserScript==
  10.  
  11. var YANDEX_API_KEY = "b704b5a9-3d67-4d19-b702-ec7807cecfc6";
  12. var BAIDU_API_KEY = "8dQ9hZPGEQnqg9r0O1C8Ate2N6P8Zk92";
  13. var KAKAO_API_KEY = "cbacbe41e3a223d794f321de4f3e247b";
  14.  
  15. myLog("Geoguessr Baidu Yandex Plugin");
  16.  
  17. const MAPS_API_URL = "https://maps.googleapis.com/maps/api/js?";
  18.  
  19. let PLAYER = null;
  20. let PLAYER2 = null;
  21. let PLAYER3 = null;
  22. let rv = null;
  23. let ROUND = 0;
  24. let YANDEX_INJECTED = false;
  25. let BAIDU_INJECTED = false;
  26. let KAKAO_INJECTED = false;
  27. let NEW_ROUND_LOADED = false;
  28. let COMPASS = null;
  29. let PANORAMA_MAP = false;
  30. let CURRENT_ROUND_DATA = null;
  31. let nextPlayer = "Google";
  32. let global_lat = 0;
  33. let global_lng = 0;
  34. let global_panoID = null;
  35. let playerLoaded = false;
  36.  
  37. let BR = false;
  38. let eventlistener = false;
  39. let loc_list = [];
  40. let pops = true;
  41.  
  42. let teleportLoaded = false;
  43.  
  44. let krCoordinates = [38.75292321084364, 124.2804539232574, 33.18509676203202, 129.597381999198]
  45. let yandex_map = false;
  46.  
  47.  
  48. /**
  49. * Helper Functions
  50. */
  51.  
  52. function myLog(...args) {
  53. console.log(...args);
  54. }
  55. function myHighlight(...args) {
  56. console.log(`%c${[...args]}`, "color: dodgerblue; font-size: 24px;");
  57. }
  58.  
  59. function hex2a(hexx) {
  60. var hex = hexx.toString();//force conversion
  61. var str = '';
  62. for (var i = 0; i < hex.length; i += 2)
  63. str += String.fromCharCode(parseInt(hex.substr(i, 2), 16));
  64. return str;
  65. }
  66.  
  67. function FindPointAtDistanceFrom(startPoint, initialBearingRadians, distanceKilometres) {
  68. const radiusEarthKilometres = 6371.01;
  69. var distRatio = distanceKilometres / radiusEarthKilometres;
  70. var distRatioSine = Math.sin(distRatio);
  71. var distRatioCosine = Math.cos(distRatio);
  72.  
  73. var startLatRad = DegreesToRadians(startPoint.lat);
  74. var startLonRad = DegreesToRadians(startPoint.lng);
  75.  
  76. var startLatCos = Math.cos(startLatRad);
  77. var startLatSin = Math.sin(startLatRad);
  78.  
  79. var endLatRads = Math.asin((startLatSin * distRatioCosine) + (startLatCos * distRatioSine * Math.cos(initialBearingRadians)));
  80.  
  81. var endLonRads = startLonRad
  82. + Math.atan2(
  83. Math.sin(initialBearingRadians) * distRatioSine * startLatCos,
  84. distRatioCosine - startLatSin * Math.sin(endLatRads));
  85.  
  86. return { lat: RadiansToDegrees(endLatRads), lng: RadiansToDegrees(endLonRads) };
  87. }
  88.  
  89. function DegreesToRadians(degrees) {
  90. const degToRadFactor = Math.PI / 180;
  91. return degrees * degToRadFactor;
  92. }
  93.  
  94. function RadiansToDegrees(radians) {
  95. const radToDegFactor = 180 / Math.PI;
  96. return radians * radToDegFactor;
  97. }
  98.  
  99. function runAsClient(f) {
  100. var s = document.createElement("script");
  101. s.type = "text/javascript";
  102. s.text = "(async () => { try { await (" + f.toString() + ")(); } catch (e) { console.error(e); }})();";
  103. document.body.appendChild(s);
  104. }
  105.  
  106. window.runAsClient = runAsClient;
  107.  
  108. /**
  109. * Resolves succesfully after detecting that Google Maps API was loaded in a page
  110. *
  111. * @returns Promise
  112. */
  113. function gmp() {
  114. return new Promise((resolve, reject) => {
  115. let scriptObserver = new MutationObserver((mutations, observer) => {
  116. for (let mutation of mutations) {
  117. for (let node of mutation.addedNodes) {
  118. if (node.tagName === "SCRIPT" && node.src.startsWith(MAPS_API_URL)) {
  119. scriptObserver.disconnect();
  120. scriptObserver = undefined;
  121. myLog("Detected Google Maps API");
  122. node.onload = () => resolve();
  123. }
  124. }
  125. }
  126. });
  127.  
  128. let bodyDone = false;
  129. let headDone = false;
  130.  
  131. let injectorObserver = new MutationObserver((mutations, observer) => {
  132. if (!bodyDone && document.body) {
  133. bodyDone = true;
  134. myLog("Body Observer Injected");
  135. scriptObserver && scriptObserver.observe(document.body, {
  136. childList: true
  137. });
  138. }
  139. if (!headDone && document.head) {
  140. headDone = true;
  141. myLog("Head Observer Injected");
  142. scriptObserver && scriptObserver.observe(document.head, {
  143. childList: true
  144. });
  145. }
  146. if (headDone && bodyDone) {
  147. myLog("Body and Head Observers Injected");
  148. observer.disconnect();
  149. }
  150. });
  151.  
  152. injectorObserver.observe(document.documentElement, {
  153. childList: true,
  154. subtree: true
  155. });
  156. });
  157. }
  158.  
  159. /**
  160. * Creates teleportation and Kakao switch button
  161. *
  162. * @returns Promise
  163. */
  164.  
  165. function ArisKakao() {
  166. runAsClient(() => {
  167.  
  168. let radi = 100;
  169. const google = window.google;
  170. let curPosition, mapPlayer;
  171. let kakao_enabled = true;
  172.  
  173. const isGamePage = () => location.pathname.startsWith("/challenge/") || location.pathname.startsWith("/results/") || location.pathname.startsWith("/game/")|| location.pathname.startsWith("/battle-royale/");
  174.  
  175. const getPosition = sv => (
  176. {
  177. lat: sv.position.lat(),
  178. lng: sv.position.lng(),
  179. });
  180.  
  181. // Handle the street view being navigated
  182. const onMove = (sv) => {
  183. try {
  184. if (!isGamePage()) return;
  185. const position = getPosition(sv);
  186. // console.log("HHHHHHHHHHHHH");
  187. // console.log(position);
  188. curPosition = position;
  189. }
  190. catch (e) {
  191. console.error("GeoGuessr Path Logger Error:", e);
  192. }
  193. };
  194.  
  195. // Helper Functions
  196.  
  197. function FindPointAtDistanceFrom(startPoint, initialBearingRadians, distanceKilometres) {
  198. const radiusEarthKilometres = 6371.01;
  199. var distRatio = distanceKilometres / radiusEarthKilometres;
  200. var distRatioSine = Math.sin(distRatio);
  201. var distRatioCosine = Math.cos(distRatio);
  202.  
  203. var startLatRad = DegreesToRadians(startPoint.lat);
  204. var startLonRad = DegreesToRadians(startPoint.lng);
  205.  
  206. var startLatCos = Math.cos(startLatRad);
  207. var startLatSin = Math.sin(startLatRad);
  208.  
  209. var endLatRads = Math.asin((startLatSin * distRatioCosine) + (startLatCos * distRatioSine * Math.cos(initialBearingRadians)));
  210.  
  211. var endLonRads = startLonRad
  212. + Math.atan2(
  213. Math.sin(initialBearingRadians) * distRatioSine * startLatCos,
  214. distRatioCosine - startLatSin * Math.sin(endLatRads));
  215.  
  216. return { lat: RadiansToDegrees(endLatRads), lng: RadiansToDegrees(endLonRads) };
  217. }
  218.  
  219. function DegreesToRadians(degrees) {
  220. const degToRadFactor = Math.PI / 180;
  221. return degrees * degToRadFactor;
  222. }
  223.  
  224. function RadiansToDegrees(radians) {
  225. const radToDegFactor = 180 / Math.PI;
  226. return radians * radToDegFactor;
  227. }
  228.  
  229. function svCheck(data, status) {
  230. if (status === 'OK') {
  231. console.log("OK for " + data.location.latLng + " at ID " + data.location.pano);
  232. let l = data.location.latLng.toString().split(',');
  233. let lat = l[0].replaceAll('(', '')
  234. let lng = l[1].replaceAll(')', '')
  235. // console.log(lat);
  236. // console.log(lng)
  237. // console.log(curPosition)
  238. if (lat == curPosition.lat && lng == curPosition.lng)
  239. {
  240. console.log("Trying more distance");
  241. radi += 100;
  242. teleportButton.innerHTML = "Teleport " + radi + " m";
  243. }
  244. else
  245. {
  246. mapPlayer.setPosition(data.location.latLng);
  247. // console.log(radi);
  248. if (radi > 200)
  249. {
  250. radi = 100;
  251. teleportButton.innerHTML = "Teleport " + radi + " m";
  252. }
  253. }
  254. }
  255. else {
  256. console.log("STATUS NOT OK");
  257. radi += 100;
  258. teleportButton.innerHTML = "Teleport " + radi + " m";
  259. }
  260. }
  261.  
  262. // When a StreetViewPanorama is constructed, add a listener for moving
  263. const oldSV = google.maps.StreetViewPanorama;
  264. const svService = new google.maps.StreetViewService();
  265.  
  266. google.maps.StreetViewPanorama = Object.assign(function (...args) {
  267. const res = oldSV.apply(this, args);
  268. this.addListener('position_changed', () => onMove(this));
  269. mapPlayer = this;
  270. // console.log("Hi")
  271. // console.log(mapPlayer)
  272. return res;
  273. }, {
  274. prototype: Object.create(oldSV.prototype)
  275. });
  276.  
  277. var showButtons = document.createElement("Button");
  278. showButtons.id = "Show Buttons"
  279. showButtons.innerHTML = "Script Buttons";
  280. showButtons.style =
  281. "top:6em;right:0.5em;width:6em;height:4.5em;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;";
  282. document.body.appendChild(showButtons);
  283. showButtons.addEventListener("click", () => {
  284. if (hide) {
  285. teleportButton.style.visibility = "";
  286. plusButton.style.visibility = "";
  287. minusButton.style.visibility = "";
  288. resetButton.style.visibility = "";
  289. googleKakaoButton.style.visibility = "";
  290. hide = false;
  291. }
  292. else {
  293. teleportButton.style.visibility = "hidden";
  294. plusButton.style.visibility = "hidden";
  295. minusButton.style.visibility = "hidden";
  296. resetButton.style.visibility = "hidden"
  297. googleKakaoButton.style.visibility = "hidden";
  298. hide = true;
  299. }
  300. });
  301.  
  302. var teleportButton = document.createElement("Button");
  303. teleportButton.id = "Main Button"
  304. teleportButton.innerHTML = "Teleport 100m";
  305. teleportButton.style =
  306. "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;";
  307. document.body.appendChild(teleportButton);
  308. teleportButton.addEventListener("click", () => {
  309. let heading = mapPlayer.getPov().heading;
  310. let place = FindPointAtDistanceFrom(curPosition, DegreesToRadians(heading), radi * 0.001)
  311. svService.getPanorama({ location: place, radius: 1000 }, svCheck);
  312.  
  313. });
  314.  
  315. var plusButton = document.createElement("Button");
  316. plusButton.id = "plus"
  317. plusButton.innerHTML = "+";
  318. plusButton.style =
  319. "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;";
  320. document.body.appendChild(plusButton);
  321. plusButton.addEventListener("click", () => {
  322. if (radi > 21 && radi < 200) {
  323. radi = radi + 25;
  324. }
  325. teleportButton.innerHTML = "Teleport " + radi + " m";
  326. });
  327.  
  328. var minusButton = document.createElement("Button");
  329. minusButton.id = "minus"
  330. minusButton.innerHTML = "-";
  331. minusButton.style =
  332. "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;";
  333. document.body.appendChild(minusButton);
  334. minusButton.addEventListener("click", () => {
  335. if (radi > 26) {
  336. radi = radi - 25;
  337. }
  338. teleportButton.innerHTML = "Teleport " + radi + " m";
  339. });
  340.  
  341. var resetButton = document.createElement("Button");
  342. resetButton.id = "reset"
  343. resetButton.innerHTML = "Reset";
  344. resetButton.style =
  345. "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;";
  346. document.body.appendChild(resetButton);
  347. resetButton.addEventListener("click", () => {
  348. radi = 100;
  349. teleportButton.innerHTML = "Teleport " + radi + " m";
  350. });
  351.  
  352. var googleKakaoButton = document.createElement("Button");
  353. googleKakaoButton.id = "switch"
  354. googleKakaoButton.innerHTML = "Switch coverage";
  355. googleKakaoButton.style =
  356. "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;";
  357. document.body.appendChild(googleKakaoButton);
  358. googleKakaoButton.addEventListener("click", () => {
  359. let GOOGLE_MAPS_CANVAS1 = document.querySelector(".game-layout__panorama-canvas");
  360. let GOOGLE_MAPS_CANVAS2 = document.querySelector(".br-game-layout__panorama-canvas");
  361. let GOOGLE_MAPS_CANVAS = null;
  362. if (GOOGLE_MAPS_CANVAS1 !== null)
  363. {
  364. GOOGLE_MAPS_CANVAS = GOOGLE_MAPS_CANVAS1;
  365. }
  366. else
  367. {
  368. GOOGLE_MAPS_CANVAS = GOOGLE_MAPS_CANVAS2;
  369. }
  370. let KAKAO_MAPS_CANVAS = document.getElementById("roadview");
  371. if (kakao_enabled) {
  372. GOOGLE_MAPS_CANVAS.style.visibility = "";
  373. KAKAO_MAPS_CANVAS.style.visibility = "hidden";
  374. kakao_enabled = false;
  375. }
  376. else {
  377. GOOGLE_MAPS_CANVAS.style.visibility = "hidden";
  378. KAKAO_MAPS_CANVAS.style.visibility = "";
  379. kakao_enabled = true;
  380. console.log("use Kakao");
  381. }
  382. });
  383.  
  384. let hide = true;
  385. if (document.querySelector(".br-game-layout__panorama-canvas") != null)
  386. {
  387. teleportButton.style.top = "2px";
  388. plusButton.style.top = "2px";
  389. minusButton.style.top = "2px";
  390. resetButton.style.top = "calc(2.5em + 2px)";
  391. googleKakaoButton.style.top = "calc(2.5em + 2px)";
  392. showButtons.style.top = "2px";
  393.  
  394. teleportButton.style.right = "calc(9.5em + 300px)";
  395. plusButton.style.right = "calc(20em + 300px)";
  396. minusButton.style.right = "calc(7em + 300px)";
  397. resetButton.style.right = "calc(17.5em + 300px)";
  398. googleKakaoButton.style.right = "calc(7em + 300px)";
  399. showButtons.style.right = "300px";
  400. }
  401.  
  402. console.log("Buttons Loaded");
  403.  
  404. });
  405. }
  406.  
  407. /**
  408. * Hide or Reveal such buttons
  409. */
  410.  
  411. function setHidden(cond)
  412. {
  413. if (cond)
  414. {
  415. if (document.getElementById("Show Buttons") != null)
  416. {
  417. document.getElementById("Show Buttons").style.visibility = "hidden";
  418. if (document.getElementById("Main Button") != null)
  419. {
  420. document.getElementById("plus").style.visibility = "hidden";
  421. document.getElementById("minus").style.visibility = "hidden";
  422. document.getElementById("reset").style.visibility = "hidden";
  423. document.getElementById("Main Button").style.visibility = "hidden";
  424. document.getElementById("switch").style.visibility = "hidden";
  425. }
  426. }
  427. }
  428. else
  429. {
  430. if (document.getElementById("Show Buttons") != null)
  431. {
  432. document.getElementById("Show Buttons").style.visibility = "";
  433. }
  434. }
  435. }
  436.  
  437. function setDisable(cond)
  438. {
  439. if (cond !== "Google")
  440. {
  441. if (document.getElementById("Main Button") != null)
  442. {
  443. document.getElementById("plus").disabled = true;
  444. document.getElementById("plus").style.backgroundColor = "red";
  445. document.getElementById("minus").disabled = true;
  446. document.getElementById("minus").style.backgroundColor = "red";
  447. document.getElementById("reset").disabled = true;
  448. document.getElementById("reset").style.backgroundColor = "red";
  449. document.getElementById("Main Button").disabled = true;
  450. document.getElementById("Main Button").style.backgroundColor = "red";
  451. document.getElementById("switch").disabled = true;
  452. document.getElementById("switch").style.backgroundColor = "red";
  453.  
  454. if (cond === "Kakao")
  455. {
  456. document.getElementById("switch").disabled = false;
  457. document.getElementById("switch").style.backgroundColor = "#4CAF50";
  458. }
  459. else
  460. {
  461. document.getElementById("switch").disabled = true;
  462. document.getElementById("switch").style.backgroundColor = "red";
  463. }
  464. }
  465. }
  466. else
  467. {
  468. if (document.getElementById("Main Button") != null)
  469. {
  470. document.getElementById("plus").disabled = false;
  471. document.getElementById("plus").style.backgroundColor = "#4CAF50";
  472. document.getElementById("minus").disabled = false;
  473. document.getElementById("minus").style.backgroundColor = "#4CAF50";
  474. document.getElementById("reset").disabled = false;
  475. document.getElementById("reset").style.backgroundColor = "#4CAF50";
  476. document.getElementById("Main Button").disabled = false;
  477. document.getElementById("Main Button").style.backgroundColor = "#4CAF50";
  478. document.getElementById("switch").disabled = false;
  479. document.getElementById("switch").style.backgroundColor = "#4CAF50";
  480. document.getElementById("switch").disabled = true;
  481. document.getElementById("switch").style.backgroundColor = "red";
  482. }
  483. }
  484. }
  485.  
  486. /**
  487. * This observer stays alive while the script is running
  488. */
  489. function launchObserver() {
  490. ArisKakao();
  491. myHighlight("Main Observer");
  492. const OBSERVER = new MutationObserver((mutations, observer) => {
  493. detectGamePage();
  494. });
  495. OBSERVER.observe(document.head, { attributes: true, childList: true, subtree: true });
  496. }
  497.  
  498. /**
  499. * Once the Google Maps API was loaded we can do more stuff
  500. */
  501. gmp().then(() => {
  502. launchObserver();
  503. });
  504.  
  505.  
  506. /**
  507. * Detects if the current page contains /game/ or /challenge/ in it
  508. */
  509.  
  510. function detectGamePage() {
  511. let toLoad = !playerLoaded && !PLAYER && !PLAYER2 && !PLAYER3 && !YANDEX_INJECTED && !BAIDU_INJECTED && !KAKAO_INJECTED
  512. const PATHNAME = window.location.pathname;
  513. if (PATHNAME.startsWith("/game/") || PATHNAME.startsWith("/challenge/")) {
  514. // myLog("Game page");
  515. BR = false;
  516.  
  517. if (toLoad) {
  518. loadPlayers();
  519. }
  520. waitLoad();
  521. }
  522. else if (PATHNAME.startsWith("/battle-royale/")) {
  523. if (document.querySelector(".br-game-layout") == null) {
  524. // myLog("Battle Royale Lobby");
  525. }
  526. else {
  527. // myLog("Battle Royale");
  528. BR = true;
  529. if (toLoad) {
  530. loadPlayers();
  531. }
  532. waitLoad();
  533. }
  534. }
  535. else {
  536. //myLog("Not a Game page");
  537. ROUND = 0;
  538. PLAYER = null;
  539. PLAYER2 = null;
  540. PLAYER3 = null;
  541. COMPASS = null;
  542. eventlistener = false;
  543. BAIDU_INJECTED = false;
  544. YANDEX_INJECTED = false;
  545. KAKAO_INJECTED = false;
  546. global_lat = 0;
  547. global_lng = 0;
  548. global_panoID = null;
  549. playerLoaded = false;
  550. loc_list = [];
  551. setHidden(true);
  552. yandex_map = false;
  553. }
  554. }
  555.  
  556. /**
  557. * Wait for various players to load
  558. */
  559.  
  560. function waitLoad() {
  561. if (!PLAYER || !PLAYER2 || !PLAYER3 || !YANDEX_INJECTED || !BAIDU_INJECTED || !KAKAO_INJECTED) {
  562. setTimeout(waitLoad, 100);
  563. } else {
  564. checkRound();
  565. }
  566. }
  567.  
  568. /**
  569. * Checks for round changes
  570. */
  571. function checkRound() {
  572. // myLog("Check Round");
  573. if (!BR) {
  574. let currentRound = getRoundFromPage();
  575. if (ROUND != currentRound) {
  576. myHighlight("New round");
  577. ROUND = currentRound;
  578. NEW_ROUND_LOADED = true;
  579. COMPASS = null;
  580. loc_list = [];
  581. getMapData();
  582. nextButtonCallback();
  583. }
  584. }
  585. else {
  586. // myHighlight("BR New round");
  587. NEW_ROUND_LOADED = true;
  588. COMPASS = null;
  589. loc_list = [];
  590. getMapData();
  591. }
  592. }
  593.  
  594. function nextButtonCallback()
  595. {
  596. let nextButton = document.querySelector("button[data-qa='close-round-result']");
  597. if (nextButton != null)
  598. {
  599. nextButton.addEventListener("click", (e) => {
  600. if (document.getElementById("Show Buttons") != null)
  601. {
  602. myLog("try to hide show buttons")
  603. document.getElementById("Show Buttons").style.visibility = "";
  604. }
  605. })
  606. }
  607. else
  608. {
  609. setTimeout(nextButtonCallback, 500);
  610. }
  611. }
  612.  
  613. function guessButtonCallback()
  614. {
  615. let guessButton = document.querySelector("button[data-qa='perform-guess']");
  616.  
  617. if (guessButton!= null)
  618. {
  619.  
  620. guessButton.addEventListener("click", (e) => {
  621. if (document.getElementById("Show Buttons") != null && !BR)
  622. {
  623. myLog("try to hide show buttons")
  624. document.getElementById("Show Buttons").style.visibility = "hidden";
  625. setHidden(true);
  626. }
  627. })
  628. }
  629. else
  630. {
  631. setTimeout(guessButtonCallback, 500);
  632. }
  633. }
  634.  
  635. /**
  636. * Load different streetview players
  637. */
  638.  
  639. function loadPlayers() {
  640. playerLoaded = true;
  641. if (!BR)
  642. {
  643. getSeed().then((data) => {
  644. myLog(data);
  645. if (data.mapName.includes("A United World"))
  646. {
  647. injectYandexScript().then(() => {
  648. myLog("Ready to inject Yandex player");
  649. injectYandexPlayer();
  650. }).catch((error) => {
  651. myLog(error);
  652. });
  653. }
  654. else if (data.mapName.includes("Yandex"))
  655. {
  656. yandex_map = true;
  657. injectYandexScript().then(() => {
  658. myLog("Ready to inject Yandex player");
  659. injectYandexPlayer();
  660. }).catch((error) => {
  661. myLog(error);
  662. });
  663. }
  664. else{
  665. YANDEX_API_KEY = "";
  666. myLog("Not a Yandex map");
  667. YANDEX_INJECTED = true;
  668. PLAYER = "YD";
  669. injectYandexScript().then(() => {
  670. myLog("Ready to inject Yandex player");
  671. }).catch((error) => {
  672. myLog(error);
  673. });
  674. }
  675. setHidden(false);
  676.  
  677. }).catch((error) => {
  678. myLog(error);
  679. });
  680. }
  681. initializeCanvas();
  682. injectBaiduPlayer();
  683. injectKakaoScript().then(() => {
  684. myLog("Ready to inject Kakao player");
  685. }).catch((error) => {
  686. myLog(error);
  687. });
  688. if (BR)
  689. {
  690. injectYandexScript().then(() => {
  691. myLog("Ready to inject Yandex player");
  692. injectYandexPlayer();
  693. }).catch((error) => {
  694. myLog(error);
  695. });
  696. }
  697. }
  698.  
  699. /**
  700. * Handles Return to start and undo
  701. */
  702.  
  703. function handleReturnToStart() {
  704. myLog("handleReturnToStart listener attached");
  705. let rtsButton = document.querySelector("button[data-qa='return-to-start']");
  706. if (rtsButton != null) {
  707. rtsButton.addEventListener("click", (e) => {
  708. goToLocation(CURRENT_ROUND_DATA);
  709. const elementClicked = e.target;
  710. elementClicked.setAttribute('listener', 'true');
  711. myLog("Return to start");
  712. });
  713. }
  714. guessButtonCallback();
  715. }
  716.  
  717. function handleUndo() {
  718. let undoButton = document.querySelector("button[data-qa='undo-move']");
  719. undoButton.addEventListener("click", (e) => {
  720. if (loc_list.length > 0) {
  721. goToUndoMove();
  722. myLog("Undo Move");
  723. }
  724. })
  725.  
  726. }
  727.  
  728. function getMapData() {
  729. getSeed().then((data) => {
  730. //myHighlight("Seed data");
  731. //myLog(data);
  732. if (BR) {
  733. if (document.querySelector(".br-game-layout") == null) {
  734. // myLog("Battle Royale Lobby");
  735. }
  736. else
  737. {
  738. // myLog("hello");
  739. let origin = false;
  740. if (!CURRENT_ROUND_DATA) {
  741. CURRENT_ROUND_DATA = data
  742. origin = true;
  743. }
  744.  
  745. if (origin || !(data.currentRoundNumber === CURRENT_ROUND_DATA.currentRoundNumber)) {
  746. if (!origin) {
  747. CURRENT_ROUND_DATA = data;
  748. }
  749. locationCheck(data);
  750. // myLog(data)
  751. setTimeout(function () {goToLocation(data, nextPlayer);}, 1000);
  752. setTimeout(function () { handleReturnToStart(); }, 2000);
  753.  
  754. }
  755. }
  756. }
  757. else {
  758. locationCheck(data);
  759. setTimeout(function () { goToLocation(data, nextPlayer);}, 1000);
  760. setTimeout(function () { handleReturnToStart(); }, 2000);
  761. setTimeout(function () { handleUndo(); }, 2000);
  762. hideButtons();
  763. }
  764. }).catch((error) => {
  765. myLog(error);
  766. });
  767. }
  768.  
  769. function hideButtons() {
  770. let CHECKPOINT = document.querySelector("button[data-qa='set-checkpoint']");
  771. let ZOOM_IN = document.querySelector("button[data-qa='pano-zoom-in']");
  772. let ZOOM_OUT = document.querySelector("button[data-qa='pano-zoom-out']");
  773. // myLog(CHECKPOINT);
  774. if (nextPlayer === "Google") {
  775. if (CHECKPOINT != null) {
  776. CHECKPOINT.style.visibility = "";
  777. ZOOM_IN.style.visibility = "";
  778. ZOOM_OUT.style.visibility = "";
  779. myLog("Buttons Unhidden");
  780. }
  781. }
  782. else {
  783. if (CHECKPOINT != null) {
  784. CHECKPOINT.style.visibility = "hidden";
  785. ZOOM_IN.style.visibility = "hidden";
  786. ZOOM_OUT.style.visibility = "hidden";
  787. myLog("Buttons Hidden");
  788. }
  789. }
  790. }
  791.  
  792. function locationCheck(data) {
  793. console.log(data);
  794. if (BR) {
  795. global_lat = data.rounds[data.currentRoundNumber - 1].lat;
  796. global_lng = data.rounds[data.currentRoundNumber - 1].lng;
  797. global_panoID = data.rounds[data.currentRoundNumber - 1].panoId;
  798. }
  799. else {
  800. global_lat = data.rounds[data.round - 1].lat;
  801. global_lng = data.rounds[data.round - 1].lng;
  802. global_panoID = data.rounds[data.round - 1].panoId;
  803. }
  804. myLog(global_lat);
  805. myLog(global_lng);
  806. myLog(krCoordinates);
  807. if ( krCoordinates[0] > global_lat && krCoordinates[2] < global_lat && krCoordinates[1] < global_lng && krCoordinates[3] > global_lng)
  808. {
  809. nextPlayer = "Kakao";
  810. }
  811. else
  812. {
  813. if (global_panoID) {
  814. let output = hex2a(global_panoID);
  815. let type = output.substring(0, 5);
  816. if (type === "BDMAP") {
  817. nextPlayer = "Baidu";
  818. let coord = output.substring(5);
  819. global_lat = coord.split(",")[0];
  820. global_lng = coord.split(",")[1];
  821. }
  822. else if (type === "YDMAP" ) {
  823. nextPlayer = "Yandex";
  824. }
  825. else {
  826. nextPlayer = "Google";
  827. }
  828. }
  829. else {
  830. if (yandex_map)
  831. {
  832. nextPlayer = "Yandex";
  833. }
  834. else
  835. {
  836. nextPlayer = "Google";
  837. }
  838. }
  839. }
  840. if(!BR)
  841. {
  842. if (data.forbidMoving || data.forbidRotating || data.forbidZooming)
  843. {
  844. setDisable("NMPZ");
  845. }
  846. else
  847. {
  848. setDisable(nextPlayer);
  849. }
  850. }
  851. else
  852. {
  853. if (data.movementOptions.forbidMoving || data.movementOptions.forbidRotating || data.movementOptions.forbidZooming)
  854. {
  855. setDisable("NMPZ");
  856. }
  857. else
  858. {
  859. setDisable(nextPlayer);
  860. }
  861. }
  862.  
  863. myLog(nextPlayer);
  864. injectCanvas();
  865. }
  866.  
  867.  
  868. function initializeCanvas() {
  869. let GAME_CANVAS = ""
  870. if (!BR) {
  871. GAME_CANVAS = document.querySelector(".game-layout__canvas");
  872. }
  873. else {
  874. GAME_CANVAS = document.querySelector(".br-game-layout__canvas");
  875. }
  876. GAME_CANVAS.id = "player";
  877. myLog("Canvas injected");
  878. }
  879.  
  880. function injectCanvas() {
  881. Google();
  882. Baidu();
  883. Kakao();
  884. Yandex();
  885. ZoomControls();
  886. }
  887.  
  888.  
  889. function Google() {
  890. let GOOGLE_MAPS_CANVAS = ""
  891. if (!BR) {
  892. GOOGLE_MAPS_CANVAS = document.querySelector(".game-layout__panorama-canvas");
  893. }
  894. else {
  895. GOOGLE_MAPS_CANVAS = document.querySelector(".br-game-layout__panorama-canvas");
  896. }
  897. if (nextPlayer === "Google") {
  898. GOOGLE_MAPS_CANVAS.style.visibility = "";
  899. myLog("Google Canvas loaded");
  900. }
  901. else {
  902. GOOGLE_MAPS_CANVAS.style.visibility = "hidden";
  903. myLog("Google Canvas hidden");
  904. }
  905.  
  906. }
  907.  
  908.  
  909. function Baidu() {
  910. let BAIDU_MAPS_CANVAS = document.getElementById("PanoramaMap");
  911. myLog("Baidu canvas");
  912. if (nextPlayer === "Baidu") {
  913. BAIDU_MAPS_CANVAS.style.visibility = "";
  914. myLog("Baidu Canvas loaded");
  915. }
  916. else {
  917. BAIDU_MAPS_CANVAS.style.visibility = "hidden";
  918. myLog("Baidu Canvas hidden");
  919. }
  920.  
  921. }
  922.  
  923. function Kakao() {
  924. let KAKAO_MAPS_CANVAS = document.getElementById("roadview");
  925. myLog("Kakao canvas");
  926. if (nextPlayer === "Kakao") {
  927. KAKAO_MAPS_CANVAS.style.visibility = "";
  928. myLog("Kakao Canvas loaded");
  929. }
  930. else {
  931. KAKAO_MAPS_CANVAS.style.visibility = "hidden";
  932. myLog("Kakao Canvas hidden");
  933. }
  934.  
  935. }
  936.  
  937. function Yandex() {
  938. let YANDEX_MAPS_CANVAS = document.querySelector(".ymaps-2-1-79-panorama-screen");
  939. if (YANDEX_MAPS_CANVAS != null)
  940. {
  941. myLog("Yandex canvas");
  942. /* myLog(YANDEX_MAPS_CANVAS); */
  943. if (nextPlayer === "Yandex") {
  944. YANDEX_MAPS_CANVAS.style.visibility = "";
  945. myLog("Yandex Canvas loaded");
  946. }
  947. else {
  948. YANDEX_MAPS_CANVAS.style.visibility = "hidden";
  949. myLog("Yandex Canvas hidden");
  950. }
  951. }
  952.  
  953. }
  954.  
  955. function ZoomControls() {
  956. let style = `
  957. .ymaps-2-1-79-panorama-gotoymaps {display: none !important;}
  958. .game-layout__controls {bottom: 8rem !important; left: 1rem !important;}
  959. `;
  960.  
  961. let style_element = document.createElement("style");
  962. style_element.innerHTML = style;
  963. document.body.appendChild(style_element);
  964. }
  965.  
  966. function goToLocation(data) {
  967. myLog("Going to location");
  968. if (nextPlayer === "Yandex") {
  969. let options = {};
  970. PLAYER.moveTo([global_lat, global_lng], options);
  971. PLAYER.setDirection([0, 16]);
  972. PLAYER.setSpan([10, 67]);
  973. }
  974. else if (nextPlayer === "Baidu") {
  975. let a = new BMap.Point(global_lng, global_lat);
  976. PLAYER2.setPov({ heading: -40, pitch: 6 });
  977. PLAYER2.setPosition(a);
  978. }
  979. else if (nextPlayer === "Kakao") {
  980. var roadviewClient = new kakao.maps.RoadviewClient();
  981. var position = new kakao.maps.LatLng(global_lat, global_lng);
  982. roadviewClient.getNearestPanoId(position, 500, function (panoId) {
  983. PLAYER3.setPanoId(panoId, position);
  984. });
  985. }
  986. else {
  987.  
  988. }
  989.  
  990. }
  991.  
  992. function goToUndoMove(data) {
  993. /* myLog(global_lat);
  994. myLog(global_lng); */
  995. if (nextPlayer === "Yandex") {
  996. let options = {};
  997. let place2 = null;
  998. if (loc_list.length === 1) {
  999. place2 = loc_list[0];
  1000. }
  1001. else {
  1002. place2 = loc_list.pop();
  1003. }
  1004. pops = false;
  1005. // myLog(place2);
  1006. // myLog(loc_list)
  1007. PLAYER.moveTo([place2[0], place2[1]], options);
  1008. PLAYER.setDirection([place2[2], place2[3]]);
  1009. PLAYER.setSpan([10, 67]);
  1010. }
  1011. else if (nextPlayer === "Kakao") {
  1012. let place3 = null;
  1013. if (loc_list.length === 1) {
  1014. place3 = loc_list[0];
  1015. }
  1016. else {
  1017. place3 = loc_list.pop();
  1018. }
  1019. pops = false;
  1020. var position = new kakao.maps.LatLng(place3[0], place3[1]);
  1021. PLAYER3.setPanoId(place3[2], position);
  1022. }
  1023. else if (nextPlayer === "Baidu") {
  1024. /* myLog(PLAYER2);
  1025. myLog(global_lng);
  1026. myLog(global_lat); */
  1027. let place = null;
  1028. if (loc_list.length === 1) {
  1029. place = loc_list[0];
  1030. }
  1031. else {
  1032. place = loc_list.pop();
  1033. }
  1034. // myLog(place);
  1035. let a = new BMap.Point(place[1], place[0]);
  1036. let pov = { heading: place[2], pitch: place[3] };
  1037. PLAYER2.setPosition(a);
  1038. PLAYER2.setPov(pov);
  1039. // myLog(loc_list);
  1040. /* myLog(PLAYER2); */
  1041. }
  1042. else {
  1043.  
  1044. }
  1045.  
  1046. }
  1047.  
  1048.  
  1049.  
  1050.  
  1051. /**
  1052. * Gets the seed data for the current game
  1053. *
  1054. * @returns Promise with seed data as object
  1055. */
  1056. function getSeed() {
  1057. // myLog("getSeed called");
  1058. return new Promise((resolve, reject) => {
  1059. let token = getToken();
  1060. let URL;
  1061. let cred = ""
  1062.  
  1063. const PATHNAME = window.location.pathname;
  1064.  
  1065. if (PATHNAME.startsWith("/game/")) {
  1066. URL = `https://www.geoguessr.com/api/v3/games/${token}`;
  1067. }
  1068. else if (PATHNAME.startsWith("/challenge/")) {
  1069. URL = `https://www.geoguessr.com/api/v3/challenges/${token}/game`;
  1070. }
  1071. else if (PATHNAME.startsWith("/battle-royale/")) {
  1072. URL = `https://game-server.geoguessr.com/api/battle-royale/${token}`;
  1073. }
  1074. if (BR) {
  1075. fetch(URL, {
  1076. // Include credentials to GET from the endpoint
  1077. credentials: 'include'
  1078. })
  1079. .then((response) => response.json())
  1080. .then((data) => {
  1081. resolve(data);
  1082. })
  1083. .catch((error) => {
  1084. reject(error);
  1085. });
  1086. }
  1087. else {
  1088. fetch(URL)
  1089. .then((response) => response.json())
  1090. .then((data) => {
  1091. resolve(data);
  1092. })
  1093. .catch((error) => {
  1094. reject(error);
  1095. });
  1096. }
  1097. });
  1098. }
  1099.  
  1100. /**
  1101. * Gets the token from the current URL
  1102. *
  1103. * @returns token
  1104. */
  1105. function getToken() {
  1106. const PATHNAME = window.location.pathname;
  1107. if (PATHNAME.startsWith("/game/")) {
  1108. return PATHNAME.replace("/game/", "");
  1109. }
  1110. else if (PATHNAME.startsWith("/challenge/")) {
  1111. return PATHNAME.replace("/challenge/", "");
  1112. }
  1113. else if (PATHNAME.startsWith("/battle-royale/")) {
  1114. return PATHNAME.replace("/battle-royale/", "");
  1115. }
  1116. }
  1117.  
  1118. /**
  1119. * Gets the round number from the ongoing game from the page itself
  1120. *
  1121. * @returns Round number
  1122. */
  1123. function getRoundFromPage() {
  1124. const roundData = document.querySelector("div[data-qa='round-number']");
  1125. if (roundData) {
  1126. let roundElement = roundData.querySelector("div:last-child");
  1127. if (roundElement) {
  1128. let round = parseInt(roundElement.innerText.charAt(0));
  1129. if (!isNaN(round) && round >= 1 && round <= 5) {
  1130. return round;
  1131. }
  1132. }
  1133. }
  1134. else {
  1135. return ROUND;
  1136. }
  1137. }
  1138.  
  1139.  
  1140. /**
  1141. * Injects Yandex Script
  1142. */
  1143. function injectYandexScript() {
  1144. return new Promise((resolve, reject) => {
  1145. if (!YANDEX_INJECTED) {
  1146. if (YANDEX_API_KEY === "") {
  1147. // let canvas = document.getElementById("player");
  1148. // canvas.innerHTML = `
  1149. // <div style="text-align: center;">
  1150. // <h1 style="margin-top: 80px; font-size: 48px;">YOU NEED YANDEX API KEY<h1>
  1151. // <p><a target="_blank" href="https://yandex.com/dev/maps/jsapi/doc/2.1/quick-start/index.html?from=techmapsmain">Get it here</a></p>
  1152. // <br/>
  1153. // <p>After that you need to add that key into this script in</p>
  1154. // <code>const YANDEX_API_KEY = "";</code>
  1155. // </div>
  1156. // `;
  1157. myLog("No Yandex Key")
  1158. reject();
  1159. }
  1160. else {
  1161. const SCRIPT = document.createElement("script");
  1162. SCRIPT.type = "text/javascript";
  1163. SCRIPT.async = true;
  1164. SCRIPT.onload = () => {
  1165. ymaps.ready(() => {
  1166. YANDEX_INJECTED = true;
  1167. myHighlight("Yandex API Loaded");
  1168. resolve();
  1169. });
  1170. }
  1171. SCRIPT.src = `https://api-maps.yandex.ru/2.1/?lang=en_US&apikey=${YANDEX_API_KEY}`;
  1172. document.body.appendChild(SCRIPT);
  1173. }
  1174. }
  1175. else {
  1176. resolve();
  1177. }
  1178. });
  1179. }
  1180.  
  1181. /**
  1182. * Injects Yandex Player and calls handleReturnToStart
  1183. */
  1184. function injectYandexPlayer() {
  1185. let lat = 41.321861;
  1186. let lng = 69.212920;
  1187.  
  1188. let options = {
  1189. "direction": [0, 16],
  1190. "span": [10, 67],
  1191. "controls": ["zoomControl"]
  1192. };
  1193. ymaps.panorama.createPlayer("player", [lat, lng], options)
  1194. .done((player) => {
  1195. PLAYER = player;
  1196. PLAYER.events.add("directionchange", (e) => {
  1197. updateCompass();
  1198. });
  1199. PLAYER.events.add("panoramachange", (e) => {
  1200. if (pops && !BR) {
  1201. let num = PLAYER.getPanorama().getPosition();
  1202. let pov = PLAYER.getDirection();
  1203. // myLog(num);
  1204. // myLog(pov);
  1205. loc_list.push([num[0], num[1], pov[0], pov[1]]);
  1206. let btn = document.querySelector("button[data-qa='undo-move']");
  1207. if (loc_list.length > 1) {
  1208. btn.disabled = false;
  1209. btn.classList.remove('styles_disabled__W_k45');
  1210. }
  1211. // myLog(loc_list);
  1212. }
  1213. pops = true;
  1214.  
  1215. });
  1216. myHighlight("Player injected");
  1217. });
  1218.  
  1219. }
  1220.  
  1221.  
  1222. /**
  1223. * Injects Baidu
  1224. */
  1225. function injectBaiduScript() {
  1226. return new Promise((resolve, reject) => {
  1227. if (!BAIDU_INJECTED) {
  1228. if (BAIDU_API_KEY === "") {
  1229. let canvas = document.getElementById("player");
  1230. canvas.innerHTML = `
  1231. <div style="text-align: center;">
  1232. <h1 style="margin-top: 80px; font-size: 48px;">YOU NEED Baidu API KEY<h1>
  1233. <br/>
  1234. <p>After that you need to add that key into this script in</p>
  1235. <code>const YANDEX_API_KEY = "";</code>
  1236. </div>
  1237. `;
  1238. reject();
  1239. }
  1240. else {
  1241. const SCRIPT = document.createElement("script");
  1242. SCRIPT.type = "text/javascript";
  1243. SCRIPT.async = true;
  1244. SCRIPT.src = `https://api.map.baidu.com/api?v=3.0&ak=${BAIDU_API_KEY}&callback=init`;
  1245. document.body.appendChild(SCRIPT);
  1246.  
  1247. let canvas = document.createElement("bmap");
  1248. if (BR) {
  1249. canvas.innerHTML = `
  1250. <div id="PanoramaMap" class="br-game-layout__panorama" style="zIndex: 99999,position: "absolute", top: 0, left: 0, width: '100%', height: '100%',"> </div>
  1251. `;
  1252. }
  1253. else {
  1254. canvas.innerHTML = `
  1255. <div id="PanoramaMap" class="game-layout__panorama" style="zIndex: 99999,position: "absolute", top: 0, left: 0, width: '100%', height: '100%',"> </div>
  1256. `;
  1257. }
  1258.  
  1259. var div = document.getElementById("player");
  1260. div.appendChild(canvas);
  1261.  
  1262. SCRIPT.addEventListener('load', () => {
  1263. myHighlight("Baidu API Loaded");
  1264. // resolve(BMap);
  1265. let timeout = 0;
  1266. let interval = setInterval(() => {
  1267. if (timeout >= 20) {
  1268. reject();
  1269. clearInterval(interval);
  1270. }
  1271. if (typeof BMap.Panorama !== "undefined") {
  1272. BAIDU_INJECTED = true;
  1273. resolve(BMap);
  1274. clearInterval(interval);
  1275. }
  1276. timeout += 1;
  1277. }, 500);
  1278. })
  1279.  
  1280.  
  1281. }
  1282. }
  1283. else {
  1284. resolve();
  1285. }
  1286. });
  1287. }
  1288.  
  1289.  
  1290.  
  1291. /**
  1292. * Injects Baidu
  1293. */
  1294. function injectKakaoScript() {
  1295. return new Promise((resolve, reject) => {
  1296. if (!KAKAO_INJECTED) {
  1297. if (KAKAO_API_KEY === "") {
  1298. let canvas = document.getElementById("player");
  1299. canvas.innerHTML = `
  1300. <div style="text-align: center;">
  1301. <h1 style="margin-top: 80px; font-size: 48px;">YOU NEED Kakao API KEY<h1>
  1302. <br/>
  1303. <p>After that you need to add that key into this script in</p>
  1304. <code>const YANDEX_API_KEY = "";</code>
  1305. </div>
  1306. `;
  1307. reject();
  1308. }
  1309. else {
  1310.  
  1311. let canvas = document.createElement("kmap");
  1312. if (BR) {
  1313. canvas.innerHTML = `
  1314. <div id="roadview" class="br-game-layout__panorama" style="zIndex: 99999,position: "absolute", top: 0, left: 0, width: '100%', height: '100%',"> </div>
  1315. `;
  1316. }
  1317. else {
  1318. canvas.innerHTML = `
  1319. <div id="roadview" class="game-layout__panorama" style="zIndex: 99999,position: "absolute", top: 0, left: 0, width: '100%', height: '100%',"> </div>
  1320. `;
  1321. }
  1322.  
  1323. var div = document.getElementById("player");
  1324. div.appendChild(canvas);
  1325.  
  1326. const SCRIPT = document.createElement("script");
  1327. SCRIPT.async = true;
  1328. // SCRIPT.type = "text/javascript";
  1329. SCRIPT.src = `//dapi.kakao.com/v2/maps/sdk.js?appkey=${KAKAO_API_KEY}&autoload=false`;
  1330. document.body.appendChild(SCRIPT);
  1331. SCRIPT.onload = () => {
  1332. kakao.maps.load(function () {
  1333. var position = new kakao.maps.LatLng(33.450701, 126.560667);
  1334. let roadviewContainer = document.getElementById('roadview');
  1335. PLAYER3 = new kakao.maps.Roadview(roadviewContainer);
  1336. var panoId = 1023434522;
  1337. PLAYER3.setPanoId(panoId, position);
  1338. KAKAO_INJECTED = true;
  1339. kakao.maps.event.addListener(PLAYER3, 'panoid_changed', function() {
  1340. if (pops && !BR) {
  1341. let latlng = PLAYER3.getPosition();
  1342. let lat = latlng.getLat();
  1343. let lng = latlng.getLng();
  1344. let pID = PLAYER3.getPanoId();
  1345. // myLog(num);
  1346. // myLog(pov);
  1347. loc_list.push([lat, lng, pID]);
  1348. let btn = document.querySelector("button[data-qa='undo-move']");
  1349. if (loc_list.length > 1) {
  1350. btn.disabled = false;
  1351. btn.classList.remove('styles_disabled__W_k45');
  1352. }
  1353. myLog(loc_list);
  1354. }
  1355. pops = true;
  1356. });
  1357. resolve();
  1358. });
  1359. };
  1360.  
  1361.  
  1362.  
  1363. }
  1364. }
  1365. else {
  1366. resolve();
  1367. }
  1368. });
  1369. }
  1370.  
  1371.  
  1372. /**
  1373. * Injects Baidu Player and calls handleReturnToStart
  1374. */
  1375. function injectBaiduPlayer() {
  1376. let lat = 0;
  1377. let lng = 0;
  1378. injectBaiduScript().then(BMap => {
  1379. PLAYER2 = new BMap.Panorama('PanoramaMap');
  1380. PLAYER2.setPov({ heading: -40, pitch: 6 });
  1381. PLAYER2.setPosition(new BMap.Point(lng, lat));
  1382. if (!eventlistener && !BR) {
  1383. myLog("position_listener attached");
  1384. PLAYER2.addEventListener('position_changed', function (e) {
  1385. eventlistener = true;
  1386. // myLog('position_changed')
  1387. let num = PLAYER2.getPosition();
  1388. let pov = PLAYER2.getPov();
  1389. if (num.lat != 0 && num.lat != 27.101448386472637) {
  1390. loc_list.push([num.lat, num.lng, pov.heading, pov.pitch]);
  1391. }
  1392. let btn = document.querySelector("button[data-qa='undo-move']");
  1393. if (loc_list.length > 1) {
  1394. btn.disabled = false;
  1395. btn.classList.remove('styles_disabled__W_k45');
  1396. }
  1397. // myLog(loc_list);
  1398. })
  1399. }
  1400. });
  1401. }
  1402.  
  1403.  
  1404.  
  1405. /**
  1406. * Goes to location when PLAYER already exists
  1407. *
  1408. * @param {*} data
  1409. */
  1410.  
  1411. /**
  1412. * Updates the compass to match Yandex Panorama facing
  1413. */
  1414. function updateCompass() {
  1415. if (!COMPASS) {
  1416. let compass = document.querySelector("img.compass__indicator");
  1417. if (compass != null) {
  1418. COMPASS = compass;
  1419. let direction = PLAYER.getDirection()[0] * -1;
  1420. COMPASS.setAttribute("style", `transform: rotate(${direction}deg);`);
  1421. }
  1422. }
  1423. else {
  1424. let direction = PLAYER.getDirection()[0] * -1;
  1425. COMPASS.setAttribute("style", `transform: rotate(${direction}deg);`);
  1426. }
  1427. }
  1428.  
  1429. // New Features:
  1430. // 1. New teleportation algorithm
  1431. // reset it to 100m, disable nm, nmpz, undo, button cover stuff in BR, button associate with guess button not correct for sk, button disappear after each round
  1432. // Uncaught TypeError: Cannot read properties of undefined (reading 'lat')
  1433. // at FindPointAtDistanceFrom (<anonymous>:36:59)
  1434. // at HTMLButtonElement.<anonymous> (<anonymous>:139:25)
  1435. // Enable