Greasy Fork

Greasy Fork is available in English.

RoLocate

Adds filter options to roblox server page. Alternative to paid extensions like RoPro, RoGold (Ultimate), RoQol, and RoKit.

当前为 2025-03-17 提交的版本,查看 最新版本

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         RoLocate
// @namespace    https://oqarshi.github.io/
// @version      33.3
// @description  Adds filter options to roblox server page. Alternative to paid extensions like RoPro, RoGold (Ultimate), RoQol, and RoKit.
// @author       Oqarshi
// @match        https://www.roblox.com/*
// @license      CC-BY-4.0; https://creativecommons.org/licenses/by/4.0/
// @icon         data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wCEAAYEBQYFBAYGBQYHBwYIChAKCgkJChQODwwQFxQYGBcUFhYaHSUfGhsjHBYWICwgIyYnKSopGR8tMC0oMCUoKSgBBwcHCggKEwoKEygaFhooKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKP/AABEIAEAAQAMBEQACEQEDEQH/xAGiAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgsQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5+gEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoLEQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2FxEyIygQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2dri4+Tl5ufo6ery8/T19vf4+fr/2gAMAwEAAhEDEQA/AOE714B+/wDUO9AdQoABQCExxTF0FNIbDHSgAxzQHUTjPSmLQv6HYJqmr21i9zHa+e4QSyA7VJ6Zx6nj8acY8ztc58VX+r0pVVHmsr2W503jH4e3/hWK1uLy4hltJpPLeaJWIiPuPpn8q1qUJU7Ns8vLM+o5i5QpxakleztqdBB8GdRnhSWHV7B4pFDKyqxDA8gjitfqknrc82XF1CDcZUpJr0HH4Kart41SxJ91f/Cj6nLuT/rjhv8An2/wOb8TfDfxBoFu9zNbx3Vqgy8ts2/aPUggHHvjFZTw84anq4LiHBYyShF8sn0en/AOM444rE9vQOM9KA0uL3pD6m34P0N/EWrvp8LbJ2gkkiPYuoyAfrjH41pThzuyODMccsDS9tJaXSfo2e2+CNSh8ceDrzQ9cDfb7Zfs9yrff4+7J9QR+Y9676UlVg4S3Pgs0w8spxscXhvglqu3mvT9GeT+JdV17RI4PDlxdXMEmlySKskUrJ5kbbSvQ8jgkezY7VxzlOHuN7H2OBw2ExbljYxTVRLRpOzV7/8AB9DCXxFrS4K6vqII7i5f/Gs/aS7ne8BhWtaUfuR6r8HfHOpajq/9iazO12ssbNDLJy4KjJUnuCM9fSuvDVpSfLI+R4kyWhQo/WsPHls9UttevlqcN8V9Fh0LxpdQWiBLaZVuI0HRQ2cge2QawxEFCbSPf4fxs8ZgoznrJaP5f8A5DvWB7fUO9Aa3O8+CP/JQLX/rjL/6Ca6ML/ER87xT/wAi+XqvzN/x1qv/AAh3xbTUrGPak0KPdRr0lDEhvx4B+ozWlWXsq3Mjzspwv9qZQ6FR6pvlfa239djf+L3h6HxJ4cg8RaRiWaCISFkH+tgPP5r1/OtcRTU488TzuHMfPAYmWBr6Ju3pL/g7fceERwyyr+6jd+3yqTzXn2P0GU1Fas9Z+Cvg/UoteTW9QtpLW2gRhEJVKtIzDHAPOACefpXZhqUubmZ8fxPm1CWHeFpSUpNq9uiWv3nM/GLVotW8cXJtnDxWyLbBhyCVyW/UkfhWWJkpTdj1eG8LPDYGPPo5Nv79vwOJ71znvdQ70B1O8+CP/JQbX/rjL/6Ca6ML/ER87xT/AMi+XqvzO28T6fb6r8arSxvU328+nMjr7FJOR7jrW84qVdJ9jwsBXnh8jlWpuzU0/wAYlj4a30/hzXb3wVrT7grNJZSN0dTyVHsRzj13CqoycJOlL5GWd0IY7DwzXD9dJLs/+Bt9xHppPw88fNp8hK+HtZbdAT92GT09sE4+hU9qUf3NS3RlVl/beX+2X8alv5r+tfW5ofGvUdd0zQ4ZdImENjIfKuXjX94uenzdgeRxznHPNViZTjH3djm4Yw+ExFdxrq81qu3np3Pnk9eteafpdg70B1E4z2pi0ud78Ecf8LBtf+uMv/oJrfC/xEfPcUW/s+XqvzPQdR/5L5pf/Xkf/QJK6X/vC9D5uj/yT9T/ABfrE5L453Etn49sLm2kMc8VpG6OOqsJHINY4ptVE0ezwpThVy+cJq6cmn9yO8ItPih8O8jYl8o/783Cj+Rz+TetdGlen5nzq9pkGY94fnF/qvzQeA9TTxb4WvdA19CdQtFNrdRv95h0D/UY6+oz3opS9pFwluh5vhnluLhjMK/cl70e3p6foeDeJtGn8P65dabdj95C+A2OHXqrD6ivPnBwk4s/Q8Fi6eNoRrw2f4PqjL4z2qTq0uL3pD6mv4V1+58NazHqVlFFJMisoWUErgjB6EVpTm6b5kcWYYGGPouhUbSdtvI2ZviBqc3jCDxG1tZi8hi8lYwreWRhhyN2c/Me9W68ufn6nDDIqEcHLApvlbvfS/Ty8uxmeMPE934r1OO+v4YIpUiEIWEELgEnuTzyaipUdR3Z15Zl1PLqTo0m2m762/4HYm8GeMNS8JT3EunLFIk6BXimBKkjoeCORz+dOnVlTehnmeU0MyhGNW6a2atctHx5qS+Lh4it7a0t7xk2Sxxq3lzDGPmBbPp0PYVXt5c/OjH+xKDwf1Kbbje6btdemn9XKvjTxbdeLLi3nv7O0hnhUoHgVgWXrg5Y9OcfU1NWq6mrRtlmV08ti4UpNp9Hb9EjnO9ZHqdQ70BrcO9Aa3CgNQFAK4namLWwppDdwoDUO9AdT//Z
// @grant        GM_xmlhttpRequest
// @require https://update.greasyfork.icu/scripts/526611/1535754/Rolocate%20Base64%20Image%20Library.js
// ==/UserScript==



(function() {
    'use strict';



    function initializeLocalStorage() {
        // Define default settings
        const defaultSettings = {
            enableLogs: false, // disabled by default
            removeads: false, // disabled by default
            togglefilterserversbutton: true, // enable by default
            AutoRunServerRegions: false, // disabled by default
        };

        // Loop through default settings and set them in localStorage if they don't exist
        Object.entries(defaultSettings).forEach(([key, value]) => {
            const storageKey = `ROLOCATE_${key}`;
            if (localStorage.getItem(storageKey) === null) {
                localStorage.setItem(storageKey, value);
            }
        });
    }

    function openSettingsMenu() {
        if (document.getElementById("userscript-settings-menu")) return;

        // Initialize localStorage with default values if they don't exist
        initializeLocalStorage();

        // Create overlay
        const overlay = document.createElement("div");
        overlay.id = "userscript-settings-menu";
        overlay.innerHTML = `
        <div class="settings-container">
            <button id="close-settings" class="close-hover">✖</button>
            <div class="settings-sidebar">
                <h2>Settings</h2>
                <ul>
                    <li class="active" data-section="home">🏠 Home</li>
                    <li data-section="general">⚙️ General</li>
                    <li data-section="appearance">🎨 Appearance</li>
                    <li data-section="advanced">🚀 Advanced</li>
                    <li data-section ="help">📙 Help</li>
                    <li data-section="about">ℹ️ About</li>
                </ul>
            </div>
            <div class="settings-content">
                <h2 id="settings-title">Home</h2>
                <div id="settings-body">${getSettingsContent("home")}</div>
            </div>
        </div>
    `;

        document.body.appendChild(overlay);

        // Inject styles
        const style = document.createElement("style");
        style.textContent = `
        @keyframes fadeIn {
            from { opacity: 0; transform: scale(0.95); }
            to { opacity: 1; transform: scale(1); }
        }
        @keyframes fadeOut {
            from { opacity: 1; transform: scale(1); }
            to { opacity: 0; transform: scale(0.95); }
        }
        @keyframes sectionFade {
            from { opacity: 0; transform: translateY(10px); }
            to { opacity: 1; transform: translateY(0); }
        }

        #userscript-settings-menu {
            position: fixed;
            top: 0; left: 0;
            width: 100vw; height: 100vh;
            background: rgba(0,0,0,0.6);
            display: flex;
            align-items: center;
            justify-content: center;
            z-index: 10000;
            animation: fadeIn 0.3s ease-out;
        }
        .settings-container {
            display: flex;
            position: relative;
            width: 520px; height: 380px;
            background: #1e1e1e;
            border-radius: 14px;
            overflow: hidden;
            box-shadow: 0 12px 24px rgba(0,0,0,0.5);
            font-family: Arial, sans-serif;
        }
        #close-settings {
            position: absolute;
            top: 12px;
            right: 12px;
            background: transparent;
            border: none;
            color: white;
            font-size: 20px;
            cursor: pointer;
            z-index: 10001;
        }
        .settings-sidebar {
            width: 35%;
            background: #272727;
            padding: 15px;
            color: white;
            display: flex;
            flex-direction: column;
            align-items: center;
        }
        .settings-sidebar ul {
            list-style: none;
            padding: 0;
            width: 100%;
        }
        .settings-sidebar li {
            padding: 12px;
            text-align: center;
            cursor: pointer;
            transition: 0.3s;
            border-radius: 6px;
            font-weight: bold;
        }
        .settings-sidebar li:hover, .settings-sidebar .active {
            background: #444;
        }
        /* Custom Scrollbar */
        .settings-content {
            flex: 1;
            padding: 20px;
            color: white;
            text-align: center;
            max-height: 320px;
            overflow-y: auto;
            scrollbar-width: auto;
            scrollbar-color: darkgreen black;
        }

        /* Webkit (Chrome, Safari) Scrollbar */
        .settings-content::-webkit-scrollbar {
            width: 14px; /* Increased thickness but it doesent work for some reason */
        }
        .settings-content::-webkit-scrollbar-track {
            background: black;
            border-radius: 7px;
        }
        .settings-content::-webkit-scrollbar-thumb {
            background: darkgreen;
            border-radius: 7px;
        }
        .settings-content::-webkit-scrollbar-thumb:hover {
            background: #006400; /* Darker green on hover */
        }
        .settings-content h2,
        .settings-content div {
            animation: sectionFade 0.3s ease-in-out;
        }
        .close-hover {
            position: relative;
            color: black;
            transition: color 0.3s ease;
            background: none;
            border: none;
            font-size: 1.5rem;
            cursor: pointer;
        }
        .close-hover::after {
            content: "" !important;
            position: absolute !important;
            left: 0 !important;
            bottom: -2px !important;
            width: 0% !important;
            height: 2px !important;
            background-color: red !important;
            transition: width 0.3s ease !important;
        }
        .close-hover:hover {
            color: red !important;
        }
        .close-hover:hover::after {
            width: 100% !important;
        }

        /* Toggle Slider Styles */
        .toggle-slider {
            display: flex;
            align-items: center;
            margin: 10px 0;
            cursor: pointer;
        }
        .toggle-slider input {
            display: none;
        }
        .toggle-slider .slider {
            position: relative;
            display: inline-block;
            width: 40px;
            height: 20px;
            background-color: #A9A9A9;
            border-radius: 20px;
            margin-right: 10px;
            transition: background-color 0.3s;
        }
        .toggle-slider .slider::before {
            content: "";
            position: absolute;
            height: 16px;
            width: 16px;
            left: 2px;
            bottom: 2px;
            background-color: white;
            border-radius: 50%;
            transition: transform 0.3s;
        }
        .toggle-slider input:checked + .slider {
            background-color: #4CAF50;
        }
        .toggle-slider input:checked + .slider::before {
            transform: translateX(20px);
        }
        .rolocate-logo {
            width: 75px !important;  /* Force width */
            height: 75px !important; /* Ensure proper scaling */
            object-fit: contain; /* Prevent distortion */
            border-radius: 10px; /* Rounded corners */
            display: block;
            margin: 0 auto 10px auto; /* Center and add spacing */
        }
        .version {
            font-size: 14px;
            color: #aaa;
            margin-bottom: 20px;
        }
        .settings-content ul {
            text-align: left;
            list-style-type: none;
            padding: 0;
        }
        .settings-content ul li {
            margin: 10px 0;
        }
        .settings-content ul li a {
            color: #4CAF50;
            text-decoration: none;
        }
        .settings-content ul li a:hover {
            text-decoration: underline;
        }
        .warning_advanced {
            font-size: 14px; /* Adjust size as needed */
            color: red;
            font-weight: bold;
        }
        .average_text {
            font-size: 16px;
            color: grey;
            font-weight: bold;
        }
        h2 {
          text-decoration: underline;
        }

    `;
        document.head.appendChild(style);

        // Sidebar logic with animation
        document.querySelectorAll(".settings-sidebar li").forEach(li => {
            li.addEventListener("click", function() {
                const currentActive = document.querySelector(".settings-sidebar .active");
                if (currentActive) currentActive.classList.remove("active");
                this.classList.add("active");

                const section = this.getAttribute("data-section");
                const settingsBody = document.getElementById("settings-body");
                const settingsTitle = document.getElementById("settings-title");

                // Apply fade-out first
                settingsBody.style.animation = "fadeOut 0.2s ease-in forwards";
                settingsTitle.style.animation = "fadeOut 0.2s ease-in forwards";

                setTimeout(() => {
                    // Update content
                    settingsTitle.textContent = section.charAt(0).toUpperCase() + section.slice(1);
                    settingsBody.innerHTML = getSettingsContent(section);

                    // Apply fade-in animation
                    settingsBody.style.animation = "sectionFade 0.3s ease-in-out forwards";
                    settingsTitle.style.animation = "sectionFade 0.3s ease-in-out forwards";

                    applyStoredSettings();
                }, 200);
            });
        });

        // Close button with fade-out animation
        document.getElementById("close-settings").addEventListener("click", function() {
            overlay.style.animation = "fadeOut 0.3s ease-in forwards";
            setTimeout(() => overlay.remove(), 300);
        });

        // Apply stored settings on open
        applyStoredSettings();
    }

    function getSettingsContent(section) {
        if (section === "home") {
            return `
            <img class="rolocate-logo" src="${window.Base64Images.logo}" alt="ROLOCATE Logo">
            <span class="average_text">Rolocate Settings Menu.</span>
        `;
        }
        if (section === "appearance") {
            return `
            <span class="average_text">Nothing to see here! Come back later for more awesome features! 😊</span>
        `;
        }
        if (section === "advanced") {
            return `
            <span class="warning_advanced">⚠️ Warning: Do not edit unless you know what you're doing! ⚠️</span>
            <label class="toggle-slider">
                <input type="checkbox" id="enableLogs">
                <span class="slider"></span>
                Enable Console Logs
            </label>
            <label class="toggle-slider">
                <input type="checkbox" id="togglefilterserversbutton">
                <span class="slider"></span>
                Enable Filter & Server Hop
            </label>
        `;
        }
        if (section === "about") {
            return `
            <div class="version">Rolocate: Version 33.3</div>
            <h2>Credits</h2>
            <p>This project was created by:</p>
            <ul>
                <li>Developer: <a href="https://www.roblox.com/users/545334824/profile" target="_blank">Oqarshi</a></li>
                <li>Special Thanks: <a href="https://chromewebstore.google.com/detail/btroblox-making-roblox-be/hbkpclpemjeibhioopcebchdmohaieln" target="_blank">Btroblox Team</a></li>
                <li>Roblox Locate: <a href="http://greasyfork.icu/en/scripts/523727-rolocate" target="_blank">GreasyFork</a></li>
                <li>Invite & FAQ Source Code: <a href="https://github.com/Oqarshi/Invite" target="_blank">GitHub</a></li>
                <li>FAQ Website: <a href="https://oqarshi.github.io/Invite/rolocate/index.html" target="_blank">RoLocate FAQ</a></li>
            </ul>
        `;
        } // the help
        if (section === "help") {
            return `
            <h2>General Tab:</h2>
            <ul>
                <li>Auto Run Server Regions: <a>Replaces Roblox's 8 default servers with at least 8 servers, providing detailed info such as location and ping.</a></li>
              <li>Remove All Roblox Ads: <a>Blocks most ads on the roblox site. Still experimental.</a></li>
            </ul>
            <h2>Appearance Tab:</h2>
            <ul>
                <li>Nothing yet!</a></li>
            </ul>
            <h2>Advanced Tab:</h2>
            <ul>
                <li>Enable Console Logs: <a>Enables console.log messages from the script.</a></li>
                <li>Enable Filter & Server Hop: <a>Enables filter and server hop features on the game page.</a></li>
            </ul>
        `;
        } // the general
        return `
      <label class="toggle-slider">
          <input type="checkbox" id="AutoRunServerRegions">
          <span class="slider"></span>
          Auto Run Server Regions
      </label>
      <label class="toggle-slider">
          <input type="checkbox" id="removeads">
          <span class="slider"></span>
          Remove All Roblox Ads
      </label>
    `;
    }

    function applyStoredSettings() {
        document.querySelectorAll("input[type='checkbox']").forEach(checkbox => {
            const storageKey = `ROLOCATE_${checkbox.id}`;
            checkbox.checked = localStorage.getItem(storageKey) === "true";

            checkbox.addEventListener("change", () => {
                localStorage.setItem(storageKey, checkbox.checked);
            });
        });
    }

    function AddSettingsButton() {
        const base64Logo = window.Base64Images.logo;
        const navbarGroup = document.querySelector('.nav.navbar-right.rbx-navbar-icon-group');
        if (!navbarGroup || document.getElementById('custom-logo')) return;

        const li = document.createElement('li');
        li.id = 'custom-logo-container';
        li.style.position = 'relative';

        li.innerHTML = `
        <img id="custom-logo"
             style="
                 margin-top: 6px;
                 margin-left: 6px;
                 width: 26px;
                 cursor: pointer;
                 border-radius: 4px;
                 transition: all 0.2s ease-in-out;
             "
             src="${base64Logo}">
        <span id="custom-tooltip"
              style="
                  visibility: hidden;
                  background-color: black;
                  color: white;
                  text-align: center;
                  padding: 5px;
                  border-radius: 5px;
                  position: absolute;
                  top: 35px;
                  left: 50%;
                  transform: translateX(-50%);
                  white-space: nowrap;
                  font-size: 12px;
                  opacity: 0;
                  transition: opacity 0.2s ease-in-out;
              ">
              Settings
        </span>
    `;

        const logo = li.querySelector('#custom-logo');
        const tooltip = li.querySelector('#custom-tooltip');

        logo.addEventListener('click', () => openSettingsMenu());

        logo.addEventListener('mouseover', () => {
            logo.style.width = '30px';
            logo.style.border = '2px solid white';
            tooltip.style.visibility = 'visible';
            tooltip.style.opacity = '1';
        });

        logo.addEventListener('mouseout', () => {
            logo.style.width = '26px';
            logo.style.border = 'none';
            tooltip.style.visibility = 'hidden';
            tooltip.style.opacity = '0';
        });

        navbarGroup.appendChild(li);
    }




    /*************************************************************************
                      notification function
    *************************************************************************/
    function notifications(message, type = 'info', emoji = '', duration = 3000) {
        // Helper function to darken (or lighten) a hex color.
        // Pass a negative percent to darken, a positive percent to lighten.
        function shadeColor(color, percent) {
            let num = parseInt(color.slice(1), 16),
                amt = Math.round(2.55 * percent),
                R = (num >> 16) + amt,
                G = ((num >> 8) & 0xFF) + amt,
                B = (num & 0xFF) + amt;
            R = Math.max(Math.min(255, R), 0);
            G = Math.max(Math.min(255, G), 0);
            B = Math.max(Math.min(255, B), 0);
            return "#" + ((1 << 24) + (R << 16) + (G << 8) + B).toString(16).slice(1);
        }

        // Inject CSS styles for the toast and close button once
        if (!document.getElementById('toast-styles')) {
            const style = document.createElement('style');
            style.id = 'toast-styles';
            style.innerHTML = `
      #toast-container {
        position: fixed;
        top: 20px;
        right: 20px;
        z-index: 9999;
        display: flex;
        flex-direction: column;
        gap: 10px;
      }

      .toast {
        position: relative;
        min-width: 300px;
        max-width: 400px;
        padding: 15px 20px;
        border-radius: 8px;
        box-shadow: 0 2px 10px rgba(0,0,0,0.15);
        opacity: 0;
        transform: translateX(50px);
        transition: opacity 0.5s ease, transform 0.5s ease;
        font-family: Arial, sans-serif;
        word-wrap: break-word;
      }

      .toast .toast-content {
        display: flex;
        align-items: center;
      }

      .toast .toast-close-btn {
        position: absolute;
        top: 8px;
        right: 12px;
        cursor: pointer;
        font-weight: bold;
        font-size: 18px;
        line-height: 18px;
        color: #fff;
        display: inline-block;
      }

      /* Underline animation for close button */
      .toast .toast-close-btn::after {
        content: '';
        position: absolute;
        left: 0;
        bottom: -2px;
        width: 100%;
        height: 2px;
        background: currentColor;
        transform: scaleX(0);
        transform-origin: left;
        transition: transform 0.3s ease;
      }

      .toast .toast-close-btn:hover::after {
        transform: scaleX(1);
      }

      .toast .progress-bar {
        position: absolute;
        bottom: 0;
        left: 0;
        height: 4px;
        background-color: rgba(255,255,255,0.7);
        width: 100%;
        border-bottom-left-radius: 8px;
        border-bottom-right-radius: 8px;
      }
    `;
            document.head.appendChild(style);
        }

        // Create or get the container
        let container = document.getElementById('toast-container');
        if (!container) {
            container = document.createElement('div');
            container.id = 'toast-container';
            document.body.appendChild(container);
        }

        // Create toast element
        const toast = document.createElement('div');
        toast.className = 'toast';

        // Determine the base color based on type
        let baseColor;
        switch (type.toLowerCase()) {
            case 'success':
                baseColor = '#4CAF50';
                break;
            case 'error':
                baseColor = '#F44336';
                break;
            case 'info':
            default:
                baseColor = '#2196F3';
                break;
        }

        // Create a dark version of the base color (darkened by 20%)
        let darkColor = shadeColor(baseColor, -20);

        // Set a gradient background from the dark variant to the base color
        toast.style.background = `linear-gradient(90deg, ${darkColor}, ${baseColor})`;

        // Create content wrapper with optional emoji
        const content = document.createElement('div');
        content.className = 'toast-content';
        content.innerHTML = `${emoji ? `<span style="margin-right:8px;">${emoji}</span>` : ''}<span>${message}</span>`;
        toast.appendChild(content);

        // Create the close (×) button with underline animation on hover
        const closeBtn = document.createElement('span');
        closeBtn.className = 'toast-close-btn';
        closeBtn.innerHTML = '&times;';
        closeBtn.addEventListener('click', () => removeToast(toast));
        toast.appendChild(closeBtn);

        // Create progress bar
        const progressBar = document.createElement('div');
        progressBar.className = 'progress-bar';
        // Set the progress bar's transition to match the duration
        progressBar.style.transition = `width ${duration}ms linear`;
        toast.appendChild(progressBar);

        // Append toast to container and animate in
        container.appendChild(toast);
        setTimeout(() => {
            toast.style.opacity = '1';
            toast.style.transform = 'translateX(0)';
            // Start progress bar animation
            setTimeout(() => {
                progressBar.style.width = '0%';
            }, 50);
        }, 50);

        // Auto-remove toast after the specified duration
        const removeTimeout = setTimeout(() => removeToast(toast), duration);

        // Function to fade out and remove toast
        function removeToast(toastEl) {
            clearTimeout(removeTimeout);
            toastEl.style.opacity = '0';
            toastEl.style.transform = 'translateX(50px)';
            setTimeout(() => toastEl.remove(), 500);
        }
    }


    function Update_Popup() {
        const VERSION = "V33.3";
        const PREV_VERSION = "V32.3";

        if (localStorage.getItem(PREV_VERSION)) {
            localStorage.removeItem(PREV_VERSION);
        }

        if (localStorage.getItem(VERSION)) return;
        localStorage.setItem(VERSION, "true");

        const css = `
        .first-time-popup {
            display: flex;
            position: fixed;
            inset: 0;
            background: rgba(0, 0, 0, 0.7);
            justify-content: center;
            align-items: center;
            z-index: 1000;
            opacity: 0;
            animation: fadeIn 0.4s ease-in-out forwards;
        }
        .first-time-popup-content {
            background: rgba(25, 25, 25, 0.95);
            border-radius: 18px;
            padding: 30px;
            width: 420px;
            max-width: 90%;
            box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5);
            text-align: center;
            color: #fff;
            transform: scale(0.85);
            animation: scaleUp 0.5s ease-out forwards;
        }
        .popup-header {
            font-size: 22px;
            font-weight: bold;
            color: #4da6ff;
            text-transform: uppercase;
            letter-spacing: 1px;
            margin-bottom: 5px;
        }
        .popup-version {
            font-size: 18px;
            font-weight: bold;
            color: #ffcc00;
            margin-bottom: 15px;
        }
        .popup-info {
            font-size: 15px;
            color: #ccc;
            margin-bottom: 20px;
            line-height: 1.6;
            padding: 10px;
            border-radius: 10px;
            background: rgba(255, 255, 255, 0.05);
        }
        .popup-info a {
            color: #4da6ff;
            text-decoration: none;
            font-weight: bold;
            transition: color 0.3s ease;
        }
        .popup-info a:hover {
            color: #80bfff;
            text-decoration: underline;
        }
        .popup-footer {
            font-size: 14px;
            color: #aaa;
            font-weight: bold;
            margin-top: 10px;
            transition: opacity 0.3s ease-out;
        }
        .popup-footer.hidden {
            opacity: 0;
            visibility: hidden;
        }
        .popup-note {
            font-size: 13px;
            font-weight: bold;
            color: #ff6666;
            margin-top: 8px;
        }
.popup-logo {
    display: block;
    margin: 0 auto 15px;
    width: 80px;  /* Adjust based on your preference */
    height: auto;
    border-radius: 10px;  /* Optional: Adds rounded corners */
}

.first-time-popup-close {
    position: absolute;
    top: 10px;
    right: 15px;
    font-size: 24px;
    font-weight: bold;
    cursor: pointer;
    color: #fff;
    opacity: 0.4;
    transition: opacity 0.3s ease;
    pointer-events: none;
}

.first-time-popup-close.active {
    opacity: 1;
    pointer-events: auto;
}

.first-time-popup-close:hover {
    color: #ff4d4d;
}

.first-time-popup-close::after {
    content: "";
    display: block;
    width: 0%;
    height: 2px;
    background: #ff4d4d;
    transition: width 0.3s ease-out;
}

.first-time-popup-close:hover::after {
    width: 100%;
}

        @keyframes fadeIn {
            from { opacity: 0; }
            to { opacity: 1; }
        }
        @keyframes fadeOut {
            from { opacity: 1; }
            to { opacity: 0; }
        }
        @keyframes scaleUp {
            0% { transform: scale(0.85); }
            60% { transform: scale(1.05); }
            100% { transform: scale(1); }
        }
        @keyframes scaleDown {
            from { transform: scale(1); }
            to { transform: scale(0.85); }
        }
    `;

        const style = document.createElement('style');
        style.type = 'text/css';
        style.innerHTML = css;
        document.head.appendChild(style);

        const popupHTML = `
    <div class="first-time-popup">
        <div class="first-time-popup-content">
            <span class="first-time-popup-close">&times;</span>
            <img class="popup-logo" src="${window.Base64Images.logo}" alt="Rolocate Logo">
            <div class="popup-header"><b>Rolocate Update</b></div>
            <div class="popup-version"><b>Version: ${VERSION}</b></div>
            <div class="popup-info">
                <p>Fixed script to new html changes by Roblox website, plus a new feature: "Remove All Roblox Ads" Disabled by default. Its still experimental and may not block all ads. Check out the <a href="https://oqarshi.github.io/Invite/rolocate/index.html" target="_blank">FAQ page</a>! This won't appear again until the next update.</p>
            <div class="popup-footer">Closing enabled in <span id="countdown-timer"><strong>5</strong></span> seconds...</div>
        </div>
    </div>
`;

        const popupContainer = document.createElement('div');
        popupContainer.innerHTML = popupHTML;
        document.body.appendChild(popupContainer);

        const closeButton = document.querySelector('.first-time-popup-close');
        const popup = document.querySelector('.first-time-popup');
        const countdownTimer = document.getElementById('countdown-timer');
        const footer = document.querySelector('.popup-footer');

        let countdown = 5;
        const countdownInterval = setInterval(() => {
            countdown--;
            countdownTimer.innerHTML = `<strong>${countdown}</strong>`;

            if (countdown <= 0) {
                clearInterval(countdownInterval);
                closeButton.classList.add('active');
                footer.classList.add('hidden'); // Hides the countdown text
            }
        }, 1000);

        closeButton.addEventListener('click', () => {
            popup.style.animation = 'fadeOut 0.4s ease-in-out forwards';
            document.querySelector('.first-time-popup-content').style.animation = 'scaleDown 0.4s ease-in-out forwards';
            setTimeout(() => {
                popup.remove();
            }, 400);
        });
    }

    function removeAds() {
        if (localStorage.getItem("ROLOCATE_removeads") !== "true") {
            return;
        }

        const iframeSelector = `.ads-container iframe,.abp iframe,.abp-spacer iframe,.abp-container iframe,.top-abp-container iframe,
    #AdvertisingLeaderboard iframe,#AdvertisementRight iframe,#MessagesAdSkyscraper iframe,.Ads_WideSkyscraper iframe,
    .profile-ads-container iframe, #ad iframe, iframe[src*="roblox.com/user-sponsorship/"]`;

        const iframes = document.getElementsByTagName("iframe");
        const scripts = document.getElementsByTagName("script");
        const doneMap = new WeakMap();

        function removeElements() {
            // Remove Iframes
            for (let i = iframes.length; i--;) {
                const iframe = iframes[i];
                if (!doneMap.get(iframe) && iframe.matches(iframeSelector)) {
                    iframe.remove();
                    doneMap.set(iframe, true);
                }
            }

            // Remove Scripts
            for (let i = scripts.length; i--;) {
                const script = scripts[i];
                if (doneMap.get(script)) {
                    continue;
                }
                doneMap.set(script, true);

                if (script.src && (
                        script.src.includes("imasdk.googleapis.com") ||
                        script.src.includes("googletagmanager.com") ||
                        script.src.includes("radar.cedexis.com") ||
                        script.src.includes("ns1p.net")
                    )) {
                    script.remove();
                } else {
                    const cont = script.textContent;
                    if (!cont.includes("ContentJS") && (
                            cont.includes("scorecardresearch.com") ||
                            cont.includes("cedexis.com") ||
                            cont.includes("pingdom.net") ||
                            cont.includes("ns1p.net") ||
                            cont.includes("Roblox.Hashcash") ||
                            cont.includes("Roblox.VideoPreRollDFP") ||
                            cont.includes("Roblox.AdsHelper=") ||
                            cont.includes("googletag.enableServices()") ||
                            cont.includes("gtag('config'")
                        )) {
                        script.remove();
                    } else if (cont.includes("Roblox.EventStream.Init")) {
                        script.textContent = cont.replace(/"[^"]*"/g, "\"\"");
                    }
                }
            }

            // Hide Sponsored Game Cards
            document.querySelectorAll(".game-card-native-ad").forEach(ad => {
                const gameCard = ad.closest(".game-card-container");
                if (gameCard) {
                    gameCard.style.display = "none";
                }
            });
        }

        // Observe DOM for dynamically added elements
        new MutationObserver(removeElements).observe(document.body, {
            childList: true,
            subtree: true
        });

        removeElements(); // Initial run
    }



    function ConsoleLogEnabled(...args) {
        if (localStorage.getItem("ROLOCATE_enableLogs") === "true") {
            console.log(...args);
        }
    }



    // Load all required stuff hehehe
    window.addEventListener("load", () => {
        loadBase64Library(() => {
            ConsoleLogEnabled("Loaded Base64Images. It is ready to use!");
        });

        AddSettingsButton(() => {
            ConsoleLogEnabled("Loaded Settings button!");
        });

        Update_Popup();
        initializeLocalStorage();
        removeAds();
    });



    function loadBase64Library(callback, timeout = 5000) {
        let elapsed = 0;
        (function waitForLibrary() {
            if (typeof window.Base64Images === "undefined") {
                if (elapsed < timeout) {
                    elapsed += 50;
                    setTimeout(waitForLibrary, 50);
                } else {
                    ConsoleLogEnabled("Base64Images did not load within the timeout.");
                    notifications('An error occured! No icons will show. Please refresh the page.', 'error', '⚠️', '8000')
                }
            } else {
                if (callback) callback();
            }
        })();
    }


    /*******************************************************
    The code for the random hop button and the filter button on roblox.com/games/*
    *******************************************************/

    if (window.location.href.startsWith("https://www.roblox.com/games/") && localStorage.getItem("ROLOCATE_togglefilterserversbutton") === "true") {
        let Isongamespage = false; // Initially false
        /*********************************************************************************************************************************************************************************************************************************************
                                                                 This is all of the functions for the filter button and the popup for the 7 buttons does not include the functions for the 8 buttons

        *********************************************************************************************************************************************************************************************************************************************/
        /*******************************************************
        name of function: createPopup
        description: Creates a popup with server filtering options and interactive buttons.
        *******************************************************/
        function createPopup() {
            const popup = document.createElement('div');
            popup.className = 'server-filters-dropdown-box'; // Unique class name
            popup.style.cssText = `
        position: absolute;
        width: 210px;
        height: 382px;
        right: 0px;
        top: 30px;
        z-index: 1000;
        border-radius: 5px;
        background-color: rgb(30, 32, 34);
        display: flex;
        flex-direction: column;
        padding: 5px;
    `;

            // Create the header section
            const header = document.createElement('div');
            header.style.cssText = `
        display: flex;
        align-items: center;
        padding: 10px;
        border-bottom: 1px solid #444;
        margin-bottom: 5px;
    `;

            // Add the logo (base64 image)
            const logo = document.createElement('img');
            logo.src = window.Base64Images.logo;
            logo.style.cssText = `
        width: 24px;
        height: 24px;
        margin-right: 10px;
    `;

            // Add the title
            const title = document.createElement('span');
            title.textContent = 'RoLocate';
            title.style.cssText = `
        color: white;
        font-size: 18px;
        font-weight: bold;
    `;

            // Append logo and title to the header
            header.appendChild(logo);
            header.appendChild(title);

            // Append the header to the popup
            popup.appendChild(header);

            // Define unique names, tooltips, experimental status, and explanations for each button
            const buttonData = [{
                    name: "Smallest Servers",
                    tooltip: "**Reverses the order of the server list.** The emptiest servers will be displayed first.",
                    experimental: false
                },
                {
                    name: "Available Space",
                    tooltip: "**Filters out servers which are full.** Servers with space will only be shown.",
                    experimental: false
                },
                {
                    name: "Player Count",
                    tooltip: "**Rolocate will find servers with your specified player count or fewer.** Searching for up to 3 minutes. If no exact match is found, it shows servers closest to the target.",
                    experimental: false
                },
                {
                    name: "Random Shuffle",
                    tooltip: "**Display servers in a completely random order.** Shows servers with space and servers with low player counts in a randomized order.",
                    experimental: false
                },
                {
                    name: "Server Region",
                    tooltip: "**Filters servers by region.** Offering more accuracy than 'Best Connection' in areas with fewer Roblox servers, like India, or in games with high player counts.",
                    experimental: true,
                    experimentalExplanation: "**Experimental**: Still in development and testing. Ping may be inaccurate sometimes because of the Roblox API."
                },
                {
                    name: "Best Connection",
                    tooltip: "**Automatically joins the fastest servers for you.** However, it may be less accurate in regions with fewer Roblox servers, like India, or in games with large player counts.",
                    experimental: true,
                    experimentalExplanation: "**Experimental**: Still in development and testing.  it may be less accurate in regions with fewer Roblox servers"
                },
                {
                    name: "Join Small Server",
                    tooltip: "**Automatically tries to join a server with a very low population.** On popular games servers may fill up very fast so you might not always get in alone.",
                    experimental: false
                },
                {
                    name: "Locate Player",
                    tooltip: "**Finds and joins the server a user is playing on if they are playing this particular game.** Note: May take a while for very popular games.",
                    experimental: true,
                    experimentalExplanation: "**Experimental**: Still in development and testing. It may not be accurate with popular avatars, such as the default Roblox avatars."
                }
            ];

            // Create buttons with unique names, tooltips, experimental status, and explanations
            buttonData.forEach((data, index) => {
                const buttonContainer = document.createElement('div');
                buttonContainer.className = 'server-filter-option';
                buttonContainer.style.cssText = `
            width: 190px;
            height: 30px;
            background-color: #393B3D;
            margin: 5px;
            border-radius: 5px;
            padding: 3.5px;
            position: relative;
            cursor: pointer;
            display: flex;
            align-items: center;
            justify-content: center;
            transition: background-color 0.3s ease;
        `;

                const tooltip = document.createElement('div');
                tooltip.className = 'filter-tooltip';
                tooltip.style.cssText = `
            display: none;
            position: absolute;
            top: -10px;
            left: 200px;
            width: auto;
            inline-size: 200px;
            height: auto;
            background-color: #191B1D;
            color: white;
            padding: 5px;
            border-radius: 5px;
            white-space: pre-wrap;
            font-size: 14px;
        `;

                // Parse tooltip text and replace **...** with bold HTML tags
                tooltip.innerHTML = data.tooltip.replace(/\*\*(.*?)\*\*/g, "<b style='color: #068f00;'>$1</b>");

                const buttonText = document.createElement('p');
                buttonText.style.cssText = `
            margin: 0;
            color: white;
            font-size: 16px;
        `;
                buttonText.textContent = data.name;

                // Add "EXP" label if the button is experimental
                if (data.experimental) {
                    const expLabel = document.createElement('span');
                    expLabel.textContent = 'EXP';
                    expLabel.style.cssText = `
                margin-left: 8px;
                color: gold;
                font-size: 12px;
                font-weight: bold;
                background-color: rgba(255, 215, 0, 0.1);
                padding: 2px 6px;
                border-radius: 3px;
            `;
                    buttonText.appendChild(expLabel);
                }

                // Add experimental explanation tooltip (left side)
                let experimentalTooltip = null;
                if (data.experimental) {
                    experimentalTooltip = document.createElement('div');
                    experimentalTooltip.className = 'experimental-tooltip';
                    experimentalTooltip.style.cssText = `
        display: none;
        position: absolute;
        top: 0;
        right: 200px;
        width: 200px;
        background-color: #191B1D;
        color: white;
        padding: 5px;
        border-radius: 5px;
        font-size: 14px;
        white-space: pre-wrap;
        z-index: 1001;
    `;

                    // Function to replace **text** with bold and gold styled text
                    const formatText = (text) => {
                        return text.replace(/\*\*(.*?)\*\*/g, '<span style="font-weight: bold; color: gold;">$1</span>');
                    };

                    // Apply the formatting to the experimental explanation
                    experimentalTooltip.innerHTML = formatText(data.experimentalExplanation);

                    buttonContainer.appendChild(experimentalTooltip);
                }
                buttonContainer.appendChild(tooltip);
                buttonContainer.appendChild(buttonText);

                buttonContainer.addEventListener('mouseover', () => {
                    tooltip.style.display = 'block';
                    if (data.experimental) {
                        experimentalTooltip.style.display = 'block';
                    }
                    buttonContainer.style.backgroundColor = '#4A4C4E'; // Hover effect
                });
                buttonContainer.addEventListener('mouseout', () => {
                    tooltip.style.display = 'none';
                    if (data.experimental) {
                        experimentalTooltip.style.display = 'none';
                    }
                    buttonContainer.style.backgroundColor = '#393B3D'; // Revert to original color
                });

                buttonContainer.addEventListener('click', () => {
                    switch (index) {
                        case 0:
                            smallest_servers();
                            break;
                        case 1:
                            available_space_servers();
                            break;
                        case 2:
                            player_count_tab();
                            break;
                        case 3:
                            random_servers();
                            break;
                        case 4:
                            createServerCountPopup((totalLimit) => {
                                rebuildServerList(gameId, totalLimit);
                            });
                            break;
                        case 5:
                            rebuildServerList(gameId, 50, true);
                            break;
                        case 6:
                            auto_join_small_server();
                            break;
                        case 7:
                            find_user_server_tab();
                            break;
                    }
                });

                popup.appendChild(buttonContainer);
            });

            return popup;
        }


        /*******************************************************
        name of function: ServerHop
        description: Handles server hopping by fetching and joining a random server, excluding recently joined servers.
        *******************************************************/
        // Main function to handle the server hopping
        function ServerHop() {
            ConsoleLogEnabled("Starting server hop...");
            showLoadingOverlay();

            // Extract the game ID from the URL
            const url = window.location.href;
            const gameId = url.split("/")[4]; // Extracts the game ID, assuming URL is in the format: /games/{gameId}/Title

            ConsoleLogEnabled(`Game ID: ${gameId}`);

            // Array to store server IDs
            let serverIds = [];
            let nextPageCursor = null;
            let pagesRequested = 0;

            // Get the list of all recently joined servers in localStorage
            const allStoredServers = Object.keys(localStorage)
                .filter(key => key.startsWith("recentServers_"))
                .map(key => JSON.parse(localStorage.getItem(key)));

            // Remove any expired servers for all games (older than 15 minutes)
            const currentTime = new Date().getTime();
            allStoredServers.forEach(storedServers => {
                const validServers = storedServers.filter(server => {
                    const lastJoinedTime = new Date(server.timestamp).getTime();
                    return (currentTime - lastJoinedTime) <= 15 * 60 * 1000; // 15 minutes
                });

                // Update localStorage with the valid (non-expired) servers
                localStorage.setItem(`recentServers_${gameId}`, JSON.stringify(validServers));
            });

            // Get the list of recently joined servers for the current game
            const storedServers = JSON.parse(localStorage.getItem(`recentServers_${gameId}`)) || [];

            // Check if there are any recently joined servers and exclude them from selection
            const validServers = storedServers.filter(server => {
                const lastJoinedTime = new Date(server.timestamp).getTime();
                return (currentTime - lastJoinedTime) <= 15 * 60 * 1000; // 15 minutes
            });

            if (validServers.length > 0) {
                ConsoleLogEnabled(`Excluding servers joined in the last 15 minutes: ${validServers.map(s => s.serverId).join(', ')}`);
            } else {
                ConsoleLogEnabled("No recently joined servers within the last 15 minutes. Proceeding to pick a new server.");
            }

            // Function to fetch servers
            function fetchServers(cursor) {
                const url = `https://games.roblox.com/v1/games/${gameId}/servers/0?sortOrder=2&excludeFullGames=true&limit=100${cursor ? `&cursor=${cursor}` : ""}`;

                GM_xmlhttpRequest({
                    method: "GET",
                    url: url,
                    onload: function(response) {
                        ConsoleLogEnabled("API Response:", response.responseText);

                        try {
                            const data = JSON.parse(response.responseText);

                            // If there's an error, log it and return without processing
                            if (data.errors) {
                                ConsoleLogEnabled("Skipping unreadable response:", data.errors[0].message);
                                return;
                            }

                            // After a successful request, wait 0.15 seconds before proceeding
                            setTimeout(() => {
                                if (!data || !data.data) {
                                    ConsoleLogEnabled("Invalid response structure: 'data' is missing or undefined", data);
                                    return;
                                }

                                data.data.forEach(server => {
                                    if (validServers.some(vs => vs.serverId === server.id)) {
                                        ConsoleLogEnabled(`Skipping previously joined server ${server.id}.`);
                                    } else {
                                        serverIds.push(server.id);
                                    }
                                });

                                // Fetch next page if available and within limit
                                if (data.nextPageCursor && pagesRequested < 4) {
                                    pagesRequested++;
                                    ConsoleLogEnabled(`Fetching page ${pagesRequested}...`);
                                    fetchServers(data.nextPageCursor);
                                } else {
                                    pickRandomServer();
                                }
                            }, 150);

                        } catch (error) {
                            ConsoleLogEnabled("Error parsing response:", error);
                        }
                    },
                    onerror: function(error) {
                        ConsoleLogEnabled("Error fetching server data:", error);
                    }
                });
            }

            // Function to pick a random server and join it
            function pickRandomServer() {
                if (serverIds.length > 0) {
                    const randomServerId = serverIds[Math.floor(Math.random() * serverIds.length)];
                    ConsoleLogEnabled(`Joining server: ${randomServerId}`);

                    // Join the game instance with the selected server ID
                    Roblox.GameLauncher.joinGameInstance(gameId, randomServerId);

                    // Store the selected server ID with the time and date in localStorage
                    const timestamp = new Date().toISOString();
                    const newServer = {
                        serverId: randomServerId,
                        timestamp
                    };
                    validServers.push(newServer);

                    // Save the updated list of recently joined servers to localStorage
                    localStorage.setItem(`recentServers_${gameId}`, JSON.stringify(validServers));

                    ConsoleLogEnabled(`Server ${randomServerId} stored with timestamp ${timestamp}`);
                } else {
                    ConsoleLogEnabled("No servers found to join.");
                    notifications("You have joined all the servers recently. No servers found to join.", "error", "⚠️", "5000");
                }
            }

            // Start the fetching process
            fetchServers();
        }


        if (window.location.href.startsWith("https://www.roblox.com/games/")) {

            window.addEventListener("load", () => {
                // Extract game ID from URL
                function findGameId() {
                    const match = window.location.href.match(/games\/(\d+)/);
                    return match ? match[1] : null;
                }

                // Auto-click "Servers" tab if enabled in localStorage
                if (localStorage.ROLOCATE_AutoRunServerRegions === "true") {
                    setTimeout(() => {
                        const serversTab = document.querySelector("#tab-game-instances a");
                        if (serversTab) {
                            serversTab.click();
                        }
                    }, 1000);
                }

                // Auto-run server regions if enabled in localStorage
                if (localStorage.ROLOCATE_AutoRunServerRegions === "true") {
                    setTimeout(() => {
                        const gameId = findGameId();
                        if (gameId) {
                            Loadingbar(true);
                            disableFilterButton(true);
                            disableLoadMoreButton();
                            rebuildServerList(gameId, 16);
                        }
                    }, 2000);
                }
            });



            Isongamespage = true;

            const observer = new MutationObserver((mutations, obs) => {
                const serverListOptions = document.querySelector('.server-list-options');
                const playButton = document.querySelector('.btn-common-play-game-lg.btn-primary-md');

                if (serverListOptions && !document.querySelector('.RL-filter-button')) {
                    const filterButton = document.createElement('a');
                    filterButton.className = 'RL-filter-button';
                    filterButton.style.cssText = `
                color: white;
                font-weight: bold;
                text-decoration: none;
                cursor: pointer;
                margin-left: 10px;
                padding: 5px 10px;
                display: flex;
                align-items: center;
                gap: 5px;
                position: relative;
                margin-top: 4px;
            `;

                    filterButton.addEventListener('mouseover', () => {
                        filterButton.style.textDecoration = 'underline';
                    });
                    filterButton.addEventListener('mouseout', () => {
                        filterButton.style.textDecoration = 'none';
                    });

                    const buttonText = document.createElement('span');
                    buttonText.className = 'RL-filter-text';
                    buttonText.textContent = 'Filters';
                    filterButton.appendChild(buttonText);

                    const icon = document.createElement('span');
                    icon.className = 'RL-filter-icon';
                    icon.textContent = '≡';
                    icon.style.cssText = `font-size: 18px;`;
                    filterButton.appendChild(icon);

                    serverListOptions.appendChild(filterButton);

                    let popup = null;
                    filterButton.addEventListener('click', (event) => {
                        event.stopPropagation();
                        if (popup) {
                            popup.remove();
                            popup = null;
                        } else {
                            popup = createPopup();
                            popup.style.top = `${filterButton.offsetHeight}px`;
                            popup.style.left = '0';
                            filterButton.appendChild(popup);
                        }
                    });

                    document.addEventListener('click', (event) => {
                        if (popup && !filterButton.contains(event.target)) {
                            popup.remove();
                            popup = null;
                        }
                    });
                }

                if (playButton && !document.querySelector('.custom-play-button')) {
                    const buttonContainer = document.createElement('div');
                    buttonContainer.style.cssText = `
                display: flex;
                gap: 10px;
                align-items: center;
                width: 100%;
            `;

                    playButton.style.cssText += `
                flex: 3;
                padding: 10px 12px;
                text-align: center;
            `;

                    const serverHopButton = document.createElement('button');
                    serverHopButton.className = 'custom-play-button';
                    serverHopButton.style.cssText = `
                background-color: #335fff;
                color: white;
                border: none;
                padding: 7.5px 12px;
                cursor: pointer;
                font-weight: bold;
                border-radius: 8px;
                flex: 1;
                text-align: center;
                display: flex;
                align-items: center;
                justify-content: center;
                position: relative;
            `;

                    const tooltip = document.createElement('div');
                    tooltip.textContent = 'Join Random Server / Server Hop';
                    tooltip.style.cssText = `
                position: absolute;
                background-color: rgba(51, 95, 255, 0.8);
                color: white;
                padding: 5px 10px;
                border-radius: 5px;
                font-size: 12px;
                visibility: hidden;
                opacity: 0;
                transition: opacity 0.2s ease-in-out;
                bottom: 100%;
                left: 50%;
                transform: translateX(-50%);
                white-space: nowrap;
            `;
                    serverHopButton.appendChild(tooltip);

                    serverHopButton.addEventListener('mouseover', () => {
                        tooltip.style.visibility = 'visible';
                        tooltip.style.opacity = '1';
                    });

                    serverHopButton.addEventListener('mouseout', () => {
                        tooltip.style.visibility = 'hidden';
                        tooltip.style.opacity = '0';
                    });

                    const logo = document.createElement('img');
                    logo.src = window.Base64Images.icon_serverhop;
                    logo.style.cssText = `
                width: 45px;
                height: 45px;
            `;
                    serverHopButton.appendChild(logo);

                    playButton.parentNode.insertBefore(buttonContainer, playButton);
                    buttonContainer.appendChild(playButton);
                    buttonContainer.appendChild(serverHopButton);

                    serverHopButton.addEventListener('click', () => {
                        ServerHop();
                    });
                }

                if (document.querySelector('.RL-filter-button') && document.querySelector('.custom-play-button')) {
                    obs.disconnect();
                }
            });

            observer.observe(document.body, {
                childList: true,
                subtree: true
            });
        }




        /*********************************************************************************************************************************************************************************************************************************************
                                                                 The End of: This is all of the functions for the filter button and the popup for the 8 buttons does not include the functions for the 8 buttons

        *********************************************************************************************************************************************************************************************************************************************/


        /*********************************************************************************************************************************************************************************************************************************************
                                                                 Functions for the 1st button

        *********************************************************************************************************************************************************************************************************************************************/


        /*******************************************************
        name of function: smallest_servers
        description: Fetches the smallest servers, disables the "Load More" button, shows a loading bar, and recreates the server cards.
        *******************************************************/
        async function smallest_servers() {
            // Disable the "Load More" button and show the loading bar
            Loadingbar(true);
            disableFilterButton(true);
            disableLoadMoreButton();
            notifications("Finding small servers...", "success", "🧐");

            // Get the game ID from the URL
            const gameId = window.location.pathname.split('/')[2];

            // Retry mechanism
            let retries = 3;
            let success = false;

            while (retries > 0 && !success) {
                try {
                    // Use GM_xmlhttpRequest to fetch server data from the Roblox API
                    const response = await new Promise((resolve, reject) => {
                        GM_xmlhttpRequest({
                            method: "GET",
                            url: `https://games.roblox.com/v1/games/${gameId}/servers/0?sortOrder=1&excludeFullGames=true&limit=100`,
                            onload: function(response) {
                                if (response.status === 429) {
                                    reject(new Error('429: Too Many Requests'));
                                } else if (response.status >= 200 && response.status < 300) {
                                    resolve(response);
                                } else {
                                    reject(new Error(`HTTP error! status: ${response.status}`));
                                }
                            },
                            onerror: function(error) {
                                reject(error);
                            }
                        });
                    });

                    const data = JSON.parse(response.responseText);

                    // Process each server
                    for (const server of data.data) {
                        const {
                            id: serverId,
                            playerTokens,
                            maxPlayers,
                            playing
                        } = server;

                        // Pass the server data to the card creation function
                        await rbx_card(serverId, playerTokens, maxPlayers, playing, gameId);
                    }

                    success = true; // Mark as successful if no errors occurred
                } catch (error) {
                    retries--; // Decrement the retry count

                    if (error.message === '429: Too Many Requests' && retries > 0) {
                        ConsoleLogEnabled('Encountered a 429 error. Retrying in 5 seconds...');
                        await new Promise(resolve => setTimeout(resolve, 5000)); // Wait for 5 seconds
                    } else {
                        ConsoleLogEnabled('Error fetching server data:', error);
                        break; // Exit the loop if it's not a 429 error or no retries left
                    }
                } finally {
                    if (success || retries === 0) {
                        // Hide the loading bar and enable the filter button
                        Loadingbar(false);
                        disableFilterButton(false);
                    }
                }
            }
        }



        /*********************************************************************************************************************************************************************************************************************************************
                                                                 Functions for the 2nd button

        *********************************************************************************************************************************************************************************************************************************************/


        /*******************************************************
        name of function: available_space_servers
        description: Fetches servers with available space, disables the "Load More" button, shows a loading bar, and recreates the server cards.
        *******************************************************/
        async function available_space_servers() {
            // Disable the "Load More" button and show the loading bar
            Loadingbar(true);
            disableLoadMoreButton();
            disableFilterButton(true);
            notifications("Finding servers with space...", "success", "🧐");

            // Get the game ID from the URL
            const gameId = window.location.pathname.split('/')[2];

            // Retry mechanism
            let retries = 3;
            let success = false;

            while (retries > 0 && !success) {
                try {
                    // Use GM_xmlhttpRequest to fetch server data from the Roblox API
                    const response = await new Promise((resolve, reject) => {
                        GM_xmlhttpRequest({
                            method: "GET",
                            url: `https://games.roblox.com/v1/games/${gameId}/servers/0?sortOrder=2&excludeFullGames=true&limit=100`,
                            onload: function(response) {
                                if (response.status === 429) {
                                    reject(new Error('429: Too Many Requests'));
                                } else if (response.status >= 200 && response.status < 300) {
                                    resolve(response);
                                } else {
                                    reject(new Error(`HTTP error! status: ${response.status}`));
                                }
                            },
                            onerror: function(error) {
                                reject(error);
                            }
                        });
                    });

                    const data = JSON.parse(response.responseText);

                    // Process each server
                    for (const server of data.data) {
                        const {
                            id: serverId,
                            playerTokens,
                            maxPlayers,
                            playing
                        } = server;

                        // Pass the server data to the card creation function
                        await rbx_card(serverId, playerTokens, maxPlayers, playing, gameId);
                    }

                    success = true; // Mark as successful if no errors occurred
                } catch (error) {
                    retries--; // Decrement the retry count

                    if (error.message === '429: Too Many Requests' && retries > 0) {
                        ConsoleLogEnabled('Encountered a 429 error. Retrying in 10 seconds...');
                        await new Promise(resolve => setTimeout(resolve, 10000)); // Wait for 10 seconds
                    } else {
                        ConsoleLogEnabled('Error fetching server data:', error);
                        break; // Exit the loop if it's not a 429 error or no retries left
                    }
                } finally {
                    if (success || retries === 0) {
                        // Hide the loading bar and enable the filter button
                        Loadingbar(false);
                        disableFilterButton(false);
                    }
                }
            }
        }

        /*********************************************************************************************************************************************************************************************************************************************
                                                                 Functions for the 3rd button

        *********************************************************************************************************************************************************************************************************************************************/


        /*******************************************************
        	name of function: player_count_tab
        	description: Opens a popup for the user to select the max player count using a slider and filters servers accordingly.
        *******************************************************/
        function player_count_tab() {
            // Check if the max player count has already been determined
            if (!player_count_tab.maxPlayers) {
                // Try to find the element containing the player count information
                const playerCountElement = document.querySelector('.text-info.rbx-game-status.rbx-game-server-status.text-overflow');
                if (playerCountElement) {
                    const playerCountText = playerCountElement.textContent.trim();
                    const match = playerCountText.match(/(\d+) of (\d+) people max/);
                    if (match) {
                        const maxPlayers = parseInt(match[2], 10);
                        if (!isNaN(maxPlayers) && maxPlayers > 1) {
                            player_count_tab.maxPlayers = maxPlayers;
                            ConsoleLogEnabled("Found text element with max playercount");
                        }
                    }
                } else {
                    // If the element is not found, extract the gameId from the URL
                    const gameIdMatch = window.location.href.match(/games\/(\d+)/);
                    if (gameIdMatch && gameIdMatch[1]) {
                        const gameId = gameIdMatch[1];
                        // Send a request to the Roblox API to get server information
                        GM_xmlhttpRequest({
                            method: 'GET',
                            url: `https://games.roblox.com/v1/games/${gameId}/servers/public?sortOrder=1&excludeFullGames=true&limit=100`,
                            onload: function(response) {
                                try {
                                    if (response.status === 429) {
                                        // Rate limit error, default to 100
                                        ConsoleLogEnabled("Rate limited defaulting to 100.");
                                        player_count_tab.maxPlayers = 100;
                                    } else {
                                        ConsoleLogEnabled("Valid api response");
                                        const data = JSON.parse(response.responseText);
                                        if (data.data && data.data.length > 0) {
                                            const maxPlayers = data.data[0].maxPlayers;
                                            if (!isNaN(maxPlayers) && maxPlayers > 1) {
                                                player_count_tab.maxPlayers = maxPlayers;
                                            }
                                        }
                                    }
                                    // Update the slider range if the popup is already created
                                    const slider = document.querySelector('.player-count-popup input[type="range"]');
                                    if (slider) {
                                        slider.max = player_count_tab.maxPlayers ? (player_count_tab.maxPlayers - 1).toString() : '100';
                                        slider.style.background = `
                        linear-gradient(
                            to right,
                            #00A2FF 0%,
                            #00A2FF ${slider.value}%,
                            #444 ${slider.value}%,
                            #444 100%
                        );
                    `;
                                    }
                                } catch (error) {
                                    ConsoleLogEnabled('Failed to parse API response:', error);
                                    // Default to 100 if parsing fails
                                    player_count_tab.maxPlayers = 100;
                                    const slider = document.querySelector('.player-count-popup input[type="range"]');
                                    if (slider) {
                                        slider.max = '100';
                                        slider.style.background = `
                        linear-gradient(
                            to right,
                            #00A2FF 0%,
                            #00A2FF ${slider.value}%,
                            #444 ${slider.value}%,
                            #444 100%
                        );
                    `;
                                    }
                                }
                            },
                            onerror: function(error) {
                                ConsoleLogEnabled('Failed to fetch server information:', error);
                                ConsoleLogEnabled('Fallback to 100 players.');
                                // Default to 100 if the request fails
                                player_count_tab.maxPlayers = 100;
                                const slider = document.querySelector('.player-count-popup input[type="range"]');
                                if (slider) {
                                    slider.max = '100';
                                    slider.style.background = `
                    linear-gradient(
                        to right,
                        #00A2FF 0%,
                        #00A2FF ${slider.value}%,
                        #444 ${slider.value}%,
                        #444 100%
                    );
                `;
                                }
                            }
                        });
                    }
                }
            }
            // Create the overlay (backdrop)
            const overlay = document.createElement('div');
            overlay.style.cssText = `
        position: fixed;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        background-color: rgba(0, 0, 0, 0.5);
        z-index: 9999;
        opacity: 0;
        transition: opacity 0.3s ease;
    `;
            document.body.appendChild(overlay);

            // Create the popup container
            const popup = document.createElement('div');
            popup.className = 'player-count-popup';
            popup.style.cssText = `
        position: fixed;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
        background-color: rgb(30, 32, 34);
        padding: 20px;
        border-radius: 10px;
        z-index: 10000;
        box-shadow: 0 0 15px rgba(0, 0, 0, 0.7);
        display: flex;
        flex-direction: column;
        align-items: center;
        gap: 15px;
        width: 300px;
        opacity: 0;
        transition: opacity 0.3s ease, transform 0.3s ease;
    `;

            // Add a close button in the top-right corner (bigger size)
            const closeButton = document.createElement('button');
            closeButton.innerHTML = '&times;'; // Using '×' for the close icon
            closeButton.style.cssText = `
        position: absolute;
        top: 10px;
        right: 10px;
        background: transparent;
        border: none;
        color: #ffffff;
        font-size: 24px; /* Increased font size */
        cursor: pointer;
        width: 36px; /* Increased size */
        height: 36px; /* Increased size */
        border-radius: 50%;
        display: flex;
        align-items: center;
        justify-content: center;
        transition: background-color 0.3s ease, color 0.3s ease;
    `;
            closeButton.addEventListener('mouseenter', () => {
                closeButton.style.backgroundColor = 'rgba(255, 255, 255, 0.1)';
                closeButton.style.color = '#ff4444';
            });
            closeButton.addEventListener('mouseleave', () => {
                closeButton.style.backgroundColor = 'transparent';
                closeButton.style.color = '#ffffff';
            });

            // Add a title
            const title = document.createElement('h3');
            title.textContent = 'Select Max Player Count';
            title.style.cssText = `
        color: white;
        margin: 0;
        font-size: 18px;
        font-weight: 500;
    `;
            popup.appendChild(title);

            // Add a slider with improved functionality and styling
            const slider = document.createElement('input');
            slider.type = 'range';
            slider.min = '1';
            slider.max = player_count_tab.maxPlayers ? (player_count_tab.maxPlayers - 1).toString() : '100';
            slider.value = '1'; // Default value
            slider.step = '1'; // Step for better accuracy
            slider.style.cssText = `
        width: 80%;
        cursor: pointer;
        margin: 10px 0;
        -webkit-appearance: none; /* Remove default styling */
        background: transparent;
    `;
            // Custom slider track
            slider.style.background = `
        linear-gradient(
            to right,
            #00A2FF 0%,
            #00A2FF ${slider.value}%,
            #444 ${slider.value}%,
            #444 100%
        );
        border-radius: 5px;
        height: 6px;
    `;
            // Custom slider thumb
            slider.style.setProperty('--thumb-size', '20px'); /* Larger thumb */
            slider.style.setProperty('--thumb-color', '#00A2FF');
            slider.style.setProperty('--thumb-hover-color', '#0088cc');
            slider.style.setProperty('--thumb-border', '2px solid #fff');
            slider.style.setProperty('--thumb-shadow', '0 0 5px rgba(0, 0, 0, 0.5)');
            slider.addEventListener('input', () => {
                slider.style.background = `
            linear-gradient(
                to right,
                #00A2FF 0%,
                #00A2FF ${slider.value}%,
                #444 ${slider.value}%,
                #444 100%
            );
        `;
                sliderValue.textContent = slider.value; // Update the displayed value
            });
            // Keyboard support for better accuracy (fixed to increment/decrement by 1)
            slider.addEventListener('keydown', (e) => {
                e.preventDefault(); // Prevent default behavior (which might cause jumps)
                let newValue = parseInt(slider.value, 10);
                if (e.key === 'ArrowLeft' || e.key === 'ArrowDown') {
                    newValue = Math.max(1, newValue - 1); // Decrease by 1
                } else if (e.key === 'ArrowRight' || e.key === 'ArrowUp') {
                    newValue = Math.min(100, newValue + 1); // Increase by 1
                }
                slider.value = newValue;
                slider.dispatchEvent(new Event('input')); // Trigger input event to update UI
            });
            popup.appendChild(slider);

            // Add a display for the slider value
            const sliderValue = document.createElement('span');
            sliderValue.textContent = slider.value;
            sliderValue.style.cssText = `
        color: white;
        font-size: 16px;
        font-weight: bold;
    `;
            popup.appendChild(sliderValue);

            // Add a submit button with dark, blackish style
            const submitButton = document.createElement('button');
            submitButton.textContent = 'Search';
            submitButton.style.cssText = `
        padding: 8px 20px;
        font-size: 16px;
        background-color: #1a1a1a; /* Dark blackish color */
        color: white;
        border: none;
        border-radius: 5px;
        cursor: pointer;
        transition: background-color 0.3s ease, transform 0.2s ease;
    `;
            submitButton.addEventListener('mouseenter', () => {
                submitButton.style.backgroundColor = '#333'; /* Slightly lighter on hover */
                submitButton.style.transform = 'scale(1.05)';
            });
            submitButton.addEventListener('mouseleave', () => {
                submitButton.style.backgroundColor = '#1a1a1a';
                submitButton.style.transform = 'scale(1)';
            });

            // Add a yellow box with a tip under the submit button
            const tipBox = document.createElement('div');
            tipBox.style.cssText = `
        width: 100%;
        padding: 10px;
        background-color: rgba(255, 204, 0, 0.15);
        border-radius: 5px;
        text-align: center;
        font-size: 14px;
        color: #ffcc00;
        transition: background-color 0.3s ease;
    `;
            tipBox.textContent = 'Tip: Click the slider and use the arrow keys for more accuracy.';
            tipBox.addEventListener('mouseenter', () => {
                tipBox.style.backgroundColor = 'rgba(255, 204, 0, 0.25)';
            });
            tipBox.addEventListener('mouseleave', () => {
                tipBox.style.backgroundColor = 'rgba(255, 204, 0, 0.15)';
            });
            popup.appendChild(tipBox);

            // Append the popup to the body
            document.body.appendChild(popup);

            // Fade in the overlay and popup
            setTimeout(() => {
                overlay.style.opacity = '1';
                popup.style.opacity = '1';
                popup.style.transform = 'translate(-50%, -50%) scale(1)';
            }, 10);

            /*******************************************************
                name of function: fadeOutAndRemove
                description: Fades out and removes the popup and overlay.
            *******************************************************/
            function fadeOutAndRemove(popup, overlay) {
                popup.style.opacity = '0';
                popup.style.transform = 'translate(-50%, -50%) scale(0.9)';
                overlay.style.opacity = '0';
                setTimeout(() => {
                    popup.remove();
                    overlay.remove();
                }, 300); // Match the duration of the transition
            }

            // Close the popup when clicking outside
            overlay.addEventListener('click', () => {
                fadeOutAndRemove(popup, overlay);
            });

            // Close the popup when the close button is clicked
            closeButton.addEventListener('click', () => {
                fadeOutAndRemove(popup, overlay);
            });

            // Handle submit button click
            submitButton.addEventListener('click', () => {
                const maxPlayers = parseInt(slider.value, 10);
                if (!isNaN(maxPlayers) && maxPlayers > 0) {
                    filterServersByPlayerCount(maxPlayers);
                    fadeOutAndRemove(popup, overlay);
                } else {
                    notifications('Error: Please enter a number greater than 0', 'error', '⚠️', '5000');
                }
            });

            popup.appendChild(submitButton);
            popup.appendChild(closeButton);
        }
        /*******************************************************
        name of function: fetchServersWithRetry
        description: Fetches server data with retry logic and a delay between requests to avoid rate-limiting.
        Uses GM_xmlhttpRequest instead of fetch.
        *******************************************************/
        async function fetchServersWithRetry(url, retries = 15, currentDelay = 750) {
            return new Promise((resolve, reject) => {
                GM_xmlhttpRequest({
                    method: 'GET',
                    url: url,
                    onload: function(response) {
                        // Check for 429 Rate Limit error
                        if (response.status === 429) {
                            if (retries > 0) {
                                const newDelay = currentDelay * 1; // Exponential backoff
                                ConsoleLogEnabled(`[DEBUG] Rate limited. Waiting ${newDelay / 1000} seconds before retrying...`);
                                setTimeout(() => {
                                    resolve(fetchServersWithRetry(url, retries - 1, newDelay)); // Retry with increased delay
                                }, newDelay);
                            } else {
                                ConsoleLogEnabled('[DEBUG] Rate limit retries exhausted.');
                                notifications('Error: Rate limited please try again later.', 'error', '⚠️', '5000')
                                reject(new Error('RateLimit'));
                            }
                            return;
                        }

                        // Handle other HTTP errors
                        if (response.status < 200 || response.status >= 300) {
                            ConsoleLogEnabled('[DEBUG] HTTP error:', response.status, response.statusText);
                            reject(new Error(`HTTP error: ${response.status}`));
                            return;
                        }

                        // Parse and return the JSON data
                        try {
                            const data = JSON.parse(response.responseText);
                            ConsoleLogEnabled('[DEBUG] Fetched data successfully:', data);
                            resolve(data);
                        } catch (error) {
                            ConsoleLogEnabled('[DEBUG] Error parsing JSON:', error);
                            reject(error);
                        }
                    },
                    onerror: function(error) {
                        ConsoleLogEnabled('[DEBUG] Error in GM_xmlhttpRequest:', error);
                        reject(error);
                    }
                });
            });
        }

        /*******************************************************
        name of function: filterServersByPlayerCount
        description: Filters servers to show only those with a player count equal to or below the specified max.
        If no exact matches are found, prioritizes servers with player counts lower than the input.
        Keeps fetching until at least 8 servers are found, with a dynamic delay between requests.
        *******************************************************/
        async function filterServersByPlayerCount(maxPlayers) {
            // Validate maxPlayers before proceeding
            if (isNaN(maxPlayers) || maxPlayers < 1 || !Number.isInteger(maxPlayers)) {
                ConsoleLogEnabled('[DEBUG] Invalid input for maxPlayers.');
                notifications('Error: Please input a valid whole number greater than or equal to 1.', 'error', '⚠️', '5000');
                return;
            }

            // Disable UI elements and clear the server list
            Loadingbar(true);
            disableLoadMoreButton();
            disableFilterButton(true);
            const serverList = document.querySelector('#rbx-public-game-server-item-container');
            serverList.innerHTML = '';

            const gameId = window.location.pathname.split('/')[2];
            let cursor = null;
            let serversFound = 0;
            let serverMaxPlayers = null;
            let isCloserToOne = null;
            let topDownServers = []; // Servers collected during top-down search
            let bottomUpServers = []; // Servers collected during bottom-up search
            let currentDelay = 500; // Initial delay of 0.5 seconds
            const timeLimit = 3 * 60 * 1000; // 3 minutes in milliseconds
            const startTime = Date.now(); // Record the start time
            notifications('Will search for a maximum of 3 minutes to find a server.', 'success', '🔎', '5000');


            try {
                while (serversFound < 16) {
                    // Check if the time limit has been exceeded
                    if (Date.now() - startTime > timeLimit) {
                        ConsoleLogEnabled('[DEBUG] Time limit reached. Proceeding to fallback servers.');
                        notifications('Warning: Time limit reached. Proceeding to fallback servers.', 'warning', '❗', '5000');
                        break;
                    }

                    // Fetch initial data to determine serverMaxPlayers and isCloserToOne
                    if (!serverMaxPlayers) {
                        const initialUrl = cursor ?
                            `https://games.roblox.com/v1/games/${gameId}/servers/public?excludeFullGames=true&limit=100&cursor=${cursor}` :
                            `https://games.roblox.com/v1/games/${gameId}/servers/public?excludeFullGames=true&limit=100`;

                        const initialData = await fetchServersWithRetry(initialUrl);
                        if (initialData.data.length > 0) {
                            serverMaxPlayers = initialData.data[0].maxPlayers;
                            isCloserToOne = maxPlayers <= (serverMaxPlayers / 2);
                        } else {
                            notifications("No servers found in initial fetch.", "error", "⚠️", "5000")
                            ConsoleLogEnabled('[DEBUG] No servers found in initial fetch.', 'warning', '❗');
                            break;
                        }
                    }

                    // Validate maxPlayers against serverMaxPlayers
                    if (maxPlayers >= serverMaxPlayers) {
                        ConsoleLogEnabled('[DEBUG] Invalid input: maxPlayers is greater than or equal to serverMaxPlayers.');
                        notifications(`Error: Please input a number between 1 through ${serverMaxPlayers - 1}`, 'error', '⚠️', '5000');
                        return;
                    }

                    // Adjust the URL based on isCloserToOne
                    const baseUrl = isCloserToOne ?
                        `https://games.roblox.com/v1/games/${gameId}/servers/public?sortOrder=1&excludeFullGames=true&limit=100` :
                        `https://games.roblox.com/v1/games/${gameId}/servers/public?excludeFullGames=true&limit=100`; // why does this work lmao

                    const url = cursor ? `${baseUrl}&cursor=${cursor}` : baseUrl;
                    const data = await fetchServersWithRetry(url);

                    // Safety check: Ensure the server list is valid and iterable
                    if (!Array.isArray(data.data)) {
                        ConsoleLogEnabled('[DEBUG] Invalid server list received. Waiting 1 second before retrying...');
                        await delay(1000); // Wait 1 second before retrying
                        continue; // Skip the rest of the loop and retry
                    }

                    // Filter and process servers
                    for (const server of data.data) {
                        if (server.playing === maxPlayers) {
                            await rbx_card(server.id, server.playerTokens, server.maxPlayers, server.playing, gameId);
                            serversFound++;

                            if (serversFound >= 16) {
                                break;
                            }
                        } else if (!isCloserToOne && server.playing > maxPlayers) {
                            topDownServers.push(server); // Add to top-down fallback list
                        } else if (isCloserToOne && server.playing < maxPlayers) {
                            bottomUpServers.push(server); // Add to bottom-up fallback list
                        }
                    }

                    // Exit if no more servers are available
                    if (!data.nextPageCursor) {
                        break;
                    }

                    cursor = data.nextPageCursor;

                    // Adjust delay dynamically
                    if (currentDelay > 150) {
                        currentDelay = Math.max(150, currentDelay / 2); // Gradually reduce delay
                    }
                    ConsoleLogEnabled(`[DEBUG] Waiting ${currentDelay / 1000} seconds before next request...`);
                    await delay(currentDelay);
                }

                // If no exact matches were found or time limit reached, use fallback servers
                if (serversFound === 0 && (topDownServers.length > 0 || bottomUpServers.length > 0)) {
                    notifications(`There are no servers with ${maxPlayers} players. Showing servers closest to ${maxPlayers} players.`, 'warning', '😔', '8000');
                    // Sort top-down servers by player count (ascending)
                    topDownServers.sort((a, b) => a.playing - b.playing);

                    // Sort bottom-up servers by player count (descending)
                    bottomUpServers.sort((a, b) => b.playing - a.playing);

                    // Combine both fallback lists (prioritize top-down servers first)
                    const combinedFallback = [...topDownServers, ...bottomUpServers];

                    for (const server of combinedFallback) {
                        await rbx_card(server.id, server.playerTokens, server.maxPlayers, server.playing, gameId);
                        serversFound++;

                        if (serversFound >= 16) {
                            break;
                        }
                    }
                }

                if (serversFound <= 0) {
                    notifications('No Servers Found Within The Provided Criteria', 'info', '🔎', '5000');
                }
            } catch (error) {
                ConsoleLogEnabled('[DEBUG] Error in filterServersByPlayerCount:', error);
            } finally {
                Loadingbar(false);
                disableFilterButton(false);
            }
        }

        /*********************************************************************************************************************************************************************************************************************************************
                                                                 Functions for the 4th button

        *********************************************************************************************************************************************************************************************************************************************/

        /*******************************************************
        name of function: random_servers
        description: Fetches servers from two different URLs, combines the results, ensures no duplicates, shuffles the list, and passes the server information to the rbx_card function in a random order. Handles 429 errors with retries.
        *******************************************************/
        async function random_servers() {
            notifications('Finding Random Servers. Please wait 2-5 seconds', 'success', '🔎', '5000');
            // Disable the "Load More" button and show the loading bar
            Loadingbar(true);
            disableFilterButton(true);
            disableLoadMoreButton();

            // Get the game ID from the URL
            const gameId = window.location.pathname.split('/')[2];

            try {
                // Fetch servers from the first URL with retry logic
                const firstUrl = `https://games.roblox.com/v1/games/${gameId}/servers/public?excludeFullGames=true&limit=10`;
                const firstData = await fetchWithRetry(firstUrl, 10); // Retry up to 3 times

                // Wait for 5 seconds
                await delay(1500);

                // Fetch servers from the second URL with retry logic
                const secondUrl = `https://games.roblox.com/v1/games/${gameId}/servers/public?sortOrder=1&excludeFullGames=true&limit=10`;
                const secondData = await fetchWithRetry(secondUrl, 10); // Retry up to 3 times

                // Combine the servers from both URLs
                const combinedServers = [...firstData.data, ...secondData.data];

                // Remove duplicates by server ID
                const uniqueServers = [];
                const seenServerIds = new Set();

                for (const server of combinedServers) {
                    if (!seenServerIds.has(server.id)) {
                        seenServerIds.add(server.id);
                        uniqueServers.push(server);
                    }
                }

                // Shuffle the unique servers array
                const shuffledServers = shuffleArray(uniqueServers);

                // Get the first 16 shuffled servers
                const selectedServers = shuffledServers.slice(0, 16);

                // Process each server in random order
                for (const server of selectedServers) {
                    const {
                        id: serverId,
                        playerTokens,
                        maxPlayers,
                        playing
                    } = server;

                    // Pass the server data to the card creation function
                    await rbx_card(serverId, playerTokens, maxPlayers, playing, gameId);
                }
            } catch (error) {
                ConsoleLogEnabled('Error fetching server data:', error);
                notifications('Error: Failed to fetch server data. Please try again later.', 'error', '⚠️', '5000');
            } finally {
                // Hide the loading bar and enable the filter button
                Loadingbar(false);
                disableFilterButton(false);
            }
        }

        /*******************************************************
        name of function: fetchWithRetry
        description: Fetches data from a URL with retry logic for 429 errors using GM_xmlhttpRequest.
        *******************************************************/
        function fetchWithRetry(url, retries) {
            return new Promise((resolve, reject) => {
                const attemptFetch = (attempt = 0) => {
                    GM_xmlhttpRequest({
                        method: "GET",
                        url: url,
                        onload: function(response) {
                            if (response.status === 429) {
                                if (attempt < retries) {
                                    ConsoleLogEnabled(`Rate limited. Retrying in 2.5 seconds... (Attempt ${attempt + 1}/${retries})`);
                                    setTimeout(() => attemptFetch(attempt + 1), 1500); // Wait 1.5 seconds and retry
                                } else {
                                    reject(new Error('Rate limit exceeded after retries'));
                                }
                            } else if (response.status >= 200 && response.status < 300) {
                                try {
                                    const data = JSON.parse(response.responseText);
                                    resolve(data);
                                } catch (error) {
                                    reject(new Error('Failed to parse JSON response'));
                                }
                            } else {
                                reject(new Error(`HTTP error: ${response.status}`));
                            }
                        },
                        onerror: function(error) {
                            if (attempt < retries) {
                                ConsoleLogEnabled(`Error occurred. Retrying in 10 seconds... (Attempt ${attempt + 1}/${retries})`);
                                setTimeout(() => attemptFetch(attempt + 1), 10000); // Wait 10 seconds and retry
                            } else {
                                reject(error);
                            }
                        }
                    });
                };

                attemptFetch();
            });
        }

        /*******************************************************
        name of function: shuffleArray
        description: Shuffles an array using the Fisher-Yates algorithm.
        *******************************************************/
        function shuffleArray(array) {
            for (let i = array.length - 1; i > 0; i--) {
                const j = Math.floor(Math.random() * (i + 1)); // Random index from 0 to i
                [array[i], array[j]] = [array[j], array[i]]; // Swap elements
            }
            return array;
        }


        /*********************************************************************************************************************************************************************************************************************************************
                                                                 Functions for the 5th button. taken from my other project

        *********************************************************************************************************************************************************************************************************************************************/

        if (Isongamespage) {
            // Create a <style> element
            const style = document.createElement('style');
            style.textContent = `
/* Overlay for the modal background */
.overlay {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background-color: rgba(0, 0, 0, 0.85); /* Solid black overlay */
    z-index: 1000; /* Ensure overlay is below the popup */
    opacity: 0; /* Start invisible */
    animation: fadeIn 0.3s ease forwards; /* Fade-in animation */
}

@keyframes fadeIn {
    from {
        opacity: 0;
    }
    to {
        opacity: 1;
    }
}

/* Popup Container for the server region */
.filter-popup {
    background-color: #1e1e1e; /* Darker background */
    color: #ffffff; /* White text */
    padding: 25px;
    border-radius: 12px;
    box-shadow: 0 8px 20px rgba(0, 0, 0, 0.5);
    width: 320px;
    max-width: 90%;
    position: fixed; /* Fixed positioning */
    top: 50%; /* Center vertically */
    left: 50%; /* Center horizontally */
    transform: translate(-50%, -50%); /* Offset to truly center */
    text-align: center;
    z-index: 1001; /* Ensure popup is above the overlay */
    border: 1px solid #444; /* Subtle border */
    opacity: 0; /* Start invisible */
    animation: fadeInPopup 0.3s ease 0.1s forwards; /* Fade-in animation with delay */
}

@keyframes fadeInPopup {
    from {
        opacity: 0;
        transform: translate(-50%, -55%); /* Slight upward offset */
    }
    to {
        opacity: 1;
        transform: translate(-50%, -50%); /* Center position */
    }
}

/* Fade-out animation for overlay and popup */
.overlay.fade-out {
    animation: fadeOut 0.3s ease forwards;
}

.filter-popup.fade-out {
    animation: fadeOutPopup 0.3s ease forwards;
}

@keyframes fadeOut {
    from {
        opacity: 1;
    }
    to {
        opacity: 0;
    }
}

@keyframes fadeOutPopup {
    from {
        opacity: 1;
        transform: translate(-50%, -50%); /* Center position */
    }
    to {
        opacity: 0;
        transform: translate(-50%, -55%); /* Slight upward offset */
    }
}

/* Close Button for the server selector */
#closePopup {
    position: absolute;
    top: 5px; /* Reduced from 12px to 5px */
    right: 1px; /* Reduced from 12px to 5px */
    background: transparent; /* Transparent background */
    border: none;
    color: #ffffff; /* White color */
    font-size: 20px;
    cursor: pointer;
    width: 28px;
    height: 28px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: background-color 0.3s ease, color 0.3s ease;
}

#closePopup:hover {
    background-color: rgba(255, 255, 255, 0.1); /* Light hover effect */
    color: #ff4444; /* Red color on hover */
}

/* Label */
.filter-popup label {
    display: block;
    margin-bottom: 12px;
    font-size: 16px;
    color: #ffffff;
    font-weight: 500; /* Slightly bolder text */
}

/* Dropdown */
.filter-popup select {
    background-color: #333; /* Darker gray background */
    color: #ffffff; /* White text */
    padding: 10px;
    border-radius: 6px;
    border: 1px solid #555; /* Darker border */
    width: 100%;
    margin-bottom: 12px;
    font-size: 14px;
    transition: border-color 0.3s ease;
}

.filter-popup select:focus {
    border-color: #888; /* Lighter border on focus */
    outline: none;
}

/* Custom Input */
.filter-popup input[type="number"] {
    background-color: #333; /* Darker gray background */
    color: #ffffff; /* White text */
    padding: 10px;
    border-radius: 6px;
    border: 1px solid #555; /* Darker border */
    width: 100%;
    margin-bottom: 12px;
    font-size: 14px;
    transition: border-color 0.3s ease;
}

.filter-popup input[type="number"]:focus {
    border-color: #888; /* Lighter border on focus */
    outline: none;
}

/* Confirm Button */
#confirmServerCount {
    background-color: #444; /* Dark gray background */
    color: #ffffff; /* White text */
    padding: 10px 20px;
    border: 1px solid #666; /* Gray border */
    border-radius: 6px;
    cursor: pointer;
    font-size: 14px;
    width: 100%;
    transition: background-color 0.3s ease, transform 0.2s ease;
}

#confirmServerCount:hover {
    background-color: #555; /* Lighter gray on hover */
    transform: translateY(-1px); /* Slight lift effect */
}

#confirmServerCount:active {
    transform: translateY(0); /* Reset lift effect on click */
}

/* Highlighted server item */
.rbx-game-server-item.highlighted {
    border: 2px solid #4caf50; /* Green border */
    border-radius: 8px;
    background-color: rgba(76, 175, 80, 0.1); /* Subtle green background */
}

/* Disabled fetch button */
.fetch-button:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

/* Popup Header */
.popup-header {
    margin-bottom: 24px;
    text-align: left;
    padding: 16px;
    background-color: rgba(255, 255, 255, 0.05); /* Subtle background for contrast */
    border-radius: 8px;
    border: 1px solid rgba(255, 255, 255, 0.1); /* Subtle border */
    transition: background-color 0.3s ease, border-color 0.3s ease;
}

.popup-header:hover {
    background-color: rgba(255, 255, 255, 0.08); /* Slightly brighter on hover */
    border-color: rgba(255, 255, 255, 0.2);
}

.popup-header h3 {
    margin: 0 0 12px 0;
    font-size: 22px;
    color: #ffffff;
    font-weight: 700; /* Bolder for emphasis */
    letter-spacing: -0.5px; /* Tighter letter spacing for modern look */
}

.popup-header p {
    margin: 0;
    font-size: 14px;
    color: #cccccc;
    line-height: 1.6; /* Improved line height for readability */
    opacity: 0.9; /* Slightly transparent for a softer look */
}

/* Popup Footer */
.popup-footer {
    margin-top: 20px;
    text-align: left;
    font-size: 14px;
    color: #ffcc00; /* Yellow color for warnings */
    background-color: rgba(255, 204, 0, 0.15); /* Lighter yellow background */
    padding: 12px;
    border-radius: 8px;
    border: 1px solid rgba(255, 204, 0, 0.15); /* Subtle border */
    transition: background-color 0.3s ease, border-color 0.3s ease;
}

.popup-footer:hover {
    background-color: rgba(255, 204, 0, 0.25); /* Slightly brighter on hover */
    border-color: rgba(255, 204, 0, 0.25);
}

.popup-footer p {
    margin: 0;
    line-height: 1.5;
    font-weight: 500; /* Slightly bolder for emphasis */
}

/* Label */
.filter-popup label {
    display: block;
    margin-bottom: 12px;
    font-size: 15px;
    color: #ffffff;
    font-weight: 500;
    text-align: left;
    opacity: 0.9; /* Slightly transparent for a softer look */
    transition: opacity 0.3s ease;
}

.filter-popup label:hover {
    opacity: 1; /* Fully opaque on hover */
}

select:hover, select:focus {
    border-color: #ffffff;
    outline: none;
}


    `;
            // Append the <style> element to the document head
            document.head.appendChild(style);
        }


        // Function to show the message under the "Load More" button
        function showMessage(message) {
            const loadMoreButtonContainer = document.querySelector('.rbx-public-running-games-footer');

            if (!loadMoreButtonContainer) {
                ConsoleLogEnabled("Error: 'Load More' button container not found! Ensure the element exists in the DOM.");
                return;
            }

            // Create the message element
            const messageElement = document.createElement('div');
            messageElement.className = 'filter-message';
            messageElement.textContent = message;

            // Clear any existing message and append the new one
            const existingMessage = loadMoreButtonContainer.querySelector('.filter-message');
            if (existingMessage) {
                ConsoleLogEnabled("Warning: An existing message was found and will be replaced.");
                existingMessage.remove(); // Remove the existing message if it exists
            }

            loadMoreButtonContainer.appendChild(messageElement);

            ConsoleLogEnabled("Message displayed successfully:", message);

            return messageElement;
        }


        // Function to hide the message of the showmessage functioon
        function hideMessage() {
            const messageElement = document.querySelector('.filter-message');
            if (messageElement) messageElement.remove();
        }

        // Function to show the popup for random stuff
        function showPopup() {
            const overlay = document.createElement('div');
            overlay.className = 'overlay';

            const popup = document.createElement('div');
            popup.className = 'filter-popup';
            popup.textContent = 'Uh somethings wrong if you see this message. Please report to the greasyfork issues page!';

            document.body.appendChild(overlay);
            document.body.appendChild(popup);

            return popup;
        }

        // Function to hide the popup for the stuff
        function hidePopup() {
            const popup = document.querySelector('.filter-popup');
            const overlay = document.querySelector('.overlay');

            if (popup) popup.remove();
            if (overlay) overlay.remove();
        }

        // Function to fetch server details so game id and job id. yea!
        async function fetchServerDetails(gameId, jobId) {
            return new Promise((resolve, reject) => {
                GM_xmlhttpRequest({
                    method: "POST",
                    url: "https://gamejoin.roblox.com/v1/join-game-instance", // url for game id
                    headers: { // doesent need cookie cuase of magic
                        "Content-Type": "application/json",
                        "User-Agent": "Roblox/WinInet",
                    },
                    data: JSON.stringify({
                        placeId: gameId,
                        gameId: jobId
                    }),
                    onload: function(response) {
                        const json = JSON.parse(response.responseText);

                        ConsoleLogEnabled("API Response:", json); // This prints the full response

                        // Check if the response indicates that the user needs to purchase the game
                        if (json.status === 12 && json.message === 'You need to purchase access to this game before you can play.') { // yea error message!
                            reject('purchase_required'); // Special error code for this case yea!
                            return;
                        }


                        // Check if the response indicates that the user needs to purchase the game
                        if (json.status === 12 && json.message === 'Cannot join this non-root place due to join restrictions') { // yea error message!
                            reject('subplace_join_restriction'); // Special error code for this case yea!
                            return;
                        }

                        const address = json?.joinScript?.UdmuxEndpoints?.[0]?.Address ?? json?.joinScript?.MachineAddress;

                        if (!address) {
                            ConsoleLogEnabled("API Response (Unknown Location) Which means Full Server!:", json); // Log the API response for debug
                            reject(`Unable to fetch server location: Status ${json.status}`); // debug
                            return;
                        }

                        const location = serverRegionsByIp[address.replace(/^(128\.116\.\d+)\.\d+$/, "$1.0")]; // lmao all servers atart with this so yea dont argue with me

                        if (!location) {
                            ConsoleLogEnabled("API Response (Unknown Location):", json); // Log the API response into the chat. might remove it from production but idc rn
                            reject(`Unknown server address ${address}`);
                            return;
                        }

                        resolve(location);
                    },
                    onerror: function(error) {
                        ConsoleLogEnabled("API Request Failed:", error); // damn if this happpens idk what to tell u
                        reject(`Failed to fetch server details: ${error}`);
                    },
                });
            });
        }

        // cusomt delay also known as sleep fucntion in js cause this language sucks and doesent have a default function
        function delay(ms) {
            return new Promise(resolve => setTimeout(resolve, ms));
        }

        // Function to create a popup for selecting the number of servers
        // basically yea thats what it doesent
        function createServerCountPopup(callback) {
            const overlay = document.createElement('div');
            overlay.className = 'overlay';

            const popup = document.createElement('div');
            popup.className = 'filter-popup'; // reason 100 is selected because thjats how many the api will show per request
            popup.innerHTML = `
<button id="closePopup">X</button>
<div class="popup-header">
    <h3>Select Number of Servers</h3>
    <p>Choose how many servers you want to search. Higher values will provide more location variety but may take longer to process.</p>
<div class="popup-footer">
    <p><strong>Note:</strong> Searching over 100 servers may take longer and could result in rate limiting.</p> <!-- For everyone's sake dont ask me about the &nbsp; chain.-->
</div>
</div>
<label for="serverCount">Select Number of Servers:</label>
<select id="serverCount">
    <option value="10">10 Servers</option>
    <option value="25">25 Servers</option>
    <option value="50">50 Servers</option>
    <option value="100" selected>100 Servers</option>
    <option value="200">200 Servers</option>
    <option value="500">500 Servers</option>
    <option value="1000">1000 Servers</option>
    <option value="custom">Custom</option>
</select>
<input id="customServerCount" type="number" min="1" max="1000" placeholder="Enter a number (1-1000)" style="display: none;">
<button id="confirmServerCount">Confirm</button>
    `;

            document.body.appendChild(overlay);
            document.body.appendChild(popup);

            const serverCountDropdown = popup.querySelector('#serverCount');
            const customServerCountInput = popup.querySelector('#customServerCount');
            const confirmButton = popup.querySelector('#confirmServerCount');
            const closeButton = popup.querySelector('#closePopup');

            // Show/hide custom input based on dropdown selection
            serverCountDropdown.addEventListener('change', () => {
                if (serverCountDropdown.value === 'custom') {
                    customServerCountInput.style.display = 'block';
                } else {
                    customServerCountInput.style.display = 'none';
                }
            });

            // button click on start or what ever
            confirmButton.addEventListener('click', () => {
                let serverCount;

                if (serverCountDropdown.value === 'custom') {
                    serverCount = parseInt(customServerCountInput.value);

                    // Validate custom input
                    if (isNaN(serverCount) || serverCount < 1 || serverCount > 1000) {
                        notifications('Error: Please enter a valid number between 1 and 1000.', 'error', '⚠️', '5000')
                        return;
                    }
                } else {
                    serverCount = parseInt(serverCountDropdown.value);
                }

                // Show an alert if the user selects a number above 100
                if (serverCount > 100) { // error cause people dont know about this maybe. idk yea so here. also if u think this is a stupid way i should have done it before the button press idc so yea
                    notifications('Warning: Searching over 100 servers may take some time and you might get rate limited!', 'warning', '❗', '8000');
                }

                // Pass the selected server count to the callback
                callback(serverCount);
                disableFilterButton(true); // disbale filter button
                disableLoadMoreButton(true); // disable load more button
                hidePopup();
                Loadingbar(true); // enable loading bar
            });

            // Close button logic :))
            closeButton.addEventListener('click', () => {
                hidePopup();
            });

            // Function to hide the popup
            // yea im dumb and used the same function name but it works and im too lazy to change it
            function hidePopup() {
                const overlay = document.querySelector('.overlay');
                const popup = document.querySelector('.filter-popup');

                // Add fade-out classes
                overlay.classList.add('fade-out');
                popup.classList.add('fade-out');

                // Remove elements after animation completes
                setTimeout(() => {
                    overlay.remove();
                    popup.remove();
                }, 300); // Match the duration of the fade-out animation
            }
        }

        // Function to fetch public servers
        // totallimit is amount of sevrers to fetch
        async function fetchPublicServers(gameId, totalLimit) {
            let servers = [];
            let cursor = null;

            while (servers.length < totalLimit) { // too lazy to comment any of this. hopefully i remember what this does in the future
                const url = `https://games.roblox.com/v1/games/${gameId}/servers/public?excludeFullGames=true&limit=100${cursor ? `&cursor=${cursor}` : ''}`;

                const response = await new Promise((resolve, reject) => {
                    GM_xmlhttpRequest({
                        method: "GET",
                        url: url,
                        onload: function(response) {
                            resolve(JSON.parse(response.responseText));
                        },
                        onerror: function(error) {
                            reject(`Failed to fetch public servers: ${error}`);
                        },
                    });
                });

                servers = servers.concat(response.data);

                if (!response.nextPageCursor || servers.length >= totalLimit) {
                    break;
                }

                cursor = response.nextPageCursor;
                await delay(3000); // wait 3 seconds before each page request. if u think this is slow i tried 1 second i got rate limited :|
            }

            return servers.slice(0, totalLimit);
        }

        function createFilterDropdowns(servers) {
            // Create the main filter container
            const filterContainer = document.createElement('div');
            Object.assign(filterContainer.style, {
                display: 'flex',
                gap: '24px',
                alignItems: 'center',
                padding: '28px',
                background: 'linear-gradient(145deg, rgba(25,25,25,0.98) 0%, rgba(15,15,15,0.98) 100%)',
                borderRadius: '20px',
                boxShadow: '0 16px 32px rgba(0,0,0,0.4)',
                backdropFilter: 'blur(20px)',
                opacity: '0',
                transform: 'translateY(-40px) scale(0.95)',
                transition: 'all 0.8s cubic-bezier(0.23, 1, 0.32, 1)',
                position: 'relative',
                border: '1px solid rgba(255,255,255,0.1)',
                margin: '24px',
                fontFamily: "'Inter', sans-serif",
                fontSize: '16px' // Larger font size
            });

            // Add animated border glow with red accents
            const borderGlow = document.createElement('div');
            Object.assign(borderGlow.style, {
                position: 'absolute',
                inset: '0',
                borderRadius: '20px',
                pointerEvents: 'none',
                background: 'linear-gradient(45deg, rgba(255,50,50,0.2), rgba(255,50,50,0.1))',
                zIndex: '-1',
                animation: 'gradientShift 12s ease infinite'
            });
            filterContainer.appendChild(borderGlow);

            // Add dynamic CSS for animations
            const style = document.createElement('style');
            style.textContent = `
        @keyframes gradientShift {
            0% { background-position: 0% 50%; }
            50% { background-position: 100% 50%; }
            100% { background-position: 0% 50%; }
        }
        select::-webkit-scrollbar {
            width: '10px';
        }
        select::-webkit-scrollbar-track {
            background: rgba(30,30,30,0.5);
        }
        select::-webkit-scrollbar-thumb {
            background: rgba(255,50,50,0.4);
            border-radius: '6px';
        }
        select::-webkit-scrollbar-thumb:hover {
            background: rgba(255,50,50,0.6);
        }
    `;
            document.head.appendChild(style);

            // Add logo with hover effects
            const logo = document.createElement('img');
            logo.src = window.Base64Images.logo;
            Object.assign(logo.style, {
                width: '56px',
                height: '56px',
                borderRadius: '14px',
                marginRight: '20px',
                transition: 'transform 0.4s ease, filter 0.4s ease',
                filter: 'drop-shadow(0 6px 12px rgba(255,50,50,0.25))'
            });
            logo.addEventListener('mouseover', () => {
                logo.style.transform = 'rotate(-10deg) scale(1.2)';
                logo.style.filter = 'drop-shadow(0 8px 16px rgba(255,50,50,0.4))';
            });
            logo.addEventListener('mouseout', () => {
                logo.style.transform = 'rotate(0) scale(1)';
                logo.style.filter = 'drop-shadow(0 6px 12px rgba(255,50,50,0.25))';
            });
            filterContainer.appendChild(logo);

            // Function to create a premium dropdown
            const createDropdown = (id, placeholder) => {
                const wrapper = document.createElement('div');
                Object.assign(wrapper.style, {
                    position: 'relative',
                    minWidth: '220px' // Wider dropdown for a modern look
                });

                const dropdown = document.createElement('select');
                dropdown.id = id;
                dropdown.innerHTML = `<option value="">${placeholder}</option>`;
                Object.assign(dropdown.style, {
                    width: '100%',
                    padding: '16px 56px 16px 24px', // More padding for a spacious feel
                    fontSize: '16px', // Larger font size
                    fontWeight: '500',
                    background: 'linear-gradient(145deg, rgba(40,40,40,0.9), rgba(25,25,25,0.9))',
                    color: '#FF1A1A',
                    border: '1px solid rgba(255,255,255,0.15)',
                    borderRadius: '12px',
                    boxShadow: '0 6px 12px rgba(0,0,0,0.2)',
                    appearance: 'none',
                    cursor: 'pointer',
                    transition: 'all 0.4s cubic-bezier(0.4, 0, 0.2, 1)',
                    opacity: '0',
                    transform: 'translateY(-20px)'
                });

                // Custom chevron icon
                const chevron = document.createElement('div');
                chevron.innerHTML = `<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M6 9l6 6 6-6"/></svg>`;
                Object.assign(chevron.style, {
                    position: 'absolute',
                    right: '20px',
                    top: '50%',
                    transform: 'translateY(-50%)',
                    pointerEvents: 'none',
                    transition: 'transform 0.4s ease',
                    color: 'rgba(255,50,50,0.9)' // Red chevron for a premium touch
                });

                // Dropdown interactions
                dropdown.addEventListener('mouseover', () => {
                    dropdown.style.background = 'linear-gradient(145deg, rgba(60,60,60,0.9), rgba(40,40,40,0.9))';
                    dropdown.style.boxShadow = '0 8px 16px rgba(0,0,0,0.3)';
                    chevron.style.transform = 'translateY(-50%) rotate(180deg)';
                });
                dropdown.addEventListener('mouseout', () => {
                    dropdown.style.background = 'linear-gradient(145deg, rgba(40,40,40,0.9), rgba(25,25,25,0.9))';
                    dropdown.style.boxShadow = '0 6px 12px rgba(0,0,0,0.2)';
                    chevron.style.transform = 'translateY(-50%)';
                });
                dropdown.addEventListener('focus', () => {
                    dropdown.style.outline = '2px solid rgba(255,50,50,0.5)';
                    dropdown.style.outlineOffset = '2px';
                });
                dropdown.addEventListener('change', () => {
                    dropdown.style.transform = 'scale(0.98)';
                    setTimeout(() => dropdown.style.transform = 'scale(1)', 150);
                });

                // Fade-in animation
                setTimeout(() => {
                    dropdown.style.opacity = '1';
                    dropdown.style.transform = 'translateY(0)';
                }, 400);

                wrapper.appendChild(dropdown);
                wrapper.appendChild(chevron);
                return wrapper;
            };

            // Create dropdowns
            const countryDropdown = createDropdown('countryFilter', 'All Countries');
            const cityDropdown = createDropdown('cityFilter', 'All Cities');

            // Populate dropdowns with server data
            const countryCounts = {};
            servers.forEach(server => {
                const country = server.location.country.name;
                countryCounts[country] = (countryCounts[country] || 0) + 1;
            });

            Object.keys(countryCounts).forEach(country => {
                const option = document.createElement('option');
                option.value = country;
                option.textContent = `${country} (${countryCounts[country]})`;
                countryDropdown.querySelector('select').appendChild(option);
            });

            countryDropdown.querySelector('select').addEventListener('change', () => {
                const selectedCountry = countryDropdown.querySelector('select').value;
                cityDropdown.querySelector('select').innerHTML = '<option value="">All Cities</option>';

                if (selectedCountry) {
                    const cityCounts = {};
                    servers
                        .filter(server => server.location.country.name === selectedCountry)
                        .forEach(server => {
                            const city = server.location.city;
                            const region = server.location.region?.name;
                            const cityKey = region ? `${city}, ${region}` : city;
                            cityCounts[cityKey] = (cityCounts[cityKey] || 0) + 1;
                        });

                    Object.keys(cityCounts).forEach(city => {
                        const option = document.createElement('option');
                        option.value = city;
                        option.textContent = `${city} (${cityCounts[city]})`;
                        cityDropdown.querySelector('select').appendChild(option);
                    });

                    // Animate city dropdown update
                    cityDropdown.querySelector('select').style.opacity = '0';
                    cityDropdown.querySelector('select').style.transform = 'translateY(-10px)';
                    setTimeout(() => {
                        cityDropdown.querySelector('select').style.opacity = '1';
                        cityDropdown.querySelector('select').style.transform = 'translateY(0)';
                    }, 150);
                }
            });

            // Append dropdowns to container
            filterContainer.appendChild(countryDropdown);
            filterContainer.appendChild(cityDropdown);

            // Fade-in container
            setTimeout(() => {
                filterContainer.style.opacity = '1';
                filterContainer.style.transform = 'translateY(0) scale(1)';
            }, 200);

            return filterContainer;
        }

        // Function to filter servers based on selected country and city cause im lazy
        function filterServers(servers, country, city) {
            return servers.filter(server => {
                const matchesCountry = !country || server.location.country.name === country;
                const matchesCity = !city || `${server.location.city}${server.location.region?.name ? `, ${server.location.region.name}` : ''}` === city;
                return matchesCountry && matchesCity;
            });
        }

        // Function to sort servers by ping. maybe inaccurate but thats roblox's problem not mine
        function sortServersByPing(servers) {
            return servers.sort((a, b) => a.server.ping - b.server.ping);
        }

        async function fetchPlayerThumbnails_servers(playerTokens) {
            const body = playerTokens.map(token => ({
                requestId: `0:${token}:AvatarHeadshot:150x150:png:regular`,
                type: "AvatarHeadShot",
                targetId: 0,
                token,
                format: "png",
                size: "150x150",
            }));

            const response = await fetch("https://thumbnails.roblox.com/v1/batch", {
                method: "POST",
                headers: {
                    "Content-Type": "application/json",
                    Accept: "application/json",
                },
                body: JSON.stringify(body),
            });

            const data = await response.json();
            return data.data || [];
        }

        async function rebuildServerList(gameId, totalLimit, best_connection) {
            const serverListContainer = document.getElementById("rbx-public-game-server-item-container");

            // If "Best Connection" is enabled
            // FUNCTION FOR THE 6TH BUTTON!
            if (best_connection === true) {
                disableLoadMoreButton(true);
                disableFilterButton(true);
                notifications("Retrieving Location...", "success", "🌎", '5000')
                // Ask for the user's location
                const userLocation = await getUserLocation();
                if (!userLocation) {
                    notifications('Error: Unable to fetch your location. Please enable location access.', 'error', '⚠️', '5000');
                    disableFilterButton(false);
                    return;
                }

                // Fetch 50 servers
                const servers = await fetchPublicServers(gameId, 50);
                if (servers.length === 0) {
                    notifications('Error: No servers found. Please try again later.', 'error', '⚠️', '5000');
                    disableFilterButton(false);
                    return;
                }

                // Calculate distances and find the closest server
                let closestServer = null;
                let minDistance = Infinity;
                let closestServerLocation = null;

                for (const server of servers) {
                    const {
                        id: serverId,
                        maxPlayers,
                        playing
                    } = server;

                    // Skip full servers
                    if (playing >= maxPlayers) {
                        continue;
                    }

                    try {
                        // Fetch server location
                        const location = await fetchServerDetails(gameId, serverId);

                        // Calculate distance
                        const distance = calculateDistance(
                            userLocation.latitude,
                            userLocation.longitude,
                            location.latitude,
                            location.longitude
                        );

                        // Update closest server
                        if (distance < minDistance) {
                            minDistance = distance;
                            closestServer = server;
                            closestServerLocation = location;
                        }
                    } catch (error) {
                        ConsoleLogEnabled(`Error fetching details for server ${serverId}:`, error);
                        // Skip this server and continue with the next one
                        continue;
                    }
                }

                if (closestServer) {
                    // Automatically join the closest server
                    showLoadingOverlay();
                    Roblox.GameLauncher.joinGameInstance(gameId, closestServer.id);
                    notifications(`Joining nearest server!
Server ID: ${closestServer.id}
Distance: ${(minDistance / 1.609).toFixed(2)} miles | ${minDistance.toFixed(2)} km
Location (Country): ${closestServerLocation.country.name}.`, 'success', '🚀', '5000');

                    disableFilterButton(false);
                    Loadingbar(false);
                } else {
                    notifications('No valid servers found. Please try again later after refreshing the webpage. Filter button disabled.', 'error', '⚠️', '8000');
                    Loadingbar(false);
                }

                return; // Exit the function after joining the best server
            }

            // Rest of the original function (for non-"Best Connection" mode)
            if (!serverListContainer) {
                ConsoleLogEnabled("Server list container not found!");
                notifications('Error: No Servers found. There is nobody playing this game. Please refresh the page.', 'error', '⚠️', '8000');
                return;
            }

            const messageElement = showMessage("Just a moment, calculating the distance from servers..");

            try {
                // Retrieve user's location for distance calculations
                const userLocation = await getUserLocation();
                if (!userLocation) {
                    notifications('Error: Unable to fetch your location. Please enable location access.', 'error', '⚠️', '5000');
                    disableFilterButton(false);
                    return;
                }

                const servers = await fetchPublicServers(gameId, totalLimit);
                const totalServers = servers.length;
                let skippedServers = 0;

                messageElement.textContent = `Filtering servers, please do not leave this page as it slows down the search...\n${totalServers} servers found, 0 servers loaded.`;
                notifications(`Please do not leave this page as it slows down the search. \nFound a total of ${totalServers} servers.`, 'success', '👍', '8000');

                const serverDetails = [];
                for (let i = 0; i < servers.length; i++) {
                    const server = servers[i];
                    const {
                        id: serverId,
                        maxPlayers,
                        playing,
                        ping,
                        fps,
                        playerTokens
                    } = server;

                    let location;
                    try {
                        location = await fetchServerDetails(gameId, serverId);
                    } catch (error) {
                        if (error === 'purchase_required') {
                            messageElement.textContent = "Error: Cannot access server regions because you have not purchased the game.";
                            notifications('Cannot access server regions because you have not purchased the game.', 'error', '⚠️', '15000');
                            Loadingbar(false); // disable loading bar
                            return;
                        } else if (error === 'subplace_join_restriction') {
                            messageElement.textContent = "This game requires users to teleport to a subplace. As a result, server regions cannot be retrieved.";
                            notifications('Error: This game requires users to teleport to a subplace. As a result, server regions cannot be retrieved.', 'error', '⚠️', '15000');
                            Loadingbar(false); // disable loading bar
                            return;
                        } else {
                            ConsoleLogEnabled(error);
                            location = {
                                city: "Unknown",
                                country: {
                                    name: "Unknown",
                                    code: "??"
                                }
                            };
                        }
                    }


                    if (location.city === "Unknown" || playing >= maxPlayers) {
                        ConsoleLogEnabled(`Skipping server ${serverId} because it is full or location is unknown.`);
                        skippedServers++;
                        continue;
                    }

                    // Fetch player thumbnails
                    const playerThumbnails = playerTokens && playerTokens.length > 0 ? await fetchPlayerThumbnails_servers(playerTokens) : [];

                    serverDetails.push({
                        server,
                        location,
                        playerThumbnails
                    });

                    messageElement.textContent = `Filtering servers, please do not leave this page...\n${totalServers} servers found, ${i + 1} server locations found`;
                }

                if (serverDetails.length === 0) {
                    messageElement.textContent = "No servers found. Please try again with an increase in the number of servers to search for.";
                    notifications('Error: No servers found. Please try again with an increase in the number of servers to search for.', 'error', '⚠️', '5000');
                    Loadingbar(false); // disable loading bar
                    return;
                }

                const loadedServers = totalServers - skippedServers;
                notifications(`Filtering complete!\n${totalServers} servers found, ${loadedServers} servers loaded, ${skippedServers} servers skipped (full).`, 'success', '👍', '5000');
                messageElement.textContent = `Filtering complete!\n${totalServers} servers found, ${loadedServers} servers loaded, ${skippedServers} servers skipped (full).`;
                Loadingbar(false); // disable loading bar

                // Add filter dropdowns
                const filterContainer = createFilterDropdowns(serverDetails);
                serverListContainer.parentNode.insertBefore(filterContainer, serverListContainer);

                // Style the server list container to use a grid layout
                serverListContainer.style.display = "grid";
                serverListContainer.style.gridTemplateColumns = "repeat(4, 1fr)"; // 4 columns
                serverListContainer.style.gap = "16px"; // Gap between cards

                const displayFilteredServers = (country, city) => {
                    serverListContainer.innerHTML = "";

                    const filteredServers = filterServers(serverDetails, country, city);
                    // Sort servers by distance from the user (fastest first)
                    const sortedServers = filteredServers.sort((a, b) => {
                        const distanceA = calculateDistance(userLocation.latitude, userLocation.longitude, a.location.latitude, a.location.longitude);
                        const distanceB = calculateDistance(userLocation.latitude, userLocation.longitude, b.location.latitude, b.location.longitude);
                        return distanceA - distanceB;
                    });

                    sortedServers.forEach(({
                        server,
                        location,
                        playerThumbnails
                    }) => {
                        const serverCard = document.createElement("li");
                        serverCard.className = "rbx-game-server-item col-md-3 col-sm-4 col-xs-6";
                        serverCard.style.width = "100%";
                        serverCard.style.minHeight = "400px";
                        serverCard.style.display = "flex";
                        serverCard.style.flexDirection = "column";
                        serverCard.style.justifyContent = "space-between";
                        serverCard.style.boxSizing = "border-box";
                        serverCard.style.outline = 'none';
                        serverCard.style.padding = '6px';
                        serverCard.style.borderRadius = '8px';

                        // Create label (now based on distance)
                        const pingLabel = document.createElement("div");
                        pingLabel.style.marginBottom = "5px"; // Adds spacing above label
                        pingLabel.style.padding = "5px 10px";
                        pingLabel.style.borderRadius = "8px";
                        pingLabel.style.fontWeight = "bold";
                        pingLabel.style.textAlign = "center"; // Centers the label

                        // Calculate distance from user to server
                        const distance = calculateDistance(
                            userLocation.latitude,
                            userLocation.longitude,
                            location.latitude,
                            location.longitude
                        );

                        // Calculate ping using the advanced formula
                        const calculatedPing = 2 * (distance / 180000) * 1000 * 1.8 + (20 + 0.04 * distance);

                        if (distance < 1250) {
                            pingLabel.textContent = "⚡ Fast";
                            pingLabel.style.backgroundColor = "#014737";
                            pingLabel.style.color = "#73e1bc";
                        } else if (distance < 5000) {
                            pingLabel.textContent = "⏳ OK";
                            pingLabel.style.backgroundColor = "#c75a00";
                            pingLabel.style.color = "#ffe8c2";
                        } else {
                            pingLabel.textContent = "🐌 Slow";
                            pingLabel.style.backgroundColor = "#771d1d";
                            pingLabel.style.color = "#fcc468";
                        }

                        // Create a container for player thumbnails
                        const thumbnailsContainer = document.createElement("div");
                        thumbnailsContainer.className = "player-thumbnails-container";
                        thumbnailsContainer.style.display = "grid";
                        thumbnailsContainer.style.gridTemplateColumns = "repeat(3, 60px)";
                        thumbnailsContainer.style.gridTemplateRows = "repeat(2, 60px)";
                        thumbnailsContainer.style.gap = "5px";
                        thumbnailsContainer.style.marginBottom = "10px";

                        // Add player thumbnails to the container (max 5)
                        const maxThumbnails = 5;
                        const displayedThumbnails = playerThumbnails.slice(0, maxThumbnails);
                        displayedThumbnails.forEach(thumb => {
                            if (thumb && thumb.imageUrl) {
                                const img = document.createElement("img");
                                img.src = thumb.imageUrl;
                                img.className = "avatar-card-image";
                                img.style.width = "60px";
                                img.style.height = "60px";
                                img.style.borderRadius = "50%";
                                thumbnailsContainer.appendChild(img);
                            }
                        });

                        // Add a placeholder for hidden players
                        const hiddenPlayers = server.playing - displayedThumbnails.length;
                        if (hiddenPlayers > 0) {
                            const placeholder = document.createElement("div");
                            placeholder.className = "avatar-card-image";
                            placeholder.style.width = "60px";
                            placeholder.style.height = "60px";
                            placeholder.style.borderRadius = "50%";
                            placeholder.style.backgroundColor = "#6a6f81";
                            placeholder.style.display = "flex";
                            placeholder.style.alignItems = "center";
                            placeholder.style.justifyContent = "center";
                            placeholder.style.color = "#fff";
                            placeholder.style.fontSize = "14px";
                            placeholder.textContent = `+${hiddenPlayers}`;
                            thumbnailsContainer.appendChild(placeholder);
                        }

                        // Server card content with both distance and calculated ping, with line spacers between each info
                        const cardItem = document.createElement("div");
                        cardItem.className = "card-item";
                        cardItem.style.display = "flex";
                        cardItem.style.flexDirection = "column";
                        cardItem.style.justifyContent = "space-between";
                        cardItem.style.height = "100%";

                        cardItem.innerHTML = `
                    ${thumbnailsContainer.outerHTML}
                    <div class="rbx-game-server-details game-server-details">
                        <div class="text-info rbx-game-status rbx-game-server-status text-overflow">
                            ${server.playing} of ${server.maxPlayers} people max
                        </div>
                        <div class="server-player-count-gauge border">
                            <div class="gauge-inner-bar border" style="width: ${(server.playing / server.maxPlayers) * 100}%;"></div>
                        </div>
                        <span data-placeid="${gameId}">
                            <button type="button" class="btn-full-width btn-control-xs rbx-game-server-join game-server-join-btn btn-primary-md btn-min-width">Join</button>
                        </span>
                    </div>
                    <div style="margin-top: 10px; text-align: center;">
                        ${pingLabel.outerHTML}
                        <div class="info-lines" style="margin-top: 8px;">
                            <div class="ping-info">Ping: ${calculatedPing.toFixed(2)} ms</div>
                            <hr style="margin: 6px 0;">
                            <div class="ping-info">Distance: ${distance.toFixed(2)} km</div>
                            <hr style="margin: 6px 0;">
                            <div class="location-info">${location.city}, ${location.country.name}</div>
                            <hr style="margin: 6px 0;">
                            <div class="fps-info">FPS: ${Math.round(server.fps)}</div>
                        </div>
                    </div>
                `;

                        const joinButton = cardItem.querySelector(".rbx-game-server-join");
                        joinButton.addEventListener("click", () => {
                            ConsoleLogEnabled(`Roblox.GameLauncher.joinGameInstance(${gameId}, "${server.id}")`);
                            showLoadingOverlay();
                            Roblox.GameLauncher.joinGameInstance(gameId, server.id);
                        });

                        const container = adjustJoinButtonContainer(joinButton);
                        const inviteButton = createInviteButton(gameId, server.id);
                        container.appendChild(inviteButton);

                        serverCard.appendChild(cardItem);
                        serverListContainer.appendChild(serverCard);
                    });
                };

                // Add event listeners to dropdowns
                const countryFilter = document.getElementById('countryFilter');
                const cityFilter = document.getElementById('cityFilter');

                countryFilter.addEventListener('change', () => {
                    displayFilteredServers(countryFilter.value, cityFilter.value);
                });

                cityFilter.addEventListener('change', () => {
                    displayFilteredServers(countryFilter.value, cityFilter.value);
                });

                // Display all servers initially
                displayFilteredServers("", "");

                setTimeout(() => {
                    hideMessage();
                }, 3000);
            } catch (error) {
                ConsoleLogEnabled("Error rebuilding server list:", error);
                notifications('Filtering error. Try again or refresh to enable the filter button.', 'error', '⚠️ ', '8000');
                messageElement.textContent = "An error occurred while filtering servers. Please try again.";
                Loadingbar(false); // enable loading bar
            } finally {
                Loadingbar(false); // omg bruh i just realzed i could put this here but now im too lazy to thorugh the code to remove all of the loading bar disabl functions
                disableFilterButton(false); // beta test filter button
                //notifications('Note: The filter button is disabled while using server regions. Refresh to enable it.', 'info', '🔄', '15000')
            }
        }




        // Function to extract the game ID from the URL
        function extractGameId() {
            const url = window.location.href;
            const match = url.match(/roblox\.com\/games\/(\d+)/);

            if (match && match[1]) {
                return match[1]; // Return the game ID
            }
            return null; // Return null if no game ID is found
        }

        // Log the game ID to the console
        const gameId = extractGameId();

        // Function to create and append the Invite button
        function createInviteButton(placeId, serverId) { // too lazy to comment this function tbh just ready the name
            const inviteButton = document.createElement('button');
            inviteButton.textContent = 'Invite';
            inviteButton.className = 'btn-control-xs btn-primary-md btn-min-width btn-full-width';
            inviteButton.style.width = '25%';
            inviteButton.style.marginLeft = '5px';

            inviteButton.style.padding = '4px 8px';
            inviteButton.style.fontSize = '12px';
            inviteButton.style.borderRadius = '8px';
            inviteButton.style.backgroundColor = '#3b3e49';
            inviteButton.style.borderColor = '#3b3e49';
            inviteButton.style.color = '#ffffff';
            inviteButton.style.cursor = 'pointer';
            inviteButton.style.fontWeight = '500';
            inviteButton.style.textAlign = 'center';
            inviteButton.style.whiteSpace = 'nowrap';
            inviteButton.style.verticalAlign = 'middle';
            inviteButton.style.lineHeight = '100%';
            inviteButton.style.fontFamily = 'Builder Sans, Helvetica Neue, Helvetica, Arial, Lucida Grande, sans-serif';
            inviteButton.style.textRendering = 'auto';
            inviteButton.style.webkitFontSmoothing = 'antialiased';
            inviteButton.style.mozOsxFontSmoothing = 'grayscale';

            inviteButton.addEventListener('click', () => {
                const inviteLink = `https://oqarshi.github.io/Invite/?placeid=${placeId}&serverid=${serverId}`;
                navigator.clipboard.writeText(inviteLink).then(() => {
                    ConsoleLogEnabled(`Invite link copied to clipboard: ${inviteLink}`);
                    notifications('Success! Invite link copied to clipboard!', 'success', '🎉', ' 2000');
                }).catch(() => {
                    ConsoleLogEnabled('Failed to copy invite link.');
                    notifications('Error: Failed to copy invite link', 'error', '😔', '2000');
                });
            });

            return inviteButton;
        }

        // Function to adjust the Join button and its container
        function adjustJoinButtonContainer(joinButton) {
            const container = document.createElement('div');
            container.style.display = 'flex';
            container.style.width = '100%';

            joinButton.style.width = '75%';

            joinButton.parentNode.insertBefore(container, joinButton);
            container.appendChild(joinButton);

            return container;
        }




        /*********************************************************************************************************************************************************************************************************************************************
                                                                 Functions for the 6th button.

        *********************************************************************************************************************************************************************************************************************************************/




        function calculateDistance(lat1, lon1, lat2, lon2) {
            const R = 6371; // Radius of the Earth in kilometers
            const dLat = (lat2 - lat1) * (Math.PI / 180);
            const dLon = (lon2 - lon1) * (Math.PI / 180);
            const a =
                Math.sin(dLat / 2) * Math.sin(dLat / 2) +
                Math.cos(lat1 * (Math.PI / 180)) * Math.cos(lat2 * (Math.PI / 180)) *
                Math.sin(dLon / 2) * Math.sin(dLon / 2);
            const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
            return R * c; // Distance in kilometers
        }

        function getUserLocation() {
            return new Promise((resolve, reject) => {
                if (!navigator.geolocation) {
                    ConsoleLogEnabled("Geolocation is not supported by this browser.");
                    return fetchFallbackLocation(resolve);
                }

                // Step 1: Try Standard Geolocation
                navigator.geolocation.getCurrentPosition(
                    (position) => resolveSuccess(position, resolve),
                    async (error) => {
                        ConsoleLogEnabled("Geolocation error:", error);

                        // Step 2: Check Permission Status (if supported)
                        if (navigator.permissions) {
                            try {
                                const permissionStatus = await navigator.permissions.query({
                                    name: "geolocation"
                                });
                                ConsoleLogEnabled("Geolocation permission status:", permissionStatus.state);

                                if (permissionStatus.state === "denied") {
                                    ConsoleLogEnabled("User denied location access.");
                                    return fetchFallbackLocation(resolve);
                                }
                            } catch (permError) {
                                ConsoleLogEnabled("Error checking permission status:", permError);
                            }
                        }

                        // Step 3: Try Alternative Geolocation API (If Available)
                        try {
                            navigator.geolocation.getCurrentPosition(
                                (position) => resolveSuccess(position, resolve), // ✅ Corrected to use resolveSuccess
                                () => fetchFallbackLocation(resolve), {
                                    maximumAge: 5000
                                }
                            );
                            return;
                        } catch (altError) {
                            ConsoleLogEnabled("Alternative Geolocation API failed:", altError);
                        }

                        // Step 4: If all else fails, fallback to server
                        fetchFallbackLocation(resolve);
                    }, {
                        timeout: 10000,
                        maximumAge: 0,
                    }
                );
            });
        }

        // 🎯 Success Handler
        function resolveSuccess(position, resolve) {
            notifications("We successfully detected your location.", "success", "🌎", "5000");
            disableLoadMoreButton(true);
            disableFilterButton(true);
            Loadingbar(true);
            resolve({
                latitude: position.coords.latitude,
                longitude: position.coords.longitude,
            });
        }

        // 🌍 Fetches fallback location from a callback server
        function fetchFallbackLocation(resolve) {
            ConsoleLogEnabled("Fetching location from the fallback server...");

            fetch("https://ipapi.co/json/") // Example fallback API
                .then((response) => response.json())
                .then((data) => {
                    ConsoleLogEnabled("Fallback location received:", data);
                    notifications("Using approximate location from IP address.", "info", "📍", "5000");

                    resolve({
                        latitude: data.latitude || 40.7128, // Default to New York if API fails
                        longitude: data.longitude || -74.0060,
                    });
                })
                .catch((error) => {
                    ConsoleLogEnabled("Error fetching fallback location:", error);
                    notifications("Could not determine location. Please report and issue on Greasyfork. Assuming New York.", "error", "⚠️", "15000");

                    resolve({
                        latitude: 40.7128,
                        longitude: -74.0060,
                    });
                });
        }




        /*********************************************************************************************************************************************************************************************************************************************
                                                                 Functions for the 7th button.

        *********************************************************************************************************************************************************************************************************************************************/
        async function auto_join_small_server() {
            // Disable the "Load More" button and show the loading bar
            Loadingbar(true);
            disableFilterButton(true);
            disableLoadMoreButton();

            // Get the game ID from the URL
            const gameId = window.location.pathname.split('/')[2];

            // Retry mechanism for 429 errors
            let retries = 3; // Number of retries
            let success = false;

            while (retries > 0 && !success) {
                try {
                    // Fetch server data using GM_xmlhttpRequest
                    const data = await new Promise((resolve, reject) => {
                        GM_xmlhttpRequest({
                            method: "GET",
                            url: `https://games.roblox.com/v1/games/${gameId}/servers/public?sortOrder=1&excludeFullGames=true&limit=100`,
                            onload: function(response) {
                                if (response.status === 429) {
                                    reject('429: Too Many Requests');
                                } else if (response.status >= 200 && response.status < 300) {
                                    resolve(JSON.parse(response.responseText));
                                } else {
                                    reject(`HTTP error: ${response.status}`);
                                }
                            },
                            onerror: function(error) {
                                reject(error);
                            },
                        });
                    });

                    // Find the server with the lowest player count
                    let minPlayers = Infinity;
                    let targetServer = null;

                    for (const server of data.data) {
                        if (server.playing < minPlayers) {
                            minPlayers = server.playing;
                            targetServer = server;
                        }
                    }

                    if (targetServer) {
                        // Join the server with the lowest player count
                        showLoadingOverlay();
                        Roblox.GameLauncher.joinGameInstance(gameId, targetServer.id);
                        notifications(`Joining a server with ${targetServer.playing} player(s).`, 'success', '🚀');
                        success = true; // Mark as successful
                    } else {
                        notifications('No available servers found.', 'error', '⚠️');
                        break; // Exit the loop if no servers are found
                    }
                } catch (error) {
                    if (error === '429: Too Many Requests' && retries > 0) {
                        ConsoleLogEnabled('Rate limited. Retrying in 10 seconds...');
                        notifications('Rate limited. Retrying in 10 seconds...', 'warning', '⏳', '10000');
                        await delay(10000); // Wait 10 seconds before retrying
                        retries--;
                    } else {
                        ConsoleLogEnabled('Error fetching server data:', error);
                        notifications('Error: Failed to fetch server data. Please try again later.', 'error', '⚠️', '5000');
                        break; // Exit the loop if it's not a 429 error or no retries left
                    }
                }
            }

            // Hide the loading bar and enable the filter button
            Loadingbar(false);
            disableFilterButton(false);
        }
        /*********************************************************************************************************************************************************************************************************************************************
                                                                 Functions for the 8th button.

        *********************************************************************************************************************************************************************************************************************************************/

        function find_user_server_tab() {
            // Create the overlay (backdrop)
            const overlay = document.createElement('div');
            overlay.style.cssText = `
        position: fixed;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        background-color: rgba(0, 0, 0, 0.5);
        z-index: 9999;
        opacity: 0;
        transition: opacity 0.3s ease;
    `;
            document.body.appendChild(overlay);

            // Create the popup container
            const popup = document.createElement('div');
            popup.className = 'player-count-popup';
            popup.style.cssText = `
        position: fixed;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
        background-color: rgb(30, 32, 34);
        padding: 20px;
        border-radius: 10px;
        z-index: 10000;
        box-shadow: 0 0 15px rgba(0, 0, 0, 0.7);
        display: flex;
        flex-direction: column;
        align-items: center;
        gap: 15px;
        width: 300px;
        opacity: 0;
        transition: opacity 0.3s ease, transform 0.3s ease;
    `;

            // Add a close button in the top-right corner (bigger size)
            const closeButton = document.createElement('button');
            closeButton.innerHTML = '&times;'; // Using '×' for the close icon
            closeButton.style.cssText = `
        position: absolute;
        top: 10px;
        right: 10px;
        background: transparent;
        border: none;
        color: #ffffff;
        font-size: 24px; /* Increased font size */
        cursor: pointer;
        width: 36px; /* Increased size */
        height: 36px; /* Increased size */
        border-radius: 50%;
        display: flex;
        align-items: center;
        justify-content: center;
        transition: background-color 0.3s ease, color 0.3s ease;
    `;
            closeButton.addEventListener('mouseenter', () => {
                closeButton.style.backgroundColor = 'rgba(255, 255, 255, 0.1)';
                closeButton.style.color = '#ff4444';
            });
            closeButton.addEventListener('mouseleave', () => {
                closeButton.style.backgroundColor = 'transparent';
                closeButton.style.color = '#ffffff';
            });

            // Add a title
            const title = document.createElement('h3');
            title.textContent = 'Enter Username';
            title.style.cssText = `
        color: white;
        margin: 0;
        font-size: 18px;
        font-weight: 500;
    `;
            popup.appendChild(title);

            // Add an input box for the username
            const usernameInput = document.createElement('input');
            usernameInput.type = 'text';
            usernameInput.placeholder = 'Username, not display';
            usernameInput.style.cssText = `
        width: 80%;
        padding: 8px;
        font-size: 16px;
        border: 1px solid #444;
        border-radius: 5px;
        background-color: #1a1a1a;
        color: white;
        outline: none;
    `;
            popup.appendChild(usernameInput);

            // Add a confirm button with dark, blackish style
            const confirmButton = document.createElement('button');
            confirmButton.textContent = 'Confirm';
            confirmButton.style.cssText = `
        padding: 8px 20px;
        font-size: 16px;
        background-color: #1a1a1a; /* Dark blackish color */
        color: white;
        border: none;
        border-radius: 5px;
        cursor: pointer;
        transition: background-color 0.3s ease, transform 0.2s ease;
    `;
            confirmButton.addEventListener('mouseenter', () => {
                confirmButton.style.backgroundColor = '#333'; /* Slightly lighter on hover */
                confirmButton.style.transform = 'scale(1.05)';
            });
            confirmButton.addEventListener('mouseleave', () => {
                confirmButton.style.backgroundColor = '#1a1a1a';
                confirmButton.style.transform = 'scale(1)';
            });

            // Handle confirm button click
            confirmButton.addEventListener('click', () => {
                const username = usernameInput.value.trim();
                if (username) {
                    // Check if the username is between 3 and 20 characters
                    if (username.length >= 3 && username.length <= 20) {
                        // Call the function with the username
                        FindPlayerGameServer(username);
                        notifications("Searching for the user's server...", "info", "🧐", "5000");
                        fadeOutAndRemove_7th(popup, overlay);
                    } else {
                        // Show an error notification if the username is not within the required length
                        notifications('Error: Username must be between 3 and 20 characters', 'error', '⚠️');
                    }
                } else {
                    notifications('Error: Please enter a username', 'error', '⚠️', '2500');
                }
            });

            // Append the popup to the body
            document.body.appendChild(popup);

            // Fade in the overlay and popup
            setTimeout(() => {
                overlay.style.opacity = '1';
                popup.style.opacity = '1';
                popup.style.transform = 'translate(-50%, -50%) scale(1)';
            }, 10);

            /*******************************************************
                name of function: fadeOutAndRemove_7th
                description: Fades out and removes the popup and overlay.
            *******************************************************/
            function fadeOutAndRemove_7th(popup, overlay) {
                popup.style.opacity = '0';
                popup.style.transform = 'translate(-50%, -50%) scale(0.9)';
                overlay.style.opacity = '0';
                setTimeout(() => {
                    popup.remove();
                    overlay.remove();
                }, 300); // Match the duration of the transition
            }

            // Close the popup when clicking outside
            overlay.addEventListener('click', () => {
                fadeOutAndRemove_7th(popup, overlay);
            });

            // Close the popup when the close button is clicked
            closeButton.addEventListener('click', () => {
                fadeOutAndRemove_7th(popup, overlay);
            });

            popup.appendChild(confirmButton);
            popup.appendChild(closeButton);
        }


        async function FindPlayerGameServer(playerName) {
            disableLoadMoreButton();
            Loadingbar(true);
            disableFilterButton(true);
            const wait = milliseconds => new Promise(resolve => setTimeout(resolve, milliseconds));

            const fetchData = async (url, options = {}) => {
                if (!options.headers) options.headers = {};
                return fetch(url, options)
                    .then(response => response.json())
                    .catch(error => ConsoleLogEnabled("Fetch error:", error));
            };

            const fetchDataGM = (url, options = {}) => {
                return new Promise((resolve, reject) => {
                    GM_xmlhttpRequest({
                        method: options.method || 'GET',
                        url: url,
                        headers: options.headers || {},
                        anonymous: true, // Prevents sending cookies
                        nocache: true, // Prevents caching
                        onload: function(response) {
                            try {
                                const parsedData = JSON.parse(response.responseText);
                                resolve(parsedData);
                            } catch (error) {
                                ConsoleLogEnabled("JSON parsing error:", error);
                                reject(error);
                            }
                        },
                        onerror: function(error) {
                            ConsoleLogEnabled("Request error:", error);
                            reject(error);
                        }
                    });
                });
            };

            ConsoleLogEnabled(`Initiating search for player: ${playerName}`);

            const gameId = window.location.href.split("/")[4];
            ConsoleLogEnabled(`Game ID identified: ${gameId}`);

            let userId;

            try {
                ConsoleLogEnabled(`Retrieving user ID for player: ${playerName}`);
                const userProfile = await fetch(`https://www.roblox.com/users/profile?username=${playerName}`);
                if (!userProfile.ok) {
                    notifications("Error: User does not exist on Roblox!", "error", "⚠️", "2500");
                    Loadingbar(false);
                    disableFilterButton(false);
                    throw `Player "${playerName}" not found`;
                }
                userId = userProfile.url.match(/\d+/)[0];
                ConsoleLogEnabled(`User ID retrieved: ${userId}`);
            } catch (error) {
                ConsoleLogEnabled("Error:", error);
                return `Error: ${error}`;
            }

            ConsoleLogEnabled(`Fetching avatar thumbnail for user ID: ${userId}`);
            const avatarThumbnail = (await fetchData(`https://thumbnails.roblox.com/v1/users/avatar-headshot?userIds=${userId}&format=Png&size=150x150`)).data[0].imageUrl;
            ConsoleLogEnabled(`Avatar thumbnail URL: ${avatarThumbnail}`);

            let pageCursor = null;
            let playerFound = false;
            let totalServersChecked = 0;
            let startTime = Date.now();

            // Show the search progress popup with the player's thumbnail
            const progressPopup = showSearchProgressPopup(avatarThumbnail);

            while (true) {
                let apiUrl = `https://games.roblox.com/v1/games/${gameId}/servers/0?limit=100`;
                if (pageCursor) apiUrl += "&cursor=" + pageCursor;

                ConsoleLogEnabled(`Accessing servers with URL: ${apiUrl}`);
                const serverList = await fetchDataGM(apiUrl, {
                    credentials: "omit"
                }).catch(() => null);

                if (serverList && serverList.data) {
                    ConsoleLogEnabled(`Discovered ${serverList.data.length} servers in this set.`);
                    for (let index = 0; index < serverList.data.length; index++) {
                        const server = serverList.data[index];
                        if (!playerFound) {
                            totalServersChecked++;

                            // Calculate time elapsed
                            const timeElapsed = Math.floor((Date.now() - startTime) / 1000);

                            // Update the progress popup
                            updateSearchProgressPopup(
                                progressPopup,
                                totalServersChecked,
                                timeElapsed
                            );

                            if (server.playerTokens.length === 0) {
                                ConsoleLogEnabled(`Server ${index + 1} is empty. Proceeding to next server.`);
                                continue;
                            }

                            ConsoleLogEnabled(`Inspecting server ${index + 1} hosting ${server.playing} players...`);

                            let thumbnailData;
                            while (true) {
                                let requestBody = [];

                                const generateRequestEntry = (playerToken) => ({
                                    requestId: `0:${playerToken}:AvatarHeadshot:150x150:png:regular`,
                                    type: "AvatarHeadShot",
                                    targetId: 0,
                                    token: playerToken,
                                    format: "png",
                                    size: "150x150"
                                });

                                server.playerTokens.forEach(token => {
                                    requestBody.push(generateRequestEntry(token));
                                });

                                try {
                                    ConsoleLogEnabled(`Fetching thumbnails for ${server.playerTokens.length} player(s)...`);
                                    thumbnailData = await fetchData("https://thumbnails.roblox.com/v1/batch", {
                                        method: "POST",
                                        headers: {
                                            "Content-Type": "application/json",
                                            Accept: "application/json"
                                        },
                                        body: JSON.stringify(requestBody)
                                    });
                                    ConsoleLogEnabled("Thumbnail Data Response:", thumbnailData);
                                    break;
                                } catch (error) {
                                    ConsoleLogEnabled("Thumbnail retrieval error:", error);
                                    await wait(1000);
                                }
                            }

                            if (!thumbnailData.data) {
                                ConsoleLogEnabled("No thumbnail data available. Moving to next server.");
                                continue;
                            }

                            for (let thumbIndex = 0; thumbIndex < thumbnailData.data.length; thumbIndex++) {
                                const thumbnail = thumbnailData.data[thumbIndex];
                                if (thumbnail && thumbnail.imageUrl === avatarThumbnail) {
                                    playerFound = true;
                                    ConsoleLogEnabled(`Player located in server ${index + 1}!`);
                                    notifications("Found User's Server! Joining Server...", "success", "🚀", "5000");
                                    showLoadingOverlay();
                                    Roblox.GameLauncher.joinGameInstance(gameId, server.id);
                                    fadeOutAndRemove_7th_progress(progressPopup.popup, progressPopup.overlay);
                                    Loadingbar(false);
                                    disableFilterButton(false);
                                    return {
                                        gameId,
                                        serverId: server.id,
                                        currentPlayers: server.playing,
                                        maximumPlayers: server.maxPlayers,
                                    };
                                }
                            }
                        } else {
                            break;
                        }
                    }

                    pageCursor = serverList.nextPageCursor;
                    if (!pageCursor || playerFound) break;
                    else {
                        ConsoleLogEnabled("Pausing for 0.5 seconds before next server batch...");
                        await wait(500);
                    }
                } else {
                    ConsoleLogEnabled("Server fetch failed. Retrying in 5 seconds...");
                    notifications("Got rate limited. Waiting 8 seconds...", "info", "❗", "8000")
                    await wait(8000);
                }
            }

            if (!playerFound) {
                // Wait for 2 seconds before calling another function
                setTimeout(() => {
                    fadeOutAndRemove_7th_progress(progressPopup.popup, progressPopup.overlay);
                    notifications("User not found playing this game!", "error", "⚠️", "5000");
                }, 2000); // 2000 milliseconds = 2 seconds

                // Existing logic (unchanged)
                Loadingbar(false);
                disableFilterButton(false);
                ConsoleLogEnabled(`Player not found in the searched servers (${totalServersChecked} servers checked)`);
                // Update the progress popup with the final count
                updateSearchProgressPopup(
                    progressPopup,
                    totalServersChecked,
                    Math.floor((Date.now() - startTime) / 1000),
                    true
                );
                return `Player not found in the searched servers (${totalServersChecked} servers checked)`;
            }
        }

        /*******************************************************
            name of function: showSearchProgressPopup
            description: Creates and displays a popup showing the search progress.
        *******************************************************/
        function showSearchProgressPopup(avatarThumbnail) {
            // Create the overlay (backdrop)
            const overlay = document.createElement('div');
            overlay.style.cssText = `
        position: fixed;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        background-color: rgba(0, 0, 0, 0.5);
        z-index: 9999;
        opacity: 0;
        transition: opacity 0.3s ease;
    `;
            document.body.appendChild(overlay);

            // Create the popup container
            const popup = document.createElement('div');
            popup.className = 'search-progress-popup';
            popup.style.cssText = `
        position: fixed;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
        background-color: rgb(30, 32, 34);
        padding: 20px;
        border-radius: 10px;
        z-index: 10000; /* Higher than overlay */
        box-shadow: 0 0 15px rgba(0, 0, 0, 0.7);
        display: flex;
        flex-direction: column;
        align-items: center;
        gap: 15px;
        width: 300px;
        opacity: 0; /* Start invisible */
        transition: opacity 0.3s ease, transform 0.3s ease;
    `;

            // Add a title
            const title = document.createElement('h3');
            title.textContent = 'Searching for Player...';
            title.style.cssText = `
        color: white;
        margin: 0;
        font-size: 18px;
        font-weight: 500;
    `;
            popup.appendChild(title);

            // Add the player's thumbnail
            const thumbnail = document.createElement('img');
            thumbnail.src = avatarThumbnail;
            thumbnail.style.cssText = `
        width: 100px;
        height: 100px;
        border-radius: 50%;
        object-fit: cover;
    `;
            popup.appendChild(thumbnail);

            // Add a progress text for servers searched
            const serversSearchedText = document.createElement('p');
            serversSearchedText.textContent = 'Servers searched: 0';
            serversSearchedText.style.cssText = `
        color: white;
        margin: 0;
        font-size: 16px;
    `;
            popup.appendChild(serversSearchedText);

            // Add a text for time elapsed
            const timeElapsedText = document.createElement('p');
            timeElapsedText.textContent = 'Time elapsed: 0s';
            timeElapsedText.style.cssText = `
        color: white;
        margin: 0;
        font-size: 16px;
    `;
            popup.appendChild(timeElapsedText);

            // Append the popup to the body
            document.body.appendChild(popup);

            // Fade in the overlay and popup
            setTimeout(() => {
                overlay.style.opacity = '1';
                popup.style.opacity = '1';
                popup.style.transform = 'translate(-50%, -50%) scale(1)';
            }, 10);

            return {
                popup,
                overlay,
                serversSearchedText,
                timeElapsedText,
            };
        }

        /*******************************************************
            name of function: updateSearchProgressPopup
            description: Updates the search progress popup with the current count.
        *******************************************************/
        function updateSearchProgressPopup(
            progressPopup,
            totalServersChecked,
            timeElapsed,
            isFinal = false
        ) {
            progressPopup.serversSearchedText.textContent = `Servers searched: ${totalServersChecked}`;
            progressPopup.timeElapsedText.textContent = `Time elapsed: ${timeElapsed}s`;

            if (isFinal) {
                progressPopup.serversSearchedText.textContent += ' (Search completed)';
            }
        }

        /*******************************************************
            name of function: fadeOutAndRemove
            description: Fades out and removes the popup and overlay.
        *******************************************************/
        function fadeOutAndRemove_7th_progress(popup, overlay) {
            popup.style.opacity = '0';
            popup.style.transform = 'translate(-50%, -50%) scale(0.9)';
            overlay.style.opacity = '0';
            setTimeout(() => {
                popup.remove();
                overlay.remove();
            }, 300); // Match the duration of the transition
        }


        /*********************************************************************************************************************************************************************************************************************************************
                                                                 End of: This is all the functions for the 8 buttons

        *********************************************************************************************************************************************************************************************************************************************/



        /*********************************************************************************************************************************************************************************************************************************************
                                                                 The Universal Functions

        *********************************************************************************************************************************************************************************************************************************************/




        /*******************************************************
        name of function: disableLoadMoreButton
        description: Disables the "Load More" button
        *******************************************************/
        function disableLoadMoreButton() {
            const loadMoreButton = document.querySelector('.rbx-running-games-load-more');
            if (loadMoreButton) {
                loadMoreButton.disabled = true;
                loadMoreButton.style.opacity = '0.5'; // Optional: Make the button look disabled
                loadMoreButton.style.cursor = 'not-allowed'; // Optional: Change cursor to indicate disabled state
                loadMoreButton.title = 'Disabled by Roblox Locator'; // Set tooltip text
            } else {
                ConsoleLogEnabled('Load More button not found!');
                ConsoleLogEnabled('Maybe moved by another extension!');
            }
        }



        /*******************************************************
        name of function: Loadingbar
        description: Shows or hides a loading bar (now using pulsing boxes)
        *******************************************************/
        function Loadingbar(disable) {
            const serverListSection = document.querySelector('#rbx-running-games');
            const serverCardsContainer = document.querySelector('#rbx-public-game-server-item-container');
            const emptyGameInstancesContainer = document.querySelector('.section-content-off.empty-game-instances-container');
            const noServersMessage = emptyGameInstancesContainer?.querySelector('.no-servers-message');

            // Check if serverCardsContainer does not exist
            if (!serverCardsContainer && emptyGameInstancesContainer && noServersMessage?.textContent.includes('Unable to load servers')) {
                notifications('Unable to load servers. Please refresh the page.', 'warning', '⚠️', '5000');
                return;
            }

            if (disable) {
                if (serverCardsContainer) {
                    serverCardsContainer.innerHTML = ''; // Clear contents
                    serverCardsContainer.removeAttribute('style'); // Remove inline styles if present
                }

                // Prevent duplicate loading bars
                if (document.querySelector('#loading-bar')) return;

                // Create and display the loading boxes
                const loadingContainer = document.createElement('div');
                loadingContainer.id = 'loading-bar';
                loadingContainer.style.cssText = `
            display: flex;
            justify-content: center;
            align-items: center;
            gap: 5px;
            margin-top: 10px;
        `;

                const fragment = document.createDocumentFragment();
                for (let i = 0; i < 3; i++) {
                    const box = document.createElement('div');
                    box.style.cssText = `
                width: 10px;
                height: 10px;
                background-color: white;
                margin: 0 5px;
                border-radius: 2px;
                animation: pulse 1.2s ${i * 0.2}s infinite;
            `;
                    fragment.appendChild(box);
                }
                loadingContainer.appendChild(fragment);

                if (serverListSection) {
                    serverListSection.appendChild(loadingContainer);
                }

                // Inject CSS only once
                if (!document.querySelector('#loading-style')) {
                    const styleSheet = document.createElement('style');
                    styleSheet.id = 'loading-style';
                    styleSheet.textContent = `
                @keyframes pulse {
                    0%, 100% { transform: scale(1); }
                    50% { transform: scale(1.5); }
                }
            `;
                    document.head.appendChild(styleSheet);
                }

                // Remove the unwanted gradient div
                document.querySelector('div[style*="background: linear-gradient(145deg"]')?.remove();

            } else {
                // Remove the loading bar
                document.querySelector('#loading-bar')?.remove();
            }
        }




        /*******************************************************
        name of function: fetchPlayerThumbnails
        description: Fetches player thumbnails for up to 5 players. Skips the batch if an error occurs.
        *******************************************************/
        async function fetchPlayerThumbnails(playerTokens) {
            // Limit to the first 5 player tokens
            const limitedTokens = playerTokens.slice(0, 5);

            const body = limitedTokens.map(token => ({
                requestId: `0:${token}:AvatarHeadshot:150x150:png:regular`,
                type: "AvatarHeadShot",
                targetId: 0,
                token,
                format: "png",
                size: "150x150",
            }));

            try {
                const response = await fetch("https://thumbnails.roblox.com/v1/batch", {
                    method: "POST",
                    headers: {
                        "Content-Type": "application/json",
                        Accept: "application/json",
                    },
                    body: JSON.stringify(body),
                });

                // Check if the response is successful
                if (!response.ok) {
                    throw new Error(`HTTP error! Status: ${response.status}`);
                }

                const data = await response.json();
                return data.data || []; // Return the data or an empty array if no data is present
            } catch (error) {
                ConsoleLogEnabled('Error fetching player thumbnails:', error);
                return []; // Return an empty array if an error occurs
            }
        }


        /*******************************************************
        name of function: disableFilterButton
        description: Disables or enables the filter button based on the input.
        *******************************************************/
        function disableFilterButton(disable) {
            const filterButton = document.querySelector('.RL-filter-button');
            const refreshButtons = document.querySelectorAll('.btn-more.rbx-refresh.refresh-link-icon.btn-control-xs.btn-min-width');
            const filterOverlayId = 'filter-button-overlay';
            const refreshOverlayClass = 'refresh-button-overlay';

            if (filterButton) {
                const parent = filterButton.parentElement;

                if (disable) {
                    // Disable the filter button with an overlay
                    filterButton.disabled = true;
                    filterButton.style.opacity = '0.5';
                    filterButton.style.cursor = 'not-allowed';

                    // Create an overlay if it doesn't exist
                    let overlay = document.getElementById(filterOverlayId);
                    if (!overlay) {
                        overlay = document.createElement('div');
                        overlay.id = filterOverlayId;
                        overlay.style.position = 'absolute';
                        overlay.style.top = '-10px';
                        overlay.style.left = '-10px';
                        overlay.style.width = 'calc(100% + 20px)';
                        overlay.style.height = 'calc(100% + 20px)';
                        overlay.style.backgroundColor = 'transparent';
                        overlay.style.zIndex = '9999';
                        overlay.style.pointerEvents = 'all'; // Block clicks
                        parent.style.position = 'relative';
                        parent.appendChild(overlay);
                    }
                } else {
                    // Enable the filter button
                    filterButton.disabled = false;
                    filterButton.style.opacity = '1';
                    filterButton.style.cursor = 'pointer';

                    // Remove the overlay if it exists
                    const overlay = document.getElementById(filterOverlayId);
                    if (overlay) {
                        overlay.remove();
                    }
                }
            } else {
                console.log('Filter button not found!');
            }

            if (refreshButtons.length > 0) {
                refreshButtons.forEach((refreshButton) => {
                    const refreshParent = refreshButton.parentElement;

                    if (disable) {
                        // Create an overlay over the refresh button
                        let refreshOverlay = refreshParent.querySelector(`.${refreshOverlayClass}`);
                        if (!refreshOverlay) {
                            refreshOverlay = document.createElement('div');
                            refreshOverlay.className = refreshOverlayClass;
                            refreshOverlay.style.position = 'absolute';
                            refreshOverlay.style.top = '-10px';
                            refreshOverlay.style.left = '-10px';
                            refreshOverlay.style.width = 'calc(100% + 20px)';
                            refreshOverlay.style.height = 'calc(100% + 20px)';
                            refreshOverlay.style.backgroundColor = 'transparent';
                            refreshOverlay.style.zIndex = '9999';
                            refreshOverlay.style.pointerEvents = 'all'; // Block clicks
                            refreshParent.style.position = 'relative';
                            refreshParent.appendChild(refreshOverlay);
                        }
                    } else {
                        // Remove the overlay if it exists
                        const refreshOverlay = refreshParent.querySelector(`.${refreshOverlayClass}`);
                        if (refreshOverlay) {
                            refreshOverlay.remove();
                        }
                    }
                });
            } else {
                ConsoleLogEnabled('Refresh button not found!');
            }
        }



        async function rbx_card(serverId, playerTokens, maxPlayers, playing, gameId) {
            // Fetch player thumbnails (up to 5)
            const thumbnails = await fetchPlayerThumbnails(playerTokens);

            // Create the server card container
            const cardItem = document.createElement('li');
            cardItem.className = 'rbx-game-server-item col-md-3 col-sm-4 col-xs-6';

            // Create the player thumbnails container
            const playerThumbnailsContainer = document.createElement('div');
            playerThumbnailsContainer.className = 'player-thumbnails-container';

            // Add player thumbnails to the container (up to 5)
            thumbnails.forEach(thumbnail => {
                const playerAvatar = document.createElement('span');
                playerAvatar.className = 'avatar avatar-headshot-md player-avatar';

                const thumbnailImage = document.createElement('span');
                thumbnailImage.className = 'thumbnail-2d-container avatar-card-image';

                const img = document.createElement('img');
                img.src = thumbnail.imageUrl;
                img.alt = '';
                img.title = '';

                thumbnailImage.appendChild(img);
                playerAvatar.appendChild(thumbnailImage);
                playerThumbnailsContainer.appendChild(playerAvatar);
            });

            // Add the 6th placeholder for remaining players
            if (playing > 5) {
                const remainingPlayers = playing - 5;
                const placeholder = document.createElement('span');
                placeholder.className = 'avatar avatar-headshot-md player-avatar hidden-players-placeholder';
                placeholder.textContent = `+${remainingPlayers}`;
                placeholder.style.cssText = `
        background-color: #6a6f81; /* Grayish-blue background */
        color: white;
        display: flex;
        align-items: center;
        justify-content: center;
        border-radius: 50%; /* Fully round */
        font-size: 16px; /* Larger font size */
        width: 60px; /* Larger width */
        height: 60px; /* Larger height */
        `;
                playerThumbnailsContainer.appendChild(placeholder);
            }

            // Create the server details container
            const serverDetails = document.createElement('div');
            serverDetails.className = 'rbx-game-server-details game-server-details';

            // Add server status (e.g., "15 of 15 people max")
            const serverStatus = document.createElement('div');
            serverStatus.className = 'text-info rbx-game-status rbx-game-server-status text-overflow';
            serverStatus.textContent = `${playing} of ${maxPlayers} people max`;
            serverDetails.appendChild(serverStatus);

            // Add the player count gauge
            const gaugeContainer = document.createElement('div');
            gaugeContainer.className = 'server-player-count-gauge border';

            const gaugeInner = document.createElement('div');
            gaugeInner.className = 'gauge-inner-bar border';
            gaugeInner.style.width = `${(playing / maxPlayers) * 100}%`;

            gaugeContainer.appendChild(gaugeInner);
            serverDetails.appendChild(gaugeContainer);

            // Create a container for the buttons
            const buttonContainer = document.createElement('div');
            buttonContainer.className = 'button-container';
            buttonContainer.style.cssText = `
        display: flex;
        gap: 8px; /* Space between buttons */
    `;

            // Add the "Join" button
            const joinButton = document.createElement('button');
            joinButton.type = 'button';
            joinButton.className = 'btn-full-width btn-control-xs rbx-game-server-join game-server-join-btn btn-primary-md btn-min-width';
            joinButton.textContent = 'Join';

            // Add click event to join the server
            joinButton.addEventListener('click', () => {
                showLoadingOverlay();
                Roblox.GameLauncher.joinGameInstance(gameId, serverId);
            });

            buttonContainer.appendChild(joinButton);

            // Add the "Invite" button
            const inviteButton = document.createElement('button');
            inviteButton.type = 'button';
            inviteButton.className = 'btn-full-width btn-control-xs rbx-game-server-invite game-server-invite-btn btn-secondary-md btn-min-width';
            inviteButton.textContent = 'Invite';

            // Add click event to log the invite link
            inviteButton.addEventListener('click', () => {
                const inviteLink = `https://oqarshi.github.io/Invite/?placeid=${gameId}&serverid=${serverId}`;
                //ConsoleLogEnabled('Copied invite link:', inviteLink);
                navigator.clipboard.writeText(inviteLink).then(() => {
                    notifications('Success! Invite link copied to clipboard!', 'success', '🎉', '2000');
                    //ConsoleLogEnabled('Invite link copied to clipboard');
                }).catch(err => {
                    ConsoleLogEnabled('Failed to copy invite link:', err);
                    notifications('Failed! Invite link copied to clipboard!', 'error', '⚠️', '2000');
                });
            });

            buttonContainer.appendChild(inviteButton);

            // Add the button container to the server details
            serverDetails.appendChild(buttonContainer);

            // Assemble the card
            const cardContainer = document.createElement('div');
            cardContainer.className = 'card-item';
            cardContainer.appendChild(playerThumbnailsContainer);
            cardContainer.appendChild(serverDetails);

            cardItem.appendChild(cardContainer);

            // Add the card to the server list
            const serverList = document.querySelector('#rbx-public-game-server-item-container');
            serverList.appendChild(cardItem);
        }

        /*********************************************************************************************************************************************************************************************************************************************
                                                                 End of function for the notification function

        *********************************************************************************************************************************************************************************************************************************************/


        /*********************************************************************************************************************************************************************************************************************************************
                                                                 Launching Function

        *********************************************************************************************************************************************************************************************************************************************/

        function showLoadingOverlay() {
            // Create the content div (no overlay background)
            const content = document.createElement('div');
            content.style.position = 'fixed';
            content.style.top = 'calc(50% - 15px)'; // Move 15px higher
            content.style.left = '50%';
            content.style.transform = 'translate(-50%, -50%)'; // Center the box horizontally
            content.style.width = '400px';
            content.style.height = '250px';
            content.style.backgroundColor = '#1e1e1e'; // Dark background
            content.style.display = 'flex';
            content.style.flexDirection = 'column';
            content.style.justifyContent = 'center';
            content.style.alignItems = 'center';
            content.style.boxShadow = '0 4px 20px rgba(0, 0, 0, 0.5)'; // Subtle shadow
            content.style.borderRadius = '12px'; // Slightly rounded corners
            content.style.zIndex = '1000000'; // z-index set to 1 million
            content.style.opacity = '0'; // Start with 0 opacity for fade-in
            content.style.transition = 'opacity 0.5s ease'; // Fade-in transition
            content.style.fontFamily = 'Arial, sans-serif'; // Clean font

            // Create the loading text
            const loadingText = document.createElement('p');
            loadingText.textContent = 'Joining Roblox Game...';
            loadingText.style.fontSize = '20px';
            loadingText.style.color = '#fff'; // White text for contrast
            loadingText.style.marginTop = '20px'; // Spacing between image and text
            loadingText.style.fontWeight = 'bold'; // Bold text

            // Create the base64 image
            const base64Image = document.createElement('img');
            base64Image.src = window.Base64Images.logo;
            base64Image.style.width = '80px'; // Slightly larger image
            base64Image.style.height = '80px'; // Slightly larger image
            base64Image.style.borderRadius = '8px'; // Rounded corners for the image

            // Create the loading boxes container
            const loadingBoxes = document.createElement('div');
            loadingBoxes.style.display = 'flex';
            loadingBoxes.style.alignItems = 'center';
            loadingBoxes.style.justifyContent = 'center';
            loadingBoxes.style.marginTop = '15px'; // Spacing between text and boxes

            // Create the three loading boxes
            for (let i = 0; i < 3; i++) {
                const box = document.createElement('div');
                box.style.width = '10px';
                box.style.height = '10px';
                box.style.backgroundColor = '#fff'; // White boxes
                box.style.margin = '0 5px'; // Spacing between boxes
                box.style.borderRadius = '2px'; // Slightly rounded corners
                box.style.animation = `pulse 1.2s ${i * 0.2}s infinite`; // Animation with delay
                loadingBoxes.appendChild(box);
            }

            // Define the pulse animation using CSS
            const style = document.createElement('style');
            style.textContent = `
        @keyframes pulse {
            0%, 100% { transform: scale(1); }
            50% { transform: scale(1.5); }
        }
    `;
            document.head.appendChild(style); // Add the animation to the document

            // Append the image, text, and loading boxes to the content div
            content.appendChild(base64Image);
            content.appendChild(loadingText);
            content.appendChild(loadingBoxes);

            // Append the content div to the body
            document.body.appendChild(content);

            // Trigger fade-in animation
            setTimeout(() => {
                content.style.opacity = '1';
            }, 10); // Small delay to trigger the transition

            // Remove the content after 8 seconds with fade-out animation
            setTimeout(() => {
                content.style.opacity = '0'; // Fade out
                setTimeout(() => {
                    document.body.removeChild(content); // Remove after fade-out completes
                }, 500); // Wait for the fade-out transition to finish
            }, 8000); // 8000 milliseconds = 8 seconds
        }


        /*********************************************************************************************************************************************************************************************************************************************
                                                                 End of function for the launching function

        *********************************************************************************************************************************************************************************************************************************************/

        const serverRegionsByIp = {
            "128.116.0.0": { city: "Hong Kong", country: { name: "Hong Kong", code: "HK" }, latitude: 22.3193, longitude: 114.1694 },
            "128.116.1.0": { city: "Los Angeles", country: { name: "United States", code: "US" }, region: { name: "California", code: "CA" }, latitude: 34.0522, longitude: -118.2437 },
            "128.116.2.0": { city: "Warsaw", country: { name: "Poland", code: "PL" }, region: { name: "Mazowieckie", code: "14" }, latitude: 52.2297, longitude: 21.0122 },
            "128.116.3.0": { city: "Warsaw", country: { name: "Poland", code: "PL" }, region: { name: "Mazowieckie", code: "14" }, latitude: 52.2297, longitude: 21.0122 },
            "128.116.4.0": { city: "Paris", country: { name: "France", code: "FR" }, region: { name: "Île-de-France", code: "IDF" }, latitude: 48.8566, longitude: 2.3522 },
            "128.116.5.0": { city: "Frankfurt am Main", country: { name: "Germany", code: "DE" }, region: { name: "Hessen", code: "HE" }, latitude: 50.1109, longitude: 8.6821 },
            "128.116.6.0": { city: "Tokyo", country: { name: "Japan", code: "JP" }, region: { name: "Tokyo", code: "13" }, latitude: 35.6895, longitude: 139.6917 },
            "128.116.7.0": { city: "Mumbai", country: { name: "India", code: "IN" }, region: { name: "Mahārāshtra", code: "MH" }, latitude: 19.0760, longitude: 72.8777 },
            "128.116.8.0": { city: "Frankfurt am Main", country: { name: "Germany", code: "DE" }, region: { name: "Hessen", code: "HE" }, latitude: 50.1109, longitude: 8.6821 },
            "128.116.9.0": { city: "Mumbai", country: { name: "India", code: "IN" }, region: { name: "Mahārāshtra", code: "MH" }, latitude: 19.0760, longitude: 72.8777 },
            "128.116.10.0": { city: "Ashburn", country: { name: "United States", code: "US" }, region: { name: "Virginia", code: "VA" }, latitude: 39.0438, longitude: -77.4874 },
            "128.116.11.0": { city: "Ashburn", country: { name: "United States", code: "US" }, region: { name: "Virginia", code: "VA" }, latitude: 39.0438, longitude: -77.4874 },
            "128.116.12.0": { city: "San Mateo", country: { name: "United States", code: "US" }, region: { name: "California", code: "CA" }, latitude: 37.5630, longitude: -122.3255 },
            "128.116.13.0": { city: "Amsterdam", country: { name: "Netherlands", code: "NL" }, region: { name: "Noord-Holland", code: "NH" }, latitude: 52.3676, longitude: 4.9041 },
            "128.116.14.0": { city: "Hong Kong", country: { name: "Hong Kong", code: "HK" }, latitude: 22.3193, longitude: 114.1694 },
            "128.116.15.0": { city: "Secaucus", country: { name: "United States", code: "US" }, region: { name: "New Jersey", code: "NJ" }, latitude: 40.7895, longitude: -74.0565 },
            "128.116.16.0": { city: "Secaucus", country: { name: "United States", code: "US" }, region: { name: "New Jersey", code: "NJ" }, latitude: 40.7895, longitude: -74.0565 },
            "128.116.17.0": { city: "Secaucus", country: { name: "United States", code: "US" }, region: { name: "New Jersey", code: "NJ" }, latitude: 40.7895, longitude: -74.0565 },
            "128.116.18.0": { city: "Miami", country: { name: "United States", code: "US" }, region: { name: "Florida", code: "FL" }, latitude: 25.7617, longitude: -80.1918 },
            "128.116.19.0": { city: "Paris", country: { name: "France", code: "FR" }, region: { name: "Île-de-France", code: "IDF" }, latitude: 48.8566, longitude: 2.3522 },
            "128.116.20.0": { city: "Paris", country: { name: "France", code: "FR" }, region: { name: "Île-de-France", code: "IDF" }, latitude: 48.8566, longitude: 2.3522 },
            "128.116.21.0": { city: "Amsterdam", country: { name: "Netherlands", code: "NL" }, region: { name: "Noord-Holland", code: "NH" }, latitude: 52.3676, longitude: 4.9041 },
            "128.116.22.0": { city: "Atlanta", country: { name: "United States", code: "US" }, region: { name: "Georgia", code: "GA" }, latitude: 33.7490, longitude: -84.3880 },
            "128.116.23.0": { city: "Secaucus", country: { name: "United States", code: "US" }, region: { name: "New Jersey", code: "NJ" }, latitude: 40.7895, longitude: -74.0565 },
            "128.116.24.0": { city: "Atlanta", country: { name: "United States", code: "US" }, region: { name: "Georgia", code: "GA" }, latitude: 33.7490, longitude: -84.3880 },
            "128.116.25.0": { city: "Atlanta", country: { name: "United States", code: "US" }, region: { name: "Georgia", code: "GA" }, latitude: 33.7490, longitude: -84.3880 },
            "128.116.26.0": { city: "Paris", country: { name: "France", code: "FR" }, region: { name: "Île-de-France", code: "IDF" }, latitude: 48.8566, longitude: 2.3522 },
            "128.116.27.0": { city: "Chicago", country: { name: "United States", code: "US" }, region: { name: "Illinois", code: "IL" }, latitude: 41.8781, longitude: -87.6298 },
            "128.116.28.0": { city: "Chicago", country: { name: "United States", code: "US" }, region: { name: "Illinois", code: "IL" }, latitude: 41.8781, longitude: -87.6298 },
            "128.116.29.0": { city: "Chicago", country: { name: "United States", code: "US" }, region: { name: "Illinois", code: "IL" }, latitude: 41.8781, longitude: -87.6298 },
            "128.116.30.0": { city: "Hong Kong", country: { name: "Hong Kong", code: "HK" }, latitude: 22.3193, longitude: 114.1694 },
            "128.116.31.0": { city: "Warsaw", country: { name: "Poland", code: "PL" }, region: { name: "Mazowieckie", code: "14" }, latitude: 52.2297, longitude: 21.0122 },
            "128.116.32.0": { city: "New York City", country: { name: "United States", code: "US" }, region: { name: "New York", code: "NY" }, latitude: 40.7128, longitude: -74.0060 },
            "128.116.33.0": { city: "London", country: { name: "United Kingdom", code: "GB" }, region: { name: "England", code: "ENG" }, latitude: 51.5072, longitude: 0.1276 },
            "128.116.34.0": { city: "Chicago", country: { name: "United States", code: "US" }, region: { name: "Illinois", code: "IL" }, latitude: 41.8781, longitude: -87.6298 },
            "128.116.35.0": { city: "London", country: { name: "United Kingdom", code: "GB" }, region: { name: "England", code: "ENG" }, latitude: 51.5072, longitude: 0.1276 },
            "128.116.36.0": { city: "London", country: { name: "United Kingdom", code: "GB" }, region: { name: "England", code: "ENG" }, latitude: 51.5072, longitude: 0.1276 },
            "128.116.37.0": { city: "Miami", country: { name: "United States", code: "US" }, region: { name: "Florida", code: "FL" }, latitude: 25.7617, longitude: -80.1918 },
            "128.116.38.0": { city: "Miami", country: { name: "United States", code: "US" }, region: { name: "Florida", code: "FL" }, latitude: 25.7617, longitude: -80.1918 },
            "128.116.39.0": { city: "Frankfurt am Main", country: { name: "Germany", code: "DE" }, region: { name: "Hessen", code: "HE" }, latitude: 50.1109, longitude: 8.6821 },
            "128.116.40.0": { city: "Frankfurt am Main", country: { name: "Germany", code: "DE" }, region: { name: "Hessen", code: "HE" }, latitude: 50.1109, longitude: 8.6821 },
            "128.116.41.0": { city: "Frankfurt am Main", country: { name: "Germany", code: "DE" }, region: { name: "Hessen", code: "HE" }, latitude: 50.1109, longitude: 8.6821 },
            "128.116.42.0": { city: "Frankfurt am Main", country: { name: "Germany", code: "DE" }, region: { name: "Hessen", code: "HE" }, latitude: 50.1109, longitude: 8.6821 },
            "128.116.43.0": { city: "Frankfurt am Main", country: { name: "Germany", code: "DE" }, region: { name: "Hessen", code: "HE" }, latitude: 50.1109, longitude: 8.6821 },
            "128.116.44.0": { city: "Frankfurt am Main", country: { name: "Germany", code: "DE" }, region: { name: "Hessen", code: "HE" }, latitude: 50.1109, longitude: 8.6821 },
            "128.116.45.0": { city: "Miami", country: { name: "United States", code: "US" }, region: { name: "Florida", code: "FL" }, latitude: 25.7617, longitude: -80.1918 },
            "128.116.46.0": { city: "Chicago", country: { name: "United States", code: "US" }, region: { name: "Illinois", code: "IL" }, latitude: 41.8781, longitude: -87.6298 },
            "128.116.47.0": { city: "Chicago", country: { name: "United States", code: "US" }, region: { name: "Illinois", code: "IL" }, latitude: 41.8781, longitude: -87.6298 },
            "128.116.48.0": { city: "Chicago", country: { name: "United States", code: "US" }, region: { name: "Illinois", code: "IL" }, latitude: 41.8781, longitude: -87.6298 },
            "128.116.49.0": { city: "Los Angeles", country: { name: "United States", code: "US" }, region: { name: "California", code: "CA" }, latitude: 34.0522, longitude: -118.2437 },
            "128.116.50.0": { city: "Singapore", country: { name: "Singapore", code: "SG" }, latitude: 1.3521, longitude: 103.8198 },
            "128.116.51.0": { city: "Sydney", country: { name: "Australia", code: "AU" }, region: { name: "New South Wales", code: "NSW" }, latitude: -33.8688, longitude: 151.2093 },
            "128.116.52.0": { city: "Ashburn", country: { name: "United States", code: "US" }, region: { name: "Virginia", code: "VA" }, latitude: 39.0438, longitude: -77.4874 },
            "128.116.53.0": { city: "Ashburn", country: { name: "United States", code: "US" }, region: { name: "Virginia", code: "VA" }, latitude: 39.0438, longitude: -77.4874 },
            "128.116.54.0": { city: "Amsterdam", country: { name: "Netherlands", code: "NL" }, region: { name: "Noord-Holland", code: "NH" }, latitude: 52.3676, longitude: 4.9041 },
            "128.116.55.0": { city: "Tokyo", country: { name: "Japan", code: "JP" }, region: { name: "Tokyo", code: "13" }, latitude: 35.6895, longitude: 139.6917 },
            "128.116.56.0": { city: "Ashburn", country: { name: "United States", code: "US" }, region: { name: "Virginia", code: "VA" }, latitude: 39.0438, longitude: -77.4874 },
            "128.116.57.0": { city: "San Jose", country: { name: "United States", code: "US" }, region: { name: "California", code: "CA" }, latitude: 37.3382, longitude: -121.8863 },
            "128.116.58.0": { city: "Tokyo", country: { name: "Japan", code: "JP" }, region: { name: "Tokyo", code: "13" }, latitude: 35.6895, longitude: 139.6917 },
            "128.116.59.0": { city: "Tokyo", country: { name: "Japan", code: "JP" }, region: { name: "Tokyo", code: "13" }, latitude: 35.6895, longitude: 139.6917 },
            "128.116.60.0": { city: "Tokyo", country: { name: "Japan", code: "JP" }, region: { name: "Tokyo", code: "13" }, latitude: 35.6895, longitude: 139.6917 },
            "128.116.61.0": { city: "San Mateo", country: { name: "United States", code: "US" }, region: { name: "California", code: "CA" }, latitude: 37.5630, longitude: -122.3255 },
            "128.116.62.0": { city: "Seattle", country: { name: "United States", code: "US" }, region: { name: "Washington", code: "WA" }, latitude: 47.6062, longitude: -122.3321 },
            "128.116.63.0": { city: "Los Angeles", country: { name: "United States", code: "US" }, region: { name: "California", code: "CA" }, latitude: 34.0522, longitude: -118.2437 },
            "128.116.64.0": { city: "San Mateo", country: { name: "United States", code: "US" }, region: { name: "California", code: "CA" }, latitude: 37.5630, longitude: -122.3255 },
            "128.116.65.0": { city: "Secaucus", country: { name: "United States", code: "US" }, region: { name: "New Jersey", code: "NJ" }, latitude: 40.7895, longitude: -74.0565 },
            "128.116.66.0": { city: "Secaucus", country: { name: "United States", code: "US" }, region: { name: "New Jersey", code: "NJ" }, latitude: 40.7895, longitude: -74.0565 },
            "128.116.67.0": { city: "San Jose", country: { name: "United States", code: "US" }, region: { name: "California", code: "CA" }, latitude: 37.3382, longitude: -121.8863 },
            "128.116.68.0": { city: "Santa Clara", country: { name: "United States", code: "US" }, region: { name: "California", code: "CA" }, latitude: 37.3541, longitude: -121.9552 },
            "128.116.69.0": { city: "Santa Clara", country: { name: "United States", code: "US" }, region: { name: "California", code: "CA" }, latitude: 37.3541, longitude: -121.9552 },
            "128.116.70.0": { city: "Ashburn", country: { name: "United States", code: "US" }, region: { name: "Virginia", code: "VA" }, latitude: 39.0438, longitude: -77.4874 },
            "128.116.71.0": { city: "Ashburn", country: { name: "United States", code: "US" }, region: { name: "Virginia", code: "VA" }, latitude: 39.0438, longitude: -77.4874 },
            "128.116.72.0": { city: "London", country: { name: "United Kingdom", code: "GB" }, region: { name: "England", code: "ENG" }, latitude: 51.5072, longitude: 0.1276 },
            "128.116.73.0": { city: "London", country: { name: "United Kingdom", code: "GB" }, region: { name: "England", code: "ENG" }, latitude: 51.5072, longitude: 0.1276 },
            "128.116.74.0": { city: "Ashburn", country: { name: "United States", code: "US" }, region: { name: "Virginia", code: "VA" }, latitude: 39.0438, longitude: -77.4874 },
            "128.116.75.0": { city: "Ashburn", country: { name: "United States", code: "US" }, region: { name: "Virginia", code: "VA" }, latitude: 39.0438, longitude: -77.4874 },
            "128.116.76.0": { city: "Ashburn", country: { name: "United States", code: "US" }, region: { name: "Virginia", code: "VA" }, latitude: 39.0438, longitude: -77.4874 },
            "128.116.77.0": { city: "Ashburn", country: { name: "United States", code: "US" }, region: { name: "Virginia", code: "VA" }, latitude: 39.0438, longitude: -77.4874 },
            "128.116.78.0": { city: "Ashburn", country: { name: "United States", code: "US" }, region: { name: "Virginia", code: "VA" }, latitude: 39.0438, longitude: -77.4874 },
            "128.116.79.0": { city: "Singapore", country: { name: "Singapore", code: "SG" }, latitude: 1.3521, longitude: 103.8198 },
            "128.116.80.0": { city: "Ashburn", country: { name: "United States", code: "US" }, region: { name: "Virginia", code: "VA" }, latitude: 39.0438, longitude: -77.4874 },
            "128.116.81.0": { city: "Santa Clara", country: { name: "United States", code: "US" }, region: { name: "California", code: "CA" }, latitude: 37.3541, longitude: -121.9552 },
            "128.116.82.0": { city: "Tokyo", country: { name: "Japan", code: "JP" }, region: { name: "Tokyo", code: "13" }, latitude: 35.6895, longitude: 139.6917 },
            "128.116.83.0": { city: "Tokyo", country: { name: "Japan", code: "JP" }, region: { name: "Tokyo", code: "13" }, latitude: 35.6895, longitude: 139.6917 },
            "128.116.84.0": { city: "Elk Grove Village", country: { name: "United States", code: "US" }, region: { name: "Illinois", code: "IL" }, latitude: 42.0039, longitude: -87.9706 },
            "128.116.85.0": { city: "Miami", country: { name: "United States", code: "US" }, region: { name: "Florida", code: "FL" }, latitude: 25.7617, longitude: -80.1918 },
            "128.116.86.0": { city: "San Mateo", country: { name: "United States", code: "US" }, region: { name: "California", code: "CA" }, latitude: 37.5630, longitude: -122.3255 },
            "128.116.87.0": { city: "Ashburn", country: { name: "United States", code: "US" }, region: { name: "Virginia", code: "VA" }, latitude: 39.0438, longitude: -77.4874 },
            "128.116.88.0": { city: "Elk Grove Village", country: { name: "United States", code: "US" }, region: { name: "Illinois", code: "IL" }, latitude: 42.0039, longitude: -87.9706 },
            "128.116.89.0": { city: "London", country: { name: "United Kingdom", code: "GB" }, region: { name: "England", code: "ENG" }, latitude: 51.5072, longitude: 0.1276 },
            "128.116.90.0": { city: "San Mateo", country: { name: "United States", code: "US" }, region: { name: "California", code: "CA" }, latitude: 37.5630, longitude: -122.3255 },
            "128.116.91.0": { city: "San Mateo", country: { name: "United States", code: "US" }, region: { name: "California", code: "CA" }, latitude: 37.5630, longitude: -122.3255 },
            "128.116.92.0": { city: "San Mateo", country: { name: "United States", code: "US" }, region: { name: "California", code: "CA" }, latitude: 37.5630, longitude: -122.3255 },
            "128.116.93.0": { city: "San Mateo", country: { name: "United States", code: "US" }, region: { name: "California", code: "CA" }, latitude: 37.5630, longitude: -122.3255 },
            "128.116.94.0": { city: "San Mateo", country: { name: "United States", code: "US" }, region: { name: "California", code: "CA" }, latitude: 37.5630, longitude: -122.3255 },
            "128.116.95.0": { city: "Dallas", country: { name: "United States", code: "US" }, region: { name: "Texas", code: "TX" }, latitude: 32.7767, longitude: -96.7970 },
            "128.116.96.0": { city: "Ashburn", country: { name: "United States", code: "US" }, region: { name: "Virginia", code: "VA" }, latitude: 39.0438, longitude: -77.4874 },
            "128.116.97.0": { city: "Singapore", country: { name: "Singapore", code: "SG" }, latitude: 1.3521, longitude: 103.8198 },
            "128.116.98.0": { city: "San Mateo", country: { name: "United States", code: "US" }, region: { name: "California", code: "CA" }, latitude: 37.5630, longitude: -122.3255 },
            "128.116.99.0": { city: "Atlanta", country: { name: "United States", code: "US" }, region: { name: "Georgia", code: "GA" }, latitude: 33.7490, longitude: -84.3880 },
            "128.116.100.0": { city: "San Mateo", country: { name: "United States", code: "US" }, region: { name: "California", code: "CA" }, latitude: 37.5630, longitude: -122.3255 },
            "128.116.101.0": { city: "Chicago", country: { name: "United States", code: "US" }, region: { name: "Illinois", code: "IL" }, latitude: 41.8781, longitude: -87.6298 },
            "128.116.102.0": { city: "Ashburn", country: { name: "United States", code: "US" }, region: { name: "Virginia", code: "VA" }, latitude: 39.0438, longitude: -77.4874 },
            "128.116.103.0": { city: "San Mateo", country: { name: "United States", code: "US" }, region: { name: "California", code: "CA" }, latitude: 37.5630, longitude: -122.3255 },
            "128.116.104.0": { city: "Mumbai", country: { name: "India", code: "IN" }, region: { name: "Mahārāshtra", code: "MH" }, latitude: 19.0760, longitude: 72.8777 },
            "128.116.105.0": { city: "Santa Clara", country: { name: "United States", code: "US" }, region: { name: "California", code: "CA" }, latitude: 37.3541, longitude: -121.9552 },
            "128.116.106.0": { city: "San Mateo", country: { name: "United States", code: "US" }, region: { name: "California", code: "CA" }, latitude: 37.5630, longitude: -122.3255 },
            "128.116.107.0": { city: "San Mateo", country: { name: "United States", code: "US" }, region: { name: "California", code: "CA" }, latitude: 37.5630, longitude: -122.3255 },
            "128.116.108.0": { city: "San Mateo", country: { name: "United States", code: "US" }, region: { name: "California", code: "CA" }, latitude: 37.5630, longitude: -122.3255 },
            "128.116.109.0": { city: "San Mateo", country: { name: "United States", code: "US" }, region: { name: "California", code: "CA" }, latitude: 37.5630, longitude: -122.3255 },
            "128.116.110.0": { city: "San Mateo", country: { name: "United States", code: "US" }, region: { name: "California", code: "CA" }, latitude: 37.5630, longitude: -122.3255 },
            "128.116.111.0": { city: "San Mateo", country: { name: "United States", code: "US" }, region: { name: "California", code: "CA" }, latitude: 37.5630, longitude: -122.3255 },
            "128.116.112.0": { city: "Chicago", country: { name: "United States", code: "US" }, region: { name: "Illinois", code: "IL" }, latitude: 41.8781, longitude: -87.6298 },
            "128.116.113.0": { city: "Chicago", country: { name: "United States", code: "US" }, region: { name: "Illinois", code: "IL" }, latitude: 41.8781, longitude: -87.6298 },
            "128.116.114.0": { city: "Ashburn", country: { name: "United States", code: "US" }, region: { name: "Virginia", code: "VA" }, latitude: 39.0438, longitude: -77.4874 },
            "128.116.115.0": { city: "Seattle", country: { name: "United States", code: "US" }, region: { name: "Washington", code: "WA" }, latitude: 47.6062, longitude: -122.3321 },
            "128.116.116.0": { city: "Los Angeles", country: { name: "United States", code: "US" }, region: { name: "California", code: "CA" }, latitude: 34.0522, longitude: -118.2437 },
            "128.116.117.0": { city: "San Jose", country: { name: "United States", code: "US" }, region: { name: "California", code: "CA" }, latitude: 37.3382, longitude: -121.8863 },
            "128.116.118.0": { city: "Hong Kong", country: { name: "Hong Kong", code: "HK" }, latitude: 22.3193, longitude: 114.1694 },
            "128.116.119.0": { city: "London", country: { name: "United Kingdom", code: "GB" }, region: { name: "England", code: "ENG" }, latitude: 51.5072, longitude: 0.1276 },
            "128.116.120.0": { city: "Tokyo", country: { name: "Japan", code: "JP" }, region: { name: "Tokyo", code: "13" }, latitude: 35.6895, longitude: 139.6917 },
            "128.116.121.0": { city: "Amsterdam", country: { name: "Netherlands", code: "NL" }, region: { name: "Noord-Holland", code: "NH" }, latitude: 52.3676, longitude: 4.9041 },
            "128.116.122.0": { city: "Paris", country: { name: "France", code: "FR" }, region: { name: "Île-de-France", code: "IDF" }, latitude: 48.8566, longitude: 2.3522 },
            "128.116.123.0": { city: "Frankfurt am Main", country: { name: "Germany", code: "DE" }, region: { name: "Hessen", code: "HE" }, latitude: 50.1109, longitude: 8.6821 },
            "128.116.124.0": { city: "Warsaw", country: { name: "Poland", code: "PL" }, region: { name: "Mazowieckie", code: "14" }, latitude: 52.2297, longitude: 21.0122 },
            "128.116.125.0": { city: "San Mateo", country: { name: "United States", code: "US" }, region: { name: "California", code: "CA" }, latitude: 37.5630, longitude: -122.3255 },
            "128.116.126.0": { city: "Secaucus", country: { name: "United States", code: "US" }, region: { name: "New Jersey", code: "NJ" }, latitude: 40.7895, longitude: -74.0565 },
            "128.116.127.0": { city: "Miami", country: { name: "United States", code: "US" }, region: { name: "Florida", code: "FL" }, latitude: 25.7617, longitude: -80.1918 },
        };
        // find_game_id function does nothing lmao but its ere i guees
        function find_game_id() {
            ConsoleLogEnabled('Trying to find game id');
            const gameIdMatch = window.location.pathname.match(/\/games\/(\d+)\//);
            if (!gameIdMatch) {
                ConsoleLogEnabled("Game ID not found in URL!");
                return;
            }

            const gameId = gameIdMatch[1];
        }

        /*******************************************************
        name of function: Initiate the observer
        description: Start observing the document for changes
        *******************************************************/

        // end of the check for the url
    }

    /*******************************************************
    End of code for the random hop button and the filter button on roblox.com/games/*
    *******************************************************/




})();