// ==UserScript==
// @name GeoGuessr XP FARM - The Best Cheat Out There!
// @namespace http://tampermonkey.net/
// @version 3.8
// @description Introducing Exodus: One of the greatest geoguessr scripts out there able to farm xp very fast to precise location pinpointing + an whole new overlay to the site! this script will amaze you!
// @author ems
// @match https://www.geoguessr.com/*
// @icon https://www.google.com/s2/favicons?sz=64&domain=geoguessr.com
// @run-at document-start
// @require https://gf.qytechs.cn/scripts/460322-geoguessr-styles-scan/code/Geoguessr%20Styles%20Scan.js?version=1246943
// @grant GM_xmlhttpRequest
// ==/UserScript==
(function() {
'use strict';
// Create and inject the logo HTML and CSS
function createLogo() {
const logoHTML = `
<div id="exodusLogo" class="logo">Version v3.8 [BETA]</div>
`;
const logoCSS = `
.logo {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
font-size: 18px; /* Smaller font size */
color: transparent; /* Hide the text initially */
text-shadow: 0 0 5px rgba(255, 0, 0, 0.8), 0 0 10px rgba(255, 0, 0, 0.8); /* Red text shadow */
background: linear-gradient(45deg, rgba(255, 0, 0, 0.8), rgba(0, 0, 0, 0.8)); /* Gradient from red to black */
background-clip: text; /* Apply the background to the text only */
-webkit-background-clip: text; /* For Safari */
position: fixed;
top: 20px;
left: 25px;
z-index: 9999;
animation: pulse 1s ease-in-out infinite alternate;
}
@keyframes pulse {
0% { transform: scale(1); }
100% { transform: scale(1.1); }
}
`;
// Inject the logo HTML
const logoContainer = document.createElement('div');
logoContainer.innerHTML = logoHTML;
document.body.appendChild(logoContainer);
// Inject the logo CSS
const style = document.createElement('style');
style.textContent = logoCSS;
document.head.appendChild(style);
}
// Call the function to create the logo
createLogo();
/////////////////CHECKS IF USER IS BANNED ON PROFILE///////////////////////////
function checkURL() {
if (location.pathname.includes("/user") || location.pathname.includes("/me/profile")) return 1;
return 0;
}
function insertAfter(newNode, existingNode) {
existingNode.parentNode.insertBefore(newNode, existingNode.nextSibling);
}
async function checkUser(profileId) {
return fetch(location.origin + "/api/v3/users/" + profileId)
.then(out => out.json())
.catch(err => {console.log(err); return null;});
}
let observer = new MutationObserver(() => {
if (checkURL() == 1) {
const profileLink = (location.pathname.includes("/me/profile")) ? document.querySelector('[name="copy-link"]').value : location.href;
const profileId = profileLink.substr(profileLink.lastIndexOf("/") + 1);
checkUser(profileId).then(user => {
if (user !== null) {
if (user.isBanned === false) {
if (document.getElementById("isBanned") == null) {
let proDiv = document.querySelector("[class*='profile-header_accountInfoWrapper__D_iCA']");
let baseDiv = (proDiv) ? proDiv.firstChild : document.querySelector("[data-qa='user-card-title']");
let bannedDiv = document.createElement("div");
bannedDiv.innerHTML = `<div id="isBanned"></div>`;
if (proDiv) {
baseDiv.style = "display: inline-block; margin-right: 10px";
bannedDiv.style.display = "inline-block";
}
insertAfter(bannedDiv, baseDiv);
}
if (document.getElementById("isBanned").innerText !== `Not Banned`) {
document.getElementById("isBanned").innerText = `Not Banned`;
}
} else {
if (document.getElementById("isBanned") == null) {
let proDiv = document.querySelector("[class*='profile-header_accountInfoWrapper__D_iCA']");
let baseDiv = (proDiv) ? proDiv.firstChild : document.querySelector("[data-qa='user-card-title']");
let bannedDiv = document.createElement("div");
bannedDiv.innerHTML = `<div id="isBanned"></div>`;
if (proDiv) {
baseDiv.style = "display: inline-block; margin-right: 10px";
bannedDiv.style.display = "inline-block";
}
insertAfter(bannedDiv, baseDiv);
}
if (document.getElementById("isBanned").innerText !== `User is banned. RIP XD`) {
document.getElementById("isBanned").innerText = `User is banned. RIP XD`;
}
}
}
});
}
});
observer.observe(document.body, { subtree: true, childList: true });
// Observer logic remains the same
// Function to periodically check and update user's ban status
function checkAndUpdateStatus() {
const profileLink = (location.pathname.includes("/me/profile")) ? document.querySelector('[name="copy-link"]').value : location.href;
const profileId = profileLink.substr(profileLink.lastIndexOf("/") + 1);
checkUser(profileId).then(user => {
if (user !== null) {
if (user.isBanned === false) {
if (document.getElementById("isBanned").innerText !== `Not Banned`) {
document.getElementById("isBanned").innerText = `Not Banned`;
}
} else {
if (document.getElementById("isBanned").innerText !== `User is banned. RIP XD`) {
document.getElementById("isBanned").innerText = `User is banned. RIP XD`;
location.replace(location.href.split('#')[0]); // Reload the page without a full refresh
}
}
}
});
}
//////////////////////END////////////////////////////////////
})();
let globalCoordinates = {
lat: 0,
lng: 0
};
let globalPanoID = undefined;
var originalOpen = XMLHttpRequest.prototype.open;
XMLHttpRequest.prototype.open = function(method, url) {
if (url.startsWith('https://maps.googleapis.com/$rpc/google.internal.maps.mapsjs.v1.MapsJsInternalService/GetMetadata')) {
this.addEventListener('load', function () {
let interceptedResult = this.responseText;
const pattern = /-?\d+\.\d+,-?\d+\.\d+/g;
let match = interceptedResult.match(pattern)[0];
let split = match.split(",");
let lat = Number.parseFloat(split[0]);
let lng = Number.parseFloat(split[1]);
globalCoordinates.lat = lat;
globalCoordinates.lng = lng;
});
}
return originalOpen.apply(this, arguments);
};
function placeMarker(safeMode){
let {lat,lng} = globalCoordinates;
if (safeMode) {
const sway = [Math.random() > 0.5, Math.random() > 0.5];
const multiplier = Math.random() * 4;
const horizontalAmount = Math.random() * multiplier;
const verticalAmount = Math.random() * multiplier;
sway[0] ? lat += verticalAmount : lat -= verticalAmount;
sway[1] ? lng += horizontalAmount : lat -= horizontalAmount;
}
let element = document.getElementsByClassName("guess-map_canvas__cvpqv")[0];
if(!element){
placeMarkerStreaks();
return;
}
const keys = Object.keys(element);
const key = keys.find(key => key.startsWith("__reactFiber$"));
const props = element[key];
const x = props.return.return.memoizedProps.map.__e3_.click;
const y = Object.keys(x)[0];
const z = {
latLng:{
lat: () => lat,
lng: () => lng,
}
};
const xy = x[y];
const a = Object.keys(x[y]);
for(let i = 0; i < a.length ;i++){
let q = a[i];
if (typeof xy[q] === "function"){
xy[q](z);
}
}
}
function placeMarkerStreaks(){
let {lat,lng} = globalCoordinates;
let element = document.getElementsByClassName("region-map_mapCanvas__R95Ki")[0];
if(!element){
return;
}
const keys = Object.keys(element);
const key = keys.find(key => key.startsWith("__reactFiber$"));
const props = element[key];
const x = props.return.return.memoizedProps.map.__e3_.click;
const y = Object.keys(x);
const w = "(e.latLng.lat(),e.latLng.lng())}";
const v = {
latLng:{
lat: () => lat,
lng: () => lng,
}
};
for(let i = 0; i < y.length; i++){
const curr = Object.keys(x[y[i]]);
let func = curr.find(l => typeof x[y[i]][l] === "function");
let prop = x[y[i]][func];
if(prop && prop.toString().slice(5) === w){
prop(v);
}
}
}
function mapsFromCoords() {
const {lat, lng} = globalCoordinates;
if (!lat || !lng) {
return;
}
const mapUrl = `https://maps.google.com/?output=embed&q=${lat},${lng}&ll=${lat},${lng}&z=5`;
window.open(mapUrl, '_blank', 'width=600,height=600,resizable=yes,scrollbars=yes');
}
// Add a black box on the right side of the screen
function createBlackBox() {
const blackBox = document.createElement('div');
blackBox.id = 'blackBox'; // Adding an ID for easy reference
blackBox.style.position = 'fixed';
blackBox.style.top = '0'; // Set the top position to 0 for top of the page
blackBox.style.left = '50%'; // Center horizontally
blackBox.style.transform = 'translateX(-50%)'; // Center horizontally
blackBox.style.width = '200px';
blackBox.style.height = '2%';
blackBox.style.backgroundColor = 'black';
blackBox.style.color = 'white';
blackBox.style.padding = '20px';
blackBox.style.zIndex = '9999';
blackBox.style.outline = '2px solid red'; // Add red outline
blackBox.innerHTML = '<span style="font-size: 16px;">Press INSERT to view the guide</span>';
document.body.appendChild(blackBox);
// Schedule the removal of the black box after 5 seconds
setTimeout(function() {
const blackBoxToRemove = document.getElementById('blackBox');
if (blackBoxToRemove) {
blackBoxToRemove.style.opacity = '0';
setTimeout(function() {
blackBoxToRemove.remove();
}, 1000); // Fade out transition time
}
}, 9000); // 5 seconds
}
// Call the function to create the black box on page load
createBlackBox();
let popupVisible = false;
function togglePopup() {
const popup = document.getElementById('popup');
if (!popup) {
// Create popup element
const popupElement = document.createElement('div');
popupElement.id = 'popup';
popupElement.style.position = 'fixed';
popupElement.style.top = '50%';
popupElement.style.left = '50%';
popupElement.style.transform = 'translate(-50%, -50%)';
popupElement.style.backgroundColor = 'black';
popupElement.style.color = 'white';
popupElement.style.padding = '20px';
popupElement.style.zIndex = '9999';
// Create an inner div for the text content
const textDiv = document.createElement('div');
textDiv.innerHTML = 'Press [1] to pick an close spot to the destination pin<br><br>Press [2] to place your pin on the exact location of the destination<br><br>Press [3] to open an separate window that opens google maps on the exact location<br><br>-----------------------------------------------------------------------------------------<br><br>Press [P] in classic maps / world when you are in the match to start farming';
popupElement.appendChild(textDiv);
// Create an inner div for the rainbow border
const borderDiv = document.createElement('div');
borderDiv.classList.add('popup-border');
popupElement.appendChild(borderDiv);
document.body.appendChild(popupElement);
popupVisible = true;
} else {
popup.style.display = popupVisible ? 'none' : 'block';
popupVisible = !popupVisible;
}
// Dynamically adjust the rainbow border size
const borderDiv = document.querySelector('.popup-border');
if (borderDiv) {
const popupContent = document.getElementById('popup');
if (popupContent) {
borderDiv.style.width = `${popupContent.offsetWidth}px`;
borderDiv.style.height = `${popupContent.offsetHeight}px`;
}
}
}
function pathMatches(path) {
return location.pathname.match(new RegExp(`^/(?:[^/]+/)?${path}$`))
}
function getIndex(element) {
if (!element) return -1
let i = 0
while (element = element.previousElementSibling) {
i++
}
return i
}
const OBSERVER_CONFIG = {
characterDataOldValue: false,
subtree: true,
childList: true,
characterData: false
}
/////////////////////////////////////////////////////////////////////
/// BATTLEROYALE START ///
// Function to check if the desired element is present before loading the main script
const waitForElement = async () => {
while (!document.getElementsByClassName("game-mode-brand_possibleTitle__xR3HP game-mode-brand_selected__TxTvh")[0]) { // LEAVE IT ON THIS ELEMENT FOR IT TO LOAD NORMALLY! AKA BATTLEROYALE LOGO IN WAITING LOBBY
await new Promise(r => setTimeout(r, 1000));
console.log("Waiting for lobby card...");
}
console.log("Lobby card found. Loading script...");
// Execute the main function
loadScript();
};
// Start checking for the lobby card element
waitForElement();
// Function to load the main script
function loadScript() {
// Main script code goes here
(async function() {
'use strict';
// Define the API URL to retrieve country data (optional)
const apiURL = "https://restcountries.com/v3.1/all?fields=name,flags";
console.log("Script started.");
// Wait until the UI element with class "countries-game-overview_overview__0cpdi" is loaded
while (!document.querySelector(".countries-game-overview_overview__0cpdi")) {
await new Promise(r => setTimeout(r, 1000));
console.log("Waiting for UI to load...");
}
console.log("UI loaded.");
let flagsProcessed = false;
function showNames() {
console.log("Retrieving all guessed flags...");
// Retrieve all elements with class related to guessed flags
let flags = document.querySelectorAll(".countries-game-overview_wrongGuessesFlag__U4XmC");
for (let flag of flags) {
let flag_img = flag.querySelector("img");
if (flag_img && flag_img.getAttribute("alt")) {
let country_code = flag_img.getAttribute("alt").toUpperCase().substring(0, 2); // Get the first two characters of the country code
// Create the country code element
let countryCodeElement = document.createElement("span");
countryCodeElement.textContent = country_code;
countryCodeElement.className = "country-code";
// Position the country code above the flag element
let flagRect = flag.getBoundingClientRect();
let bodyRect = document.body.getBoundingClientRect();
countryCodeElement.style.position = "absolute";
countryCodeElement.style.top = flagRect.top - bodyRect.top - 20 + "px"; // Adjust this value as needed (above the flag)
countryCodeElement.style.left = flagRect.left - bodyRect.left + "px"; // Align with the left edge of the flag
countryCodeElement.style.fontSize = "0.8rem"; // Adjust font size as needed
countryCodeElement.style.zIndex = "9999"; // Ensure the country code appears above the flag
// Insert the country code element above the flag element
document.body.appendChild(countryCodeElement); // Append to the body to position it above the flag element
}
}
flagsProcessed = true;
console.log("All flags processed.");
}
// Add CSS style to position the country code element above the flag image
let style = document.createElement('style');
style.textContent = `
.country-flag_flag__tlHIr {
position: relative;
}
.country-code {
position: absolute !important;
top: -20px !important; /* Adjust this value as needed (above the flag) */
left: 0; /* Align with the left edge of the flag image */
font-size: 0.8rem; /* Adjust font size as needed */
z-index: 9999; /* Ensure the country code appears above the flag image */
}
`;
document.head.appendChild(style);
// **Fix 2: MutationObserver update (for new guesses)**
var observer = new MutationObserver(function(mutations) {
for (let mutation of mutations) {
if (mutation.type === "childList" && mutation.target.className === "countries-game-overview_wrongGuessesFlags__GEhji") {
console.log("New flag guessed. Updating...");
// Loop through added nodes to find new flag elements
for (let addedNode of mutation.addedNodes) {
if (addedNode.classList && addedNode.classList.contains("countries-game-overview_wrongGuessesFlag__U4XmC")) {
// Extract country code and insert element for the new flag
let flag_img = addedNode.querySelector("img");
if (flag_img && flag_img.getAttribute("alt")) {
let country_code = flag_img.getAttribute("alt").toUpperCase().substring(0, 2); // Get the first two characters of the country code
let countryCodeElement = document.createElement("span");
countryCodeElement.textContent = country_code;
countryCodeElement.className = "country-code";
countryCodeElement.style.position = "absolute"; // Absolute positioning for precise placement
countryCodeElement.style.top = "0.2rem"; // Adjust this value as needed (slightly above the flag)
countryCodeElement.style.right = "0.2rem"; // Adjust this value as needed (slightly to the right)
countryCodeElement.style.fontSize = "0.8rem"; // Adjust font size as needed
// Insert the country code element next to the flag image
addedNode.insertBefore(countryCodeElement, addedNode.querySelector("img")); // Insert before the image
}
}
}
}
}
});
// Start observing the "countries-game-overview_wrongGuessesFlags__GEhji" element for child list changes
observer.observe(document.querySelector(".countries-game-overview_wrongGuessesFlags__GEhji"), { attributes: false, childList: true, characterData: false, subtree: true });
// Call the function to process existing flags on startup
showNames();
// Function to reset the script when the match ends
function resetScript() {
// Function to check for the end game screen class
const checkEndGameScreen = async () => {
while (true) {
const endGameScreens = document.querySelectorAll(".popup-view_popupView__TJqKD, .spectate-footer_messageText__jHqwQ");
let foundEndGameScreen = false;
endGameScreens.forEach(screen => {
if (
screen &&
window.getComputedStyle(screen).display !== 'none' &&
!screen.classList.contains('popup-view_isCorrect__oQmkS') && // Exclude correct modal
!screen.classList.contains('popup-view_isItalic__1Fbl4') && // Exclude correct modal
(screen.querySelector('[data-qa="popup-view-lost"]') || // Check for "You were knocked out" text
screen.textContent.includes("You are knocked out.") || // Check for "You are knocked out" text in <p> element
screen.getAttribute("data-qa") === "spectating-modal") // Check for "spectating-modal" data-qa attribute
) {
foundEndGameScreen = true;
}
});
if (foundEndGameScreen) {
// End game screen found, reload the script
console.log("End game screen found. Resetting script...");
observer.disconnect(); // Disconnect the existing observer
waitForElement(); // Restart the script
break; // Exit the loop once the end game screen is found
} else {
// End game screen not found, continue checking
await new Promise(r => setTimeout(r, 1000));
console.log("Looking for end game screen...");
}
}
};
// Start checking for the end game screen class
checkEndGameScreen();
}
// Start observing for match end
resetScript();
})();
};
/////////////////////////////////////////////////////////////////////
/// BATTLEROYALE END ///
/////////////// DEPLOY EXTRA INFORMATION BOX ///////////////////
// Define coordinatesData object
const coordinatesData = {
lat: null,
lng: null
};
// Function to resolve the location, fetch country information, and apply overlay on the map
async function resolveLocationAndApplyOverlayNew() {
const { lat, lng } = coordinatesData;
try {
const countryInfo = lat && lng ? await fetchCountryInfoNew(lat, lng) : null;
showCountryInfoNew(countryInfo); // Display the country info
} catch (error) {
console.error('Error fetching country information:', error);
}
}
// Function to display the country name, state, and city on the site with black outline around the letters
function showCountryInfoNew(countryInfo) {
let countryInfoElement = document.getElementById('geoguessr-country-info');
if (!countryInfoElement) {
countryInfoElement = document.createElement('div');
countryInfoElement.id = 'geoguessr-country-info';
countryInfoElement.classList.add('geoguessr-country-info');
countryInfoElement.style.position = 'fixed';
countryInfoElement.style.top = '70%';
countryInfoElement.style.right = '10px';
countryInfoElement.style.width = '200px'; // Fixed width
countryInfoElement.style.height = 'auto'; // Auto height
countryInfoElement.style.transform = 'translateY(-50%)';
countryInfoElement.style.fontFamily = 'Arial, sans-serif'; // Set font family
countryInfoElement.style.fontSize = '20px'; // Set font size
countryInfoElement.style.color = 'transparent';
countryInfoElement.style.webkitBackgroundClip = 'text';
countryInfoElement.style.animation = 'rainbow 10s linear infinite';
countryInfoElement.style.textShadow = '0 2 5px white'; // Add black outline around the letters
countryInfoElement.style.padding = '10px';
countryInfoElement.style.borderRadius = '10px';
countryInfoElement.style.boxShadow = '0 4px 8px rgba(0, 0, 0, 0.3)';
countryInfoElement.style.background = 'rgba(0, 0, 0, 0.5)'; // Semi-transparent black background
countryInfoElement.style.zIndex = '9999'; // Ensure it appears on top of other elements
document.body.appendChild(countryInfoElement);
// Add minimize button
const minimizeButton = document.createElement('span');
minimizeButton.classList.add('geoguessr-minimize-button');
minimizeButton.innerHTML = '✖'; // Unicode for 'X'
minimizeButton.style.position = 'absolute';
minimizeButton.style.top = '5px';
minimizeButton.style.right = '5px';
minimizeButton.style.cursor = 'pointer';
minimizeButton.style.color = 'white';
minimizeButton.style.zIndex = '99999'; // Ensure it appears on top of other elements
minimizeButton.addEventListener('click', toggleCountryInfoSize);
countryInfoElement.appendChild(minimizeButton);
// Make the text draggable
makeElementDraggableNew(countryInfoElement);
}
// Set the text content with rainbow-colored text
countryInfoElement.innerHTML = '';
if (countryInfo) {
countryInfoElement.innerHTML +=
`<div style="animation: rainbow 10s linear infinite">Country: ${countryInfo.country || 'N/A'}</div>` +
`<div style="animation: rainbow 10s linear infinite">State: ${countryInfo.state || 'N/A'}</div>` +
`<div style="animation: rainbow 10s linear infinite">City: ${countryInfo.city || 'N/A'}</div>`;
} else {
countryInfoElement.innerHTML =
`<div style="animation: rainbow 10s linear infinite">Country: N/A</div>` +
`<div style="animation: rainbow 10s linear infinite">State: N/A</div>` +
`<div style="animation: rainbow 10s linear infinite">City: N/A</div>`;
}
}
// Function to make an element draggable
function makeElementDraggableNew(element) {
let pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0;
element.onmousedown = dragMouseDownNew;
function dragMouseDownNew(e) {
e = e || window.event;
e.preventDefault();
pos3 = e.clientX;
pos4 = e.clientY;
document.onmouseup = closeDragElementNew;
document.onmousemove = elementDragNew;
}
function elementDragNew(e) {
e = e || window.event;
e.preventDefault();
pos1 = pos3 - e.clientX;
pos2 = pos4 - e.clientY;
pos3 = e.clientX;
pos4 = e.clientY;
element.style.top = (element.offsetTop - pos2) + "px";
element.style.left = (element.offsetLeft - pos1) + "px";
}
function closeDragElementNew() {
document.onmouseup = null;
document.onmousemove = null;
}
}
// Function to toggle visibility of country info box
function toggleCountryInfoSize() {
const countryInfoElement = document.getElementById('geoguessr-country-info');
countryInfoElement.classList.toggle('geoguessr-country-info-small');
}
// Function to reset coordinatesData
function resetCoordinatesData() {
coordinatesData.lat = null;
coordinatesData.lng = null;
}
// Function to update country info
async function updateCountryInfo() {
const { lat, lng } = coordinatesData;
try {
let countryInfo;
if (lat !== null && lng !== null) {
countryInfo = await fetchCountryInfoNew(lat, lng);
} else {
countryInfo = null; // Set countryInfo to null when coordinates are not available
resetCoordinatesData(); // Reset coordinatesData when no coordinates are available
}
showCountryInfoNew(countryInfo);
} catch (error) {
console.error('Error fetching country information:', error);
}
}
// Start actively checking for coordinates changes
async function checkForCoordinatesChanges() {
while (true) {
const { lat, lng } = coordinatesData;
try {
if (lat !== null && lng !== null) {
await updateCountryInfo();
}
} catch (error) {
console.error('Error checking for coordinates changes:', error);
}
await new Promise(resolve => setTimeout(resolve, 1000)); // Wait for 1 second before checking again
}
}
// Start checking for coordinates changes
checkForCoordinatesChanges();
// Intercept the API call to retrieve coordinates
var originalOpen1 = XMLHttpRequest.prototype.open;
XMLHttpRequest.prototype.open = function (method, url) {
if (url.startsWith('https://maps.googleapis.com/$rpc/google.internal.maps.mapsjs.v1.MapsJsInternalService/GetMetadata')) {
this.addEventListener('load', async function () {
let interceptedResult = this.responseText;
const pattern = /-?\d+\.\d+,-?\d+\.\d+/g;
let match = interceptedResult.match(pattern)[0];
let split = match.split(",");
let lat = Number.parseFloat(split[0]);
let lng = Number.parseFloat(split[1]);
coordinatesData.lat = lat;
coordinatesData.lng = lng;
});
}
return originalOpen1.apply(this, arguments);
};
// Function to fetch country information based on coordinates using Nominatim reverse geocoding API
async function fetchCountryInfoNew(lat, lng) {
try {
const response = await fetch(`https://nominatim.openstreetmap.org/reverse?lat=${lat}&lon=${lng}&format=json`);
if (!response.ok) {
throw new Error(`Failed to fetch country information: ${response.status} ${response.statusText}`);
}
const data = await response.json();
if (data && data.address) {
const country = data.address.country || 'Unknown';
const state = data.address.state || 'Unknown';
const city = data.address.city || data.address.town || 'Unknown';
return { country, state, city };
} else {
throw new Error('No country information found');
}
} catch (error) {
console.error('Error fetching country information:', error);
throw error; // Propagate the error further
}
}
// Add CSS styling
const styling = document.createElement('style');
styling.textContent = `
.geoguessr-country-info {
display: block;
}
.geoguessr-country-info-small {
width: auto;
height: 30px;
}
#geoguessr-country-info {
position: fixed;
top: 70%;
right: 10px;
transform: translateY(-50%);
font-family: Arial, sans-serif;
font-size: 20px;
color: transparent;
background: -webkit-linear-gradient(45deg, #e6e6fa, #add8e6, #87cefa, #00ff00, #ffff00, #ffa500, #ff6347);
-webkit-background-clip: text;
animation: rainbow 10s linear infinite;
text-shadow: 0 0 5px rgba(255, 255, 255, 0.5); /* Light white shadow */
-webkit-text-stroke: 1px rgba(255, 255, 255, 0.5); /* Light white outline */
padding: 10px;
border-radius: 10px;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3);
background: rgba(0, 0, 0, 0.5);
border: 2px solid transparent; /* Set initial transparent border */
border-image: linear-gradient(to right, rgba(255,0,0,0), rgba(255,0,0,0.5), rgba(255,0,0,0)) 30; /* Smooth gradient border */
border-image-slice: 1;
}
`;
document.head.appendChild(styling);
// Initially display country info
resolveLocationAndApplyOverlayNew();
/////////////// EBD ///////////////////
// Define CSS animation for rainbow border around black box when pressing insert
const styles = `
@keyframes rainbow-border {
0% { border-color: red; }
16.666% { border-color: orange; }
33.333% { border-color: yellow; }
50% { border-color: green; }
66.666% { border-color: blue; }
83.333% { border-color: indigo; }
100% { border-color: violet; }
}
@keyframes moveHeader {
0% {
transform: translateX(-1px) translateY(-1px);
}
50% {
transform: translateX(1px) translateY(1px);
}
100% {
transform: translateX(-1px) translateY(-1px);
}
}
.header_pageLabel__IIJf8 {
animation: moveHeader 5s infinite alternate;
}
.custom-menu-position {
justify-content: flex-end; /* Aligns items to the right */
/* Add more custom positioning styles as needed */
}
.header_header__JSEeB {
/* Add CSS properties to position the header to the right */
display: flex;
justify-content: flex-end; /* Aligns header to the right */
/* Add more custom styling as needed */
}
.header_pageLabel__IIJf8 {
/* Add CSS properties to ensure the menu stays on the right */
/* You may need to adjust other properties such as margin or padding */
/* Add more custom styling as needed */
}
.popup-border {
position: absolute;
top: 0;
left: 50%; /* Adjust left position as needed */
transform: translateX(-50%); /* Center the border horizontally */
border: 5px solid transparent;
box-sizing: border-box; /* Include padding in width and height */
animation: rainbow-border 5s infinite;
pointer-events: none; /* Make sure the border doesn't interfere with mouse events */
}
/* Tooltip container */
.tooltip {
position: relative;
display: inline-block;
border-bottom: 1px dotted black; /* If you want dots under the hoverable text */
}
.primary-menu_wrapper__3ahEU {
position: absolute;
left: calc(40% - 180px);
top: 30%;
transform: translate(-50%, -50%);
width: 360px;
height: 530px;
background-color: black;
border: 2px solid limegreen; /* Change border color to lime green */
border-radius: 10px;
z-index: 9999;
/* Add animation properties */
animation: pulse1 2s infinite; /* Use pulse1 as the animation name */
animation-name: pulse1; /* Specify the animation name */
}
@keyframes pulse1 {
0% {
border-color: limegreen; /* Start with lime green */
}
50% {
border-color: red; /* Change to red halfway through */
}
100% {
border-color: limegreen; /* Return to lime green */
}
}
.game-menu-button_button__qIY8u:hover {
animation: color-sweep 5s infinite;
}
@keyframes color-sweep {
0% { color: rgb(255, 0, 0); }
25% { color: rgb(0, 255, 0); }
50% { color: rgb(0, 0, 255); }
75% { color: rgb(255, 255, 0); }
100% { color: rgb(255, 0, 255); }
}
/* Tooltip text */
.tooltip .tooltiptext {
visibility: hidden;
width: 120px;
background-color: #555;
color: #fff;
text-align: center;
border-radius: 6px;
padding: 5px 0;
position: absolute;
z-index: 1;
bottom: 125%;
left: 50%;
margin-left: -60px;
opacity: 0;
transition: opacity 0.3s;
}
/* Tooltip text shown on hover */
.tooltip:hover .tooltiptext {
visibility: visible;
opacity: 1;
}
/* Custom styling for the signed-in-start-page_menu__2CH3S */
signed-in-start-page_menu__2CH3S {
width: 130%; /* Adjust this value to change the length of the divider */
left: 133%; /* Adjust this value to move the divider more to the right */
}
/* Custom styling for the footer_footer__tc8Gv */
.footer_footer__tc8Gv {
margin-bottom: 20px; /* Adjust this value to move the footer up or down */
}
.primary-menu-button_flairContainer__YaBOt {
margin-left: 223px; /* Adjust this value to move the button further to the right */
}
/* GIF background for the site */
body {
background-image: url('https://images-wixmp-ed30a86b8c4ca887773594c2.wixmp.com/f/b7f09246-ac57-40d3-97ac-4ed7562a8152/df3i4lx-0132abba-7479-4bd3-939c-9fca9c792cbc.gif?token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ1cm46YXBwOjdlMGQxODg5ODIyNjQzNzNhNWYwZDQxNWVhMGQyNmUwIiwiaXNzIjoidXJuOmFwcDo3ZTBkMTg4OTgyMjY0MzczYTVmMGQ0MTVlYTBkMjZlMCIsIm9iaiI6W1t7InBhdGgiOiJcL2ZcL2I3ZjA5MjQ2LWFjNTctNDBkMy05N2FjLTRlZDc1NjJhODE1MlwvZGYzaTRseC0wMTMyYWJiYS03NDc5LTRiZDMtOTM5Yy05ZmNhOWM3OTJjYmMuZ2lmIn1dXSwiYXVkIjpbInVybjpzZXJ2aWNlOmZpbGUuZG93bmxvYWQiXX0.J8DhZACK1XXgqaCSc4UvdjtXkq4RFL0PsfOQwsjp7bM');
background-size: cover;
background-repeat: repeat;
}
.tooltip {
position: absolute;
background-color: #fff;
border: 1px solid #ccc;
padding: 5px;
border-radius: 5px;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
}
/* Define CSS animation for rainbow background */
@keyframes rainbow-background {
0% { background-color: red; }
12.5% { background-color: orange; }
25% { background-color: yellow; }
37.5% { background-color: green; }
50% { background-color: blue; }
62.5% { background-color: indigo; }
75% { background-color: violet; }
87.5% { background-color: red; }
100% { background-color: orange; }
}
/* RGB border around the site */
html {
border-top: 20px solid transparent;
border-bottom: -30px solid transparent; /* Adjust bottom border width */
border-left: 20px solid transparent; /* Adjust left border width */
border-right: 20px solid transparent; /* Adjust right border width */
animation: rainbow-background 8s infinite linear; /* Adjust the animation duration and timing function */
}
`;
const element = document.getElementById('toggleScript');
if (element) {
// Element exists, access its textContent property
const textContent = element.textContent;
// Do something with textContent
} else {
// Element does not exist, handle the error gracefully
console.error('Element not found.');
}
// ON THE SITE ELEMENTS TO MAKE IT LOOK DIFFERENT
function removeLogoElements() {
const logoElements = document.querySelectorAll('img.header_logoImage__eYuyg');
logoElements.forEach(element => {
element.remove();
});
}
// Function to remove specified elements
function removeElements() {
const elementsToRemove = document.querySelectorAll('.signed-in-start-page_socialAndLegalLinks__kcYwR');
elementsToRemove.forEach(element => {
element.remove();
});
}
// Function to remove specified elements
function removeElements2() {
const elementsToRemove = document.querySelectorAll('.signed-in-start-page_socialAndLegalLinks__kcYwR, .startpage_avatarWrapper__j4Iua');
elementsToRemove.forEach(element => {
element.remove();
});
}
// Function to remove specified elements
function removeElements3() {
const elementsToRemove = document.querySelectorAll('.signed-in-start-page_gradientPlate__A_ziw');
elementsToRemove.forEach(element => {
element.remove();
});
}
// Function to remove specified elements
function removeElements5() {
const elementsToRemove = document.querySelectorAll('.game_inGameLogos__aDZlA');
elementsToRemove.forEach(element => {
element.remove();
});
}
// Function to remove specified elements
function removeElementsWithHrefAndClass() {
const elementsToRemove = document.querySelectorAll('[href="/me/likes"].profile_profileLink__NOzps');
elementsToRemove.forEach(element => {
element.removeAttribute('href');
element.classList.remove('profile_profileLink__NOzps');
});
}
// Remove elements every 2 milliseconds
setInterval(removeElementsWithHrefAndClass, 2);
// Remove specified elements initially
setInterval(removeElements2, 10);
setInterval(removeElements3, 10);
setInterval(removeElements5, 10);
// Check for specified elements every 10,000 seconds and remove them if found
setInterval(removeElements, 10); // 10,000 seconds
// Remove specified elements initially
removeElements();
// Check for specified elements every 10,000 seconds and remove them if found
setInterval(removeElements, 10); // 10,000 seconds
// Check for logo elements every second and remove them if found
setInterval(removeLogoElements, 10);
// Create style element and append to document head
const styleElement = document.createElement('style');
styleElement.textContent = styles;
document.head.appendChild(styleElement);
// Function to check and fade out the specified div if its opacity is back to 1
function checkAndFadeOut() {
const backgroundDiv1 = document.querySelector('.background_background__8Zm0Y.background_backgroundHome__lurxW');
const backgroundDiv2 = document.querySelector('.background_background__8Zm0Y.background_backgroundRankedSystem__wk1Dw');
const backgroundDiv3 = document.querySelector('.background_background__8Zm0Y.background_backgroundProfile__EY4oP');
if (backgroundDiv1 && backgroundDiv1.style.opacity === '1') {
backgroundDiv1.style.transition = 'opacity 1s';
backgroundDiv1.style.opacity = '0';
}
if (backgroundDiv2 && backgroundDiv2.style.opacity === '1') {
backgroundDiv2.style.transition = 'opacity 1s';
backgroundDiv2.style.opacity = '0';
}
if (backgroundDiv3 && backgroundDiv3.style.opacity === '1') {
backgroundDiv3.style.transition = 'opacity 1s';
backgroundDiv3.style.opacity = '0';
}
}
// Set the opacity of the specified classes to 0 after 2 seconds when the page has loaded
window.addEventListener('load', function() {
setTimeout(function() {
checkAndFadeOut(); // Check and fade out initially after 2 seconds
setInterval(checkAndFadeOut, 1000); // Check every 1 second
}, 2000); // 2 seconds delay
});
function togglePopupBox() {
console.log('Toggling popup box...');
const popupBox = document.getElementById('popupBox');
if (popupBox) {
popupBox.style.display = popupBox.style.display === 'none' ? 'block' : 'none';
if (popupBox.style.display === 'block') {
// Schedule the removal of the popup box after 4 seconds
setTimeout(() => {
popupBox.style.opacity = '0';
setTimeout(() => {
popupBox.remove();
}, 1000); // Fade out transition time
}, 4000); // 4 seconds delay before fading out
}
} else {
// Create the popup box if it doesn't exist
const hintMessage = document.createElement('div');
hintMessage.id = 'popupBox';
hintMessage.className = 'popup';
hintMessage.textContent = xpFarmingEnabled ? 'Enabling XP farm, please wait...' : 'Disabling XP farm, please wait...';
document.body.appendChild(hintMessage);
// Schedule the removal of the popup box after 4 seconds
setTimeout(() => {
hintMessage.style.opacity = '0';
setTimeout(() => {
hintMessage.remove();
}, 1000); // Fade out transition time
}, 4000); // 4 seconds delay before fading out
}
}
// Define a global variable to keep track of XP farming status
let xpFarmingEnabled = false;
// Function to create and display the rainbow text
function showXPFarmStatus() {
// Check if the rainbow text element already exists
let rainbowText = document.getElementById('rainbowText');
// If it doesn't exist, create it
if (!rainbowText) {
rainbowText = document.createElement('div');
rainbowText.id = 'rainbowText';
rainbowText.style.position = 'fixed';
rainbowText.style.top = '20px'; // Adjust the top position as needed
rainbowText.style.right = '1400px'; // Adjust the right position as needed
rainbowText.style.fontSize = '16px';
rainbowText.style.fontWeight = 'bold';
rainbowText.style.animation = 'rainbow-text 2s linear infinite'; // Add rainbow animation
document.body.appendChild(rainbowText);
}
// Update the text content based on XP farming status
rainbowText.textContent = xpFarmingEnabled ? 'XP FARM: ENABLED' : 'XP FARM: DISABLED';
}
// Add CSS animation for rainbow text to the existing styleElement
styleElement.textContent += `
@keyframes rainbow-text {
0% { color: red; }
16.666% { color: orange; }
33.333% { color: yellow; }
50% { color: green; }
66.666% { color: blue; }
83.333% { color: indigo; }
100% { color: violet; }
}
`;
async function toggleScript() {
console.log('Toggling script...');
xpFarmingEnabled = !xpFarmingEnabled; // Toggle XP farming status
console.log('XP farming enabled:', xpFarmingEnabled);
showXPFarmStatus(); // Update the rainbow text to reflect the new status
if (xpFarmingEnabled) {
togglePopupBox(); // Display the popup box when enabling XP farm
} else {
togglePopupBox(); // Display the popup box when disabling XP farm
}
isRunning = !isRunning;
if (isRunning) {
runScript();
} else {
isPaused = false; // Reset pause status when stopping the script
}
}
// Function to handle keydown events
function onKeyDown(e) {
if (e.keyCode === 45) {
togglePopup();
}
if (e.keyCode === 49) { // This is for placing a marker around the guessed location
e.stopImmediatePropagation();
placeMarker(true);
}
if (e.keyCode === 50) { // This is for precisely placing the marker on the guessed location
e.stopImmediatePropagation();
placeMarker(false);
}
if (e.keyCode === 51) { // This is for opening a separate window with Google Maps pinpointing the guessed location
e.stopImmediatePropagation();
mapsFromCoords(false);
}
if (e.keyCode === 52) { // This is for placing a marker further than the guessed location
e.stopImmediatePropagation();
}
if (e.key === 'p' || e.key === 'P') { // Check if the key pressed is the 'P' key
toggleScript(); // Call function to toggle XP farming status and start or stop the script
}
}
// Add event listener for keydown events
document.addEventListener("keydown", onKeyDown);
// Call the function to show XP farming status when the script runs
showXPFarmStatus();
const popupStyles = `
.popup {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background-color: rgba(0, 0, 0, 0.8);
color: white;
padding: 20px;
border-radius: 10px;
z-index: 9999;
}
.popup p {
margin: 0;
}
`;
// Append popup styles to existing styleElement
styleElement.textContent += popupStyles;
// Custom button styles
const buttonStyles = `
.custom-button {
position: fixed;
bottom: 20px;
right: 100px; /* Adjust this value to move the button more to the left */
padding: 10px 20px;
font-size: 16px;
font-weight: bold;
text-transform: uppercase;
color: #fff;
background-color: #4CAF50;
border: none;
border-radius: 5px;
cursor: pointer;
transition: background-color 0.3s;
z-index: 9999;
animation: shake 0.5s infinite alternate; /* Shake animation */
}
.custom-button:hover {
background-color: #45a049;
}
/* Shake animation */
@keyframes shake {
0% { transform: translateX(0); }
100% { transform: translateX(-5px); } /* Adjust the distance and direction of the shake */
}
/* Spark animation */
@keyframes spark {
0% { opacity: 0; }
100% { opacity: 1; }
}
.sparks {
position: absolute;
width: 5px;
height: 5px;
background-color: #FFD700; /* Yellow color */
border-radius: 50%;
animation: spark 1s infinite alternate; /* Spark animation */
}
.spark1 {
top: -10px;
left: 0;
}
.spark2 {
top: -5px;
left: 15px;
}
.spark3 {
top: 15px;
left: 5px;
}
.hide {
display: none;
}
`;
// Remove the element on page reload
window.addEventListener('beforeunload', function() {
document.querySelector('.signed-in-start-page_avatar__eLI_o').remove();
});
// Set an interval to sweep-check for the element and remove it if found
setInterval(function() {
var element = document.querySelector('.signed-in-start-page_avatar__eLI_o');
if (element) {
element.remove();
}
}, 1); // Check every 1 second
// Append button styles to existing styleElement
styleElement.textContent += buttonStyles;
// Function to create and append the custom button
function createCustomButton() {
const button = document.createElement('button');
button.className = 'custom-button';
button.textContent = 'Join Discord';
button.onclick = function() {
window.open('https://discord.gg/5MXgjsN8vz', '_blank');
};
document.body.appendChild(button);
}
// Function to create and append the sparks
function createSparks() {
const spark = document.createElement('div');
spark.className = 'spark';
document.body.appendChild(spark);
setTimeout(() => {
spark.remove();
}, 1000);
}
// Function to display tooltips
function displayTooltip() {
const tooltips = [
"Join our server to stay updated!",
"press p in classic maps to farm xp!",
"Click me!!!",
// Add more tips as needed
];
const randomIndex = Math.floor(Math.random() * tooltips.length);
const tooltip = document.createElement('div');
tooltip.className = 'tooltip';
tooltip.textContent = tooltips[randomIndex];
document.body.appendChild(tooltip);
const buttonRect = document.querySelector('.custom-button').getBoundingClientRect();
tooltip.style.top = buttonRect.top - tooltip.offsetHeight - 10 + 'px';
// Calculate the horizontal position based on the current position of the button
let leftPosition = buttonRect.left - tooltip.offsetWidth;
let animationId;
// Animate the tooltip to move with the button
function animateTooltip() {
leftPosition += 1; // Adjust the speed as needed
tooltip.style.left = leftPosition + 'px';
animationId = requestAnimationFrame(animateTooltip);
}
animateTooltip();
// Remove tooltip after some time
setTimeout(() => {
cancelAnimationFrame(animationId);
tooltip.remove();
}, 8000); // 8 seconds
}
// Main function to initialize the button and animations
function init() {
createCustomButton();
setInterval(createSparks, 2000); // Adjust timing for sparks
setInterval(displayTooltip, 50000); // Display tooltip every 5 minutes (300000 milliseconds)
}
// Initialize the script
init();
async function fetchWithCors(url, method, body) {
return await fetch(url, {
"headers": {
"accept": "*/*",
"accept-language": "en-US,en;q=0.8",
"content-type": "application/json",
"sec-fetch-dest": "empty",
"sec-fetch-mode": "cors",
"sec-fetch-site": "same-site",
"sec-gpc": "1",
"x-client": "web"
},
"referrer": "https://www.geoguessr.com/",
"referrerPolicy": "strict-origin-when-cross-origin",
"body": (method == "GET") ? null : JSON.stringify(body),
"method": method,
"mode": "cors",
"credentials": "include"
});
};
let friend_reqs_api = "https://www.geoguessr.com/api/v3/social/friends/summary?page=0&fast=true";
let delete_friend_req_api = (id) => `https://www.geoguessr.com/api/v3/social/friends/${id}`;
async function denyPlayer(id) {
await fetchWithCors(delete_friend_req_api(id), "DELETE", {});
console.log(`${id} denied`);
};
async function acceptPlayer(id) {
await fetchWithCors(delete_friend_req_api(id), "PUT", {});
console.log(`${id} accepted`);
};
function doit(accept) {
fetchWithCors(friend_reqs_api, "GET")
.then(ans => ans.json())
.then(json => {
for (let item of json.requests) {
accept ? acceptPlayer(item.userId) : denyPlayer(item.userId);
}
});
};
document.acceptAll = () => doit(true);
document.denyAll = () => doit(false);
document.doit = doit;
function makeButtons() {
const button = document.createElement("li");
button.classList.add("notification-list_notification__i0DH2");
button.style = "display: flex; justify-content: center; padding: 0 0; padding-bottom: 15px;";
button.innerHTML = `
<div class="notification-list_notificationActions__9JEe6" style="margin: auto;">
<button type="button" class="button_button__aR6_e button_variantPrimary__u3WzI" onclick="doit(true)" id="friend-reqs-true">
<div class="button_wrapper__NkcHZ">
<span>Accept everyone</span>
</div>
</button>
<button type="button" class="button_button__aR6_e button_variantPrimary__u3WzI" onclick="doit(false)" id="friend-reqs-false">
<div class="button_wrapper__NkcHZ">
<span>Deny everyone</span>
</div>
</button>
</div>`;
return button;
}
new MutationObserver(async (mutations) => {
if (document.getElementById("friend-reqs-true") != null) return;
const notifications = document.querySelector('ul[class*="notification-list_notifications__"]') || document.querySelector('div[class*="notification-list_noNotifications__"]');
if (notifications != null) {
const buttons = makeButtons();
notifications.insertBefore(buttons, notifications.childNodes[0]);
}
}).observe(document.body, { subtree: true, childList: true });
// Call the function to create and append the custom button
createCustomButton();
// Function to simulate a Space bar key press
function simulateSpaceKeyPress() {
// Create a new keyboard event for keydown event
const keyDownEvent = new KeyboardEvent('keydown', {
code: 'Space',
key: ' ',
keyCode: 32,
which: 32,
bubbles: true
});
// Dispatch the keydown event
document.dispatchEvent(keyDownEvent);
// Create a new keyboard event for keyup event
const keyUpEvent = new KeyboardEvent('keyup', {
code: 'Space',
key: ' ',
keyCode: 32,
which: 32,
bubbles: true
});
// Dispatch the keyup event after 1 second
setTimeout(() => {
document.dispatchEvent(keyUpEvent);
}, 5000); // Adjust the delay to 1000 milliseconds (1 second)
}
// Function to simulate key presses
async function simulateKeyPress(keyCode) {
const eventDown = new KeyboardEvent('keydown', { keyCode: keyCode });
const eventUp = new KeyboardEvent('keyup', { keyCode: keyCode });
document.dispatchEvent(eventDown);
// Dispatch the keyup event after 1 second
setTimeout(() => {
document.dispatchEvent(eventUp);
}, 5000); // Adjust the delay to 100 milliseconds
}
// Define global variables
let isRunning = false;
let isPaused = false;
async function toggleScript2() {
xpFarmingEnabled = !xpFarmingEnabled; // Toggle XP farming status
showXPFarmStatus(); // Update the rainbow text to reflect the new status
if (!xpFarmingEnabled) {
togglePopupBox(); // Hide the popup box when disabling XP farm
}
isRunning = !isRunning;
if (isRunning) {
runScript();
} else {
isPaused = false; // Reset pause status when stopping the script
}
}
// Function to start or pause the script
async function runScript() {
while (isRunning) {
if (!isPaused) {
await simulateKeyPress(50); // Press '2' key
await simulateSpaceKeyPress(); // Simulate Space bar key press
// Simulate clicking on the game canvas
const canvas = document.querySelector('.guess-map_canvas__cvpqv');
if (canvas) {
canvas.click();
}
// Delay for a short time
await new Promise(resolve => setTimeout(resolve, 500));
} else {
// Delay for a short time
await new Promise(resolve => setTimeout(resolve, 1007));
}
}
}
// Function to add the overlay with the waving hand emoji and text only on the main page
function addWelcomeOverlay() {
// Check if the current URL is the main page of GeoGuessr
if (window.location.pathname === '/') {
const overlay = document.createElement('div');
overlay.id = 'welcomeOverlay';
overlay.style.position = 'fixed';
overlay.style.top = '0';
overlay.style.left = '0';
overlay.style.width = '100vw'; // Adjusted width to viewport width
overlay.style.height = '100vh'; // Adjusted height to viewport height
overlay.style.backgroundColor = 'rgba(0, 0, 0, 1)'; // Initially black with full opacity
overlay.style.display = 'flex';
overlay.style.flexDirection = 'column';
overlay.style.alignItems = 'center';
overlay.style.justifyContent = 'center';
overlay.style.zIndex = '999999'; // Adjusted z-index to make sure it's in the foreground
const handEmoji = document.createElement('span');
handEmoji.style.fontSize = '48px';
handEmoji.textContent = '👋';
handEmoji.style.animation = 'wave 2s infinite'; // Apply animation to the hand emoji
const text = document.createElement('p');
text.style.fontSize = '24px';
text.style.color = 'green'; // Set initial color to green
text.textContent = 'Welcome Back!';
text.style.animation = 'sparkle 1s linear infinite'; // Apply animation to the text
overlay.appendChild(handEmoji);
overlay.appendChild(text);
document.body.appendChild(overlay);
// Add a black background to cover the entire screen
const body = document.querySelector('body');
body.style.overflow = 'hidden'; // Hide scrollbars
body.style.backgroundColor = 'black';
// Fade out the black overlay
setTimeout(() => {
overlay.style.transition = 'opacity 1s'; // Apply transition for opacity change
overlay.style.opacity = '0'; // Fade out the overlay
body.style.overflow = ''; // Restore scrollbars
body.style.backgroundColor = ''; // Restore background color
setTimeout(() => {
overlay.remove(); // Remove the overlay after fading out
}, 1000); // Delay removal to match the transition duration
// Trigger the menu animation to slide in instantly after the overlay has been hidden fully
triggerMenuAnimation();
}, 2000); // Delay the fade-out effect for 2 seconds
}
}
// menu items (can customise following the same structure as the others)
// const [variable name] = `<a href="[link]"> [name to show in menu] </a>`
const singleplayer = `<a href="/singleplayer"> Singleplayer </a>`
const party = `<a href="/play-with-friends"> Party </a>`
const quiz = `<a href="/quiz"> Quiz </a>`
const ongoingGames = `<a href="/me/current"> Ongoing Games </a>`
const activities = `<a href="/me/activities"> Activities </a>`
const likedMaps = `<a href="/me/likes"> Liked Maps </a>`
const newParty = `<a href=/party"> Party </a>`
const profile = `<a href=/me/profile"> Profile </a>`
const badges = `<a href=/me/badges"> Badges </a>`
const account = `<a href=/me/settings"> Account </a>`
const community = `<a href="/community"> Community </a>`
const explorer = `<a href="/explorer"> Explorer </a>`
const dailyChallenge = `<a href="/daily-challenges"> Daily Challenge </a>`
const streaks = `<a href="/streaks"> Streaks </a>`
// items to show in menu (can customise list using variable names defined above)
const items = [ likedMaps, dailyChallenge, explorer, streaks, ongoingGames, ]
// ======================================================================================================================================================
async function setup(items) {
await scanStyles();
const start = `<div class="` + cn("slanted-wrapper_root__") + ` ` + cn("slanted-wrapper_variantGrayTransparent__") + `">
<div class="` + cn("slanted-wrapper_start__") + ` ` + cn("slanted-wrapper_right__") + `"></div>
<div class="` + cn("page-label_labelWrapper__") + `">
<div style="--fs:var(--font-size-12);--lh:var(--line-height-12)" class="` + cn("label_label__") + `">`
const end = `</div></div><div class="` + cn("slanted-wrapper_end__") + ` ` + cn("slanted-wrapper_right__") + `"></div></div>`
let html = ""
for (let item of items) {
html = html + start + item + end
}
return html
}
const refresh = () => {
// only refreshes if not loading
if (document.querySelector("[class^='page-loading_loading__']")) return;
// if header exists
if (document.querySelector("[class^='header_header__']")) {
const header = document.querySelector("[class^='header_header__']")
// hides promos
if (document.querySelector("[class^='header_promoDealButtonWrapper__']")) {
document.querySelector("[class^='header_promoDealButtonWrapper__']").style.display = "none"
}
if (document.querySelector("[class^='header_pageLabel__']")) {
let menu = document.querySelector("[class^='header_pageLabel__07UxK']")
menu.style.display = "flex"
// hides old menu items
for (let child of menu.childNodes) {
if (!child.classList.contains("newItems")) {
child.style.display = "none"
}
}
// adds better menu items
if (document.querySelector(".newItems") === null) {
// creates new div from html
const newItems = document.createElement("div")
newItems.className = "newItems custom-menu-position" // Added custom class for positioning
setup(items).then(function(result) { newItems.innerHTML = result })
newItems.style.display = "flex"
// prepends new div
menu.prepend(newItems)
}
} else if (header.childNodes.length === 2) {
let menu = document.createElement("div")
menu.classList.add(cn("header_pageLabel__"))
menu.style.display = "flex"
header.childNodes[1].before(menu)
header.style.display = "flex"
// adds better menu items
if (document.querySelector(".newItems") === null) {
// creates new div from html
const newItems = document.createElement("div")
newItems.className = "newItems custom-menu-position" // Added custom class for positioning
setup(items).then(function(result) { newItems.innerHTML = result })
newItems.style.display = "flex"
// prepends new div
menu.prepend(newItems)
}
}
// highlights active menu item
if (document.querySelector(".newItems")) {
let url = window.location.href
const newItems = document.querySelector(".newItems")
for (let i = 0; i < newItems.childNodes.length; i++) {
let link = newItems.childNodes[i].querySelector("a")
link.style.color = "white"
newItems.childNodes[i].classList.remove(cn("slanted-wrapper_variantWhite__"))
newItems.childNodes[i].classList.add(cn("slanted-wrapper_variantGrayTransparent__"))
if (link.href == url) {
link.style.color = "#1a1a2e"
newItems.childNodes[i].classList.remove(cn("slanted-wrapper_variantGrayTransparent__"))
newItems.childNodes[i].classList.add(cn("slanted-wrapper_variantWhite__"))
}
}
}
}
// hides maprunner on home
if (document.querySelector("[class^='maprunner-start-page_content__']")) {
document.querySelector("[class^='maprunner-start-page_content__']").style.display = "none"
}
if (document.querySelector("[class^='maprunner-start-page_progress__']")) {
document.querySelector("[class^='maprunner-start-page_progress__']").style.display = "none"
}
if (document.querySelector("[class^='maprunner-class=signed-in-start-page_gradientPlate__A_ziw']")) {
document.querySelector("[class^='maprunner-signed-in-start-page_gradientPlate__']").style.display = "none"
}
if (document.querySelector("[class^='maprunner-signed-in-start-page_avatar__']")) {
document.querySelector("[class^='maprunner-signed-in-start-page_avatar__']").style.display = "none"
}
// hides footer on home
if (document.querySelector("[class^='footer_footer__']")) {
document.querySelector("[class^='footer_footer__']").style.display = "none"
}
// hides secondary menu on home
if (document.querySelector("[class^='secondary-menu_menu__']") && !document.querySelector("[class^='pop-out-main-menu_wrapper__']")) {
document.querySelector("[class^='secondary-menu_menu__']").style.display = "none"
}
// hides ongoing games on home
if (document.querySelector("[class^='primary-menu_continuePlaying__']")) {
document.querySelector("[class^='primary-menu_continuePlaying__']").style.display = "none"
}
// hides daily challenge on home
if (document.querySelector("[class^='play-daily-badge_cardWrapper__']")) {
document.querySelector("[class^='play-daily-badge_cardWrapper__']").style.display = "none"
}
if (document.querySelector("[class^='play-daily-badge_badgeCanvas__']")) {
document.querySelector("[class^='play-daily-badge_badgeCanvas__']").style.display = "none"
}
if (document.querySelector("[class^='happy-holidays-button_root__']")) {
document.querySelector("[class^='happy-holidays-button_root__']").style.display = "none"
}
}
let observer4 = new MutationObserver((mutations) => {
refresh();
});
observer4.observe(document.body, {
characterDataOldValue: false,
subtree: true,
childList: true,
characterData: false
});
// Function to trigger the menu animation to slide in
function triggerMenuAnimation() {
// Define CSS animation for the primary menu wrapper
const menuAnimation = `
@keyframes slideIn {
0% { transform: translateX(-100%); }
100% { transform: translateX(0); }
}
.primary-menu_wrapper__3ahEU {
animation: slideIn 1s forwards; /* Apply the animation without delay */
}
`;
// Append menu animation styles to existing styleElement
const styleElement = document.createElement('style');
styleElement.textContent = menuAnimation;
document.head.appendChild(styleElement);
}
// Function to observe changes in the DOM and trigger menu animation when primary menu wrapper is present
function observeMenuWrapper() {
const menuWrapper = document.querySelector('.primary-menu_wrapper__3ahEU');
if (menuWrapper) {
triggerMenuAnimation();
}
}
// Function to setup the MutationObserver to observe changes in the DOM
function setupObserver() {
const observer = new MutationObserver((mutations) => {
observeMenuWrapper();
});
observer.observe(document.body, {
characterDataOldValue: false,
subtree: true,
childList: true,
characterData: false
});
}
// Call the function to setup the MutationObserver
setupObserver();
// Call the function to trigger the menu animation when the DOM content is fully loaded
document.addEventListener('DOMContentLoaded', () => {
triggerMenuAnimation();
});
// Function to handle key press event
function handleKeyPress(event) {
// Check if the pressed key is the Escape key (key code 27)
if (event.keyCode === 27) {
// Trigger the back button element
const backButtonWrapper = document.querySelector('.back-button_contentWrapper__GN8_N');
if (backButtonWrapper) {
backButtonWrapper.click(); // Simulate a click event on the back button wrapper element
}
}
}
// Add event listener for key press events on the document
document.addEventListener('keydown', handleKeyPress);
// Call the function to add the overlay only when the script runs
addWelcomeOverlay();
// Update CSS animation for the hand emoji
const existingStyleElement = document.querySelector('style');
if (existingStyleElement) {
existingStyleElement.textContent += `
@keyframes wave {
0% { transform: rotate(0deg); }
10% { transform: rotate(-10deg); }
20% { transform: rotate(10deg); }
30% { transform: rotate(-10deg); }
40% { transform: rotate(10deg); }
50% { transform: rotate(-10deg); }
60% { transform: rotate(10deg); }
70% { transform: rotate(-10deg); }
80% { transform: rotate(10deg); }
90% { transform: rotate(-10deg); }
100% { transform: rotate(0deg); }
}
@keyframes sparkle {
0% { color: green; }
50% { color: white; }
100% { color: green; }
}
`;
}
// Call the function to add the overlay when the script runs
addWelcomeOverlay();
/////////////////// faster map closing and opening //////////////////////////
let activeClass;
function main1() {
new MutationObserver(() => {
const guessMap = document.querySelector(
"[data-qa='guess-map']:not([data-skip])",
);
if (!guessMap) return;
guessMap.setAttribute("data-skip", "");
guessMap.addEventListener("mouseenter", () => {
if (activeClass && !isPinned()) {
guessMap.classList.add(activeClass);
}
});
guessMap.addEventListener("mouseleave", () => {
activeClass = guessMap.classList.item(guessMap.classList.length - 1);
if (!isPinned()) {
guessMap.classList.remove(activeClass);
}
});
}).observe(document.body, { childList: true, subtree: true });
}
function isPinned() {
const pinButton = document.querySelector(
"[data-qa='guess-map__control--sticky-active']",
);
let pinned;
if (pinButton) {
pinButton.classList.forEach((cls) => {
if (cls.includes("Active")) {
pinned = true;
}
});
}
return pinned;
}
main1();
/////////////////// END //////////////////////////
// menu items (can customise following the same structure as the others)
// const [variable name] = `<a href="[link]"> [name to show in menu] </a>`
////////////////////////////// Blurring and unblurring email and important things for streaming //////////////////////////////////
// Create a style element
let style = document.createElement('style');
// Define CSS rules with initial blur
style.innerHTML = `
.blurred {
filter: blur(5px) !important;
}
.invite-modal_blurred {
filter: blur(10px) !important;
}
.qr-blurred {
filter: blur(8px) !important;
}
`;
// Append the style element to the document body
document.body.appendChild(style);
// Function to add blur class to elements
function addBlurClass() {
// Select all elements that need to be blurred
const elementsToBlur = document.querySelectorAll('.edit-profile__section div[class^="form-field_formField__"] div p, input[name="email"][data-qa="email-field"], input[name="repeatEmail"], span[class^="copy-link_root__"] input, [class*="invite-modal_section__"]:nth-child(3):nth-child(3), [class*="invite-modal_qr__"]');
// Loop through the selected elements
elementsToBlur.forEach(element => {
element.classList.add('blurred');
if (element.classList.contains('invite-modal_section__')) {
element.classList.add('invite-modal_blurred');
}
if (element.classList.contains('invite-modal_qr__')) {
element.classList.add('qr-blurred');
}
});
}
// Function to remove blur class from elements
function removeBlurClass() {
// Select all elements that need to be unblurred
const elementsToUnblur = document.querySelectorAll('.edit-profile__section div[class^="form-field_formField__"] div p, input[name="email"][data-qa="email-field"], input[name="repeatEmail"], span[class^="copy-link_root__"] input, [class*="invite-modal_section__"]:nth-child(3):nth-child(3), [class*="invite-modal_qr__"]');
// Loop through the selected elements
elementsToUnblur.forEach(element => {
element.classList.remove('blurred');
element.classList.remove('invite-modal_blurred');
element.classList.remove('qr-blurred');
});
}
// Function to reapply blur effect to elements
function reapplyBlurEffect() {
addBlurClass();
}
// Use MutationObserver to continuously monitor the DOM for changes
const observer5 = new MutationObserver(reapplyBlurEffect);
observer5.observe(document.body, { childList: true, subtree: true });
// Call the function to initially blur elements
addBlurClass();
// Function to handle mouseover event
function handleMouseover(event) {
const target = event.target;
target.classList.remove('blurred');
if (target.classList.contains('invite-modal_section__')) {
target.classList.remove('invite-modal_blurred');
}
if (target.classList.contains('invite-modal_qr__')) {
target.classList.remove('qr-blurred');
}
}
// Function to handle mouseout event
function handleMouseout(event) {
const target = event.target;
target.classList.add('blurred');
if (target.classList.contains('invite-modal_section__')) {
target.classList.add('invite-modal_blurred');
}
if (target.classList.contains('invite-modal_qr__')) {
target.classList.add('qr-blurred');
}
}
// Add mouseover and mouseout event listeners to each element
document.querySelectorAll('.edit-profile__section div[class^="form-field_formField__"] div p, input[name="email"][data-qa="email-field"], input[name="repeatEmail"], span[class^="copy-link_root__"] input, [class*="invite-modal_section__"]:nth-child(3):nth-child(3), [class*="invite-modal_qr__"]').forEach(element => {
element.addEventListener('mouseover', handleMouseover);
element.addEventListener('mouseout', handleMouseout);
});
// Reapply blur effect when the URL hash changes
window.addEventListener('hashchange', reapplyBlurEffect);
// Remove blur effect when navigating back to the main menu of the game
document.addEventListener('keydown', function(event) {
if (event.key === "Escape") {
removeBlurClass();
}
});
////////////////////////////// END //////////////////////////////////