Mobile Keyboard Spawner

Adds a draggable button that acts as an input to force the mobile keyboard open.Best for opening cheats on mobile.

θα χρειαστεί να εγκαταστήσετε μια επέκταση όπως το Tampermonkey, το Greasemonkey ή το Violentmonkey για να εγκαταστήσετε αυτόν τον κώδικα.

You will need to install an extension such as Tampermonkey to install this script.

θα χρειαστεί να εγκαταστήσετε μια επέκταση όπως το Tampermonkey ή το Violentmonkey για να εγκαταστήσετε αυτόν τον κώδικα.

θα χρειαστεί να εγκαταστήσετε μια επέκταση όπως το Tampermonkey ή το Userscripts για να εγκαταστήσετε αυτόν τον κώδικα.

You will need to install an extension such as Tampermonkey to install this script.

Θα χρειαστεί να εγκαταστήσετε μια επέκταση διαχείρισης κώδικα χρήστη για να εγκαταστήσετε αυτόν τον κώδικα.

(Έχω ήδη έναν διαχειριστή κώδικα χρήστη, επιτρέψτε μου να τον εγκαταστήσω!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(Έχω ήδη έναν διαχειριστή στυλ χρήστη, επιτρέψτε μου να τον εγκαταστήσω!)

// ==UserScript==
// @name         Mobile Keyboard Spawner
// @namespace    https://greasyfork.org/users/Eternosen
// @version      1.2.1
// @description  Adds a draggable button that acts as an input to force the mobile keyboard open.Best for opening cheats on mobile.
// @author       Eternosen
// @match        *://*/*
// @grant        none
// @license      MIT
// @run-at       document-end
// ==/UserScript==

(function() {
    'use strict';

    // PC PROTECTION: Don't show the button on desktop/laptops
    if (!('ontouchstart' in window) && !navigator.maxTouchPoints) return;

    function createKeyboardTrigger() {
        if (document.getElementById('mobile-kb-container')) return;

        const container = document.createElement('div');
        container.id = 'mobile-kb-container';
        (document.body || document.documentElement).appendChild(container);

        const shadow = container.attachShadow({mode: 'open'});

        const input = document.createElement('input');
        input.type = 'text';
        input.value = '⌨️';
        input.setAttribute('autocomplete', 'off');
        input.setAttribute('spellcheck', 'false');
        input.setAttribute('autocorrect', 'off');
        input.setAttribute('autocapitalize', 'none');
        
        input.style = `
            position: fixed; top: 120px; right: 20px;
            width: 50px; height: 50px;
            background: #222; 
            border: 2px solid #444; border-radius: 50%;
            text-align: center; font-size: 24px;
            z-index: 2147483647; cursor: pointer;
            box-shadow: 0 4px 10px rgba(0,0,0,0.5);
            outline: none; touch-action: none;
            caret-color: transparent; color: transparent;
            text-shadow: 0 0 0 white;
            user-select: none; -webkit-user-select: none;
        `;
        shadow.appendChild(input);

        let isDragging = false, startX, startY, xOffset = 0, yOffset = 0;

        input.addEventListener('touchstart', (e) => {
            // Stop page from reacting to the touch start
            e.stopPropagation();
            const touch = e.touches[0];
            startX = touch.clientX - xOffset;
            startY = touch.clientY - yOffset;
            isDragging = false;
        }, {passive: false});

        input.addEventListener('touchmove', (e) => {
            isDragging = true;
            // THE FIX: Stop the page from scrolling while dragging the button
            if (e.cancelable) e.preventDefault();
            e.stopPropagation();
            
            const touch = e.touches[0];
            xOffset = touch.clientX - startX;
            yOffset = touch.clientY - startY;
            input.style.transform = `translate(${xOffset}px, ${yOffset}px)`;
        }, {passive: false});

        input.addEventListener('touchend', (e) => {
            e.stopPropagation();
            if (isDragging) {
                input.blur();
            } else {
                input.value = '';
                input.focus();
            }
        });

        input.addEventListener('blur', () => { input.value = '⌨️'; });

        // BLOCK messy mobile events from leaking to the site
        ['keydown', 'keyup', 'keypress'].forEach(evtType => {
            input.addEventListener(evtType, (e) => { e.stopPropagation(); });
        });

        input.addEventListener('input', (e) => {
            const char = e.data;
            if (!char) return;
            
            let codeVal = 'Unidentified';
            if (/^[a-zA-Z]$/.test(char)) {
                codeVal = `Key${char.toUpperCase()}`;
            } else if (/^[0-9]$/.test(char)) {
                codeVal = `Digit${char}`;
            }

            const keyCode = char.toUpperCase().charCodeAt(0);
            const isUpper = char === char.toUpperCase() && char !== char.toLowerCase();
            
            const eventParams = {
                key: char,
                code: codeVal,
                keyCode: keyCode,
                which: keyCode,
                shiftKey: isUpper,
                ctrlKey: false, altKey: false, metaKey: false,
                bubbles: true, cancelable: true, composed: true,
                view: window
            };

            const down = new KeyboardEvent('keydown', eventParams);
            const press = new KeyboardEvent('keypress', eventParams);
            const up = new KeyboardEvent('keyup', eventParams);

            const target = document.activeElement && document.activeElement !== input 
                           ? document.activeElement 
                           : document.body;

            target.dispatchEvent(down);
            target.dispatchEvent(press);
            target.dispatchEvent(up);

            window.dispatchEvent(down);
            window.dispatchEvent(press);
            window.dispatchEvent(up);
            
            input.value = ''; 
        });
    }

    createKeyboardTrigger();
    
    const observer = new MutationObserver(() => {
        if (!document.getElementById('mobile-kb-container')) createKeyboardTrigger();
    });
    observer.observe(document.documentElement, { childList: true, subtree: true });
})();