Adds Apple Look Around to GeoGuessr
当前为
// ==UserScript==
// @name AppleGuessr
// @namespace https://greasyfork.org/en/users/946023-mistystar
// @version 1.0
// @description Adds Apple Look Around to GeoGuessr
// @author Mistystar (Mistystar#2205 on Discord, https://www.youtube.com/channel/UC4IHxYw9Aoz8cf9BIdHKd3A on YT)
// @match https://www.geoguessr.com/*
// @icon https://www.google.com/s2/favicons?sz=64&domain=geoguessr.com
// @grant none
// @license MIT
// @run-at document-start
// ==/UserScript==
/*
CREDITS
Massive thank you to the following people:
- skzk#8049 - Without https://github.com/sk-zk/lookaround-map this script would not have been possible to make
- Jupaoqq#7742 - I learned a lot from looking at Unity Script's source code
- mattisinthesky#1294 or kowalski - For hosting the lookaround-map in Heroku and helping with issues
- efefury#0519 and Apfeloxid#1368 - For making the Take A Look Around Germany map
*/
// BEGIN CODE SECTION
const MENU_HTML = `
<div class="start-standard-game_settings__x94PU">
<div class="game-settings_default__DIBgs">
<div class="game-settings_toggleLabel__nipwm">
<div class="label_sizeXSmall__mFnrR">Apple Look Around</div>
<span></span>
</div>
<div>
<input type="checkbox" class="apple-look-around-toggle" checked>
</div>
</div>
</div>
`;
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/") ||
location.pathname.startsWith("/bullseye/") ||
location.pathname.startsWith("/live-challenge/");
// ----------------------------------------------------------------------------
// Script injection, extracted from extenssr:
// https://gitlab.com/nonreviad/extenssr/-/blob/main/src/injected_scripts/maps_api_injecter.ts
function overrideOnLoad(googleScript, observer, overrider) {
const oldOnload = googleScript.onload;
googleScript.onload = (event) => {
const google = window.google;
if (google) {
observer.disconnect();
overrider(google);
}
if (oldOnload) {
oldOnload.call(googleScript, event);
}
};
}
function grabGoogleScript(mutations) {
for (const mutation of mutations) {
for (const newNode of mutation.addedNodes) {
const asScript = newNode;
if (asScript && asScript.src && asScript.src.startsWith("https://maps.googleapis.com/")) {
return asScript;
}
}
}
return null;
}
function injecter(overrider) {
if (document.documentElement) {
injecterCallback(overrider);
} else {
alert("Script didn't load, refresh to try loading the script");
}
}
function injecterCallback(overrider) {
new MutationObserver((mutations, observer) => {
const googleScript = grabGoogleScript(mutations);
if (googleScript) {
overrideOnLoad(googleScript, observer, overrider);
}
}).observe(document.documentElement, { childList: true, subtree: true });
}
// End Script injection --------------------------------------------------------------s
function injectMenu() {
const inject = () => {
if (document.querySelector(".apple-look-around-toggle") !== null) return;
const settingsSection = document.querySelector('.section_sectionMedium__yXgE6');
settingsSection.insertAdjacentHTML("beforeend", MENU_HTML);
const checkbox = document.querySelector(".apple-look-around-toggle");
if (checkbox) {
let isChecked = localStorage.getItem("applelookaroundchecked");
if (isChecked === null) {
checkbox.checked = false;
localStorage.setItem("applelookaroundchecked", "false");
} else if (isChecked === "true") {
checkbox.checked = true;
} else {
checkbox.checked = false;
}
checkbox.addEventListener("change", (event) => {
if (event.currentTarget.checked) {
localStorage.setItem("applelookaroundchecked", "true");
} else {
localStorage.setItem("applelookaroundchecked", "false");
}
})
}
};
// We want the page to be loaded before trying to inject anything
let documentLoadedInterval = setInterval(function() {
if(document.readyState === "complete") {
clearInterval(documentLoadedInterval);
inject();
}
}, 100);
}
// Return a pano image given the panoID.
const getCustomPanoramaTileUrl = (pano, zoom, tileX, tileY) => {
return (
"https://apple-lookaround.herokuapp.com/pano/" + pano + "/0/"
);
};
const getPano = (pano) => {
return {
location: {
pano: pano,
description: "Apple Look Around",
},
links: [],
// The text for the copyright control.
copyright: "(C) Apple",
// The definition of the tiles for this panorama.
tiles: {
tileSize: new google.maps.Size(16384, 8000),
worldSize: new google.maps.Size(16384, 9000),
// The heading in degrees at the origin of the panorama
// tile set.
centerHeading: 180,
getTileUrl: getCustomPanoramaTileUrl,
},
};
};
function initLookAround() {
google.maps.StreetViewPanorama = class extends google.maps.StreetViewPanorama {
constructor(...args) {
super(...args);
let isChecked = localStorage.getItem("applelookaroundchecked");
if (isChecked === "true") {
this.registerPanoProvider(getPano);
this.addListener("position_changed", () => {
try {
this.appleLookAround(this);
} catch {}
});
}
}
async appleLookAround() {
let isChecked = localStorage.getItem("applelookaroundchecked");
if (isChecked !== "true") return;
try {
let lat = this.position.lat();
let lon = this.position.lng();
let lookAroundPanoId, regionId;
let response = await fetch("https://apple-lookaround.herokuapp.com/closest/" + lat + "/" + lon + "/");
let data = await response.text();
let closestObject = JSON.parse(data);
lookAroundPanoId = closestObject.panoid;
regionId = closestObject.region_id;
this.setPano(lookAroundPanoId + "/" + regionId);
} catch {}
}
}
}
function launchObserver() {
initLookAround();
//let observer3 = new MutationObserver((mutations) => {
// const PATH_NAME = window.location.pathname;
// if (PATH_NAME.startsWith("/maps/") && PATH_NAME.endsWith("/play")) { // Inject the options menu if the path name is /maps/XXXXXXX/play
// //injectMenu();
// }
//});
//observer3.observe(document.body, {childList: true, subtree: true, attributes: false, characterData: false});
}
function onLoad() {
let isChecked = localStorage.getItem("applelookaroundchecked");
if (isChecked === null) {
localStorage.setItem("applelookaroundchecked", "true");
}
//const PATH_NAME = window.location.pathname;
//if (PATH_NAME.startsWith("/maps/") && PATH_NAME.endsWith("/play")) { // Inject the options menu if the path name is /maps/XXXXXXX/play
// //injectMenu();
//}
injecter(() => {
launchObserver();
});
}
window.addEventListener("DOMContentLoaded", (event) => {
onLoad();
});