Global Redirect Menu for .io Games

Open a saved URL from any .io site with ` key, set it with # menu

目前為 2025-06-07 提交的版本,檢視 最新版本

// ==UserScript==
// @name         Global Redirect Menu for .io Games
// @namespace    http://tampermonkey.net/
// @version      1.0
// @description  Open a saved URL from any .io site with ` key, set it with # menu
// @author       EccentricCoder
// @match        *://*.io/*
// @grant        none
// @license      MIT
// ==/UserScript==

(function() {
    'use strict';

    // --- Configuration ---
    const STORAGE_KEY = 'global_redirect_url';
    const MENU_ID = 'gm-io-redirect-menu';

    // --- Create and inject menu on load ---
    let menuVisible = false;
    const menu = document.createElement('div');
    menu.id = MENU_ID;
    Object.assign(menu.style, {
        position: 'fixed',
        top: '50%',
        left: '50%',
        transform: 'translate(-50%, -50%)',
        width: '300px',
        height: '150px',
        backgroundColor: 'rgba(0, 0, 0, 0.85)',
        border: '2px solid #fff',
        borderRadius: '8px',
        padding: '16px',
        zIndex: '99999',
        display: 'none',
        boxSizing: 'border-box',
        color: '#fff',
        fontFamily: 'Arial, sans-serif'
    });

    // Input field
    const input = document.createElement('input');
    input.type = 'text';
    input.placeholder = 'Paste URL here...';
    Object.assign(input.style, {
        width: '100%',
        padding: '8px',
        boxSizing: 'border-box',
        marginBottom: '12px',
        borderRadius: '4px',
        border: '1px solid #ccc'
    });

    // Go button
    const goButton = document.createElement('button');
    goButton.textContent = 'GO';
    Object.assign(goButton.style, {
        padding: '8px 16px',
        borderRadius: '4px',
        border: 'none',
        cursor: 'pointer'
    });

    menu.appendChild(input);
    menu.appendChild(goButton);
    document.body.appendChild(menu);

    // --- Helper Functions ---
    function toggleMenu() {
        menuVisible = !menuVisible;
        menu.style.display = menuVisible ? 'block' : 'none';
        if (menuVisible) {
            const saved = localStorage.getItem(STORAGE_KEY) || '';
            input.value = saved;
            input.focus();
        }
    }

    function saveAndClose() {
        let url = input.value.trim();
        if (!url) return;
        if (!/^https?:\/\//i.test(url)) {
            url = 'https://' + url;
        }
        localStorage.setItem(STORAGE_KEY, url);
        toggleMenu();
    }

    function launchSaved() {
        const url = localStorage.getItem(STORAGE_KEY);
        if (url) {
            window.open(url, '_blank');
        } else {
            console.warn('[GM-Redirect] No URL saved. Press # to set one.');
        }
    }

    // --- Event Listeners ---
    document.addEventListener('keydown', (e) => {
        // Shift+3 (#) opens/closes menu
        if (e.key === '#' || (e.shiftKey && e.key === '3')) {
            e.preventDefault();
            toggleMenu();
        }
        // Backtick (`) opens saved URL
        else if (e.key === '`') {
            e.preventDefault();
            launchSaved();
        }
        // Escape closes menu
        else if (e.key === 'Escape' && menuVisible) {
            toggleMenu();
        }
    });

    goButton.addEventListener('click', saveAndClose);

    // Close menu when clicking outside
    document.addEventListener('click', (e) => {
        if (menuVisible && !menu.contains(e.target) && e.target !== goButton) {
            toggleMenu();
        }
    });
})();