Drawaria Avatar Copy Players

You need to click on some player profile, download his picture, then drop the picture in the drag and drop part.

// ==UserScript==
// @name         Drawaria Avatar Copy Players
// @namespace    http://tampermonkey.net/
// @version      3.3
// @description  You need to click on some player profile, download his picture, then drop the picture in the drag and drop part.
// @author       YouTubeDrawaria
// @match        https://drawaria.online/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=drawaria.online
// @grant        GM_xmlhttpRequest
// @connect      *
// @license      MIT
// ==/UserScript==

(function() {
    'use-strict';

    // --- 1. INYECTAR LA INTERFAZ DE USUARIO (HTML Y CSS) ---

    // Estilos para el panel flotante y la zona de arrastre.
    const styles = `
        #avatar-switcher-panel {
            position: fixed;
            top: 150px;
            left: 20px;
            z-index: 9999;
            background: #f0f8ff;
            border: 1px solid #b0c4de;
            border-radius: 8px;
            padding: 15px;
            box-shadow: 0 4px 12px rgba(0,0,0,0.2);
            font-family: sans-serif;
            width: 250px;
            cursor: move;
            user-select: none;
        }
        #avatar-drop-zone {
            border: 2px dashed #4682b4;
            border-radius: 5px;
            padding: 20px;
            text-align: center;
            margin-top: 10px;
            color: #4682b4;
            font-weight: bold;
            transition: background-color 0.2s;
        }
        #avatar-drop-zone.hover {
            background-color: #e6f7ff;
            border-style: solid;
        }
        #avatar-upload-button {
            display: block;
            width: 100%;
            padding: 10px;
            margin-top: 10px;
            background-color: #4CAF50;
            color: white;
            border: none;
            border-radius: 5px;
            cursor: pointer;
            text-align: center;
            font-size: 16px;
        }
        #avatar-upload-button:hover {
            background-color: #45a049;
        }
        #avatar-file-input {
            display: none;
        }
        #avatar-status-message {
            margin-top: 10px;
            font-size: 14px;
            text-align: center;
            color: #333;
        }
        #player-name-display-container {
            display: flex;
            align-items: center;
            margin-top: 10px;
        }
        #player-name-field {
            width: calc(100% - 30px);
            padding: 8px;
            border: 1px solid #ccc;
            border-radius: 4px;
            background-color: #eee;
            color: #555;
            font-size: 14px;
        }
        #copy-name-icon {
            cursor: pointer;
            margin-left: 5px;
            color: #555;
            font-size: 18px;
        }
        /* FontAwesome for copy icon - if not loaded by Drawaria, we need to load it */
        @import url('https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css');
    `;

    // Crear el panel y sus elementos.             <label id="avatar-upload-button" for="avatar-file-input">Subir Avatar Descargado</label>
    const panelHTML = `
        <div id="avatar-switcher-panel">
            <h3 style="text-align:center; margin:0 0 10px 0; color:#1e90ff;">Avatar Copy Players</h3>
            <div id="avatar-drop-zone">Arrastra y suelta imagen aquí</div>

            <div id="player-name-display-container">
                <input type="text" id="player-name-field" value="" disabled>
                <i id="copy-name-icon" class="fas fa-copy"></i>
            </div>


            <input type="file" id="avatar-file-input" accept="image/*">
            <div id="avatar-status-message">Haz clic en un avatar para descargarlo.</div>
        </div>
    `;

    // Añadir los estilos y el HTML a la página.
    document.head.insertAdjacentHTML('beforeend', `<style>${styles}</style>`);
    document.body.insertAdjacentHTML('beforeend', panelHTML);

    // --- 2. LÓGICA DE FUNCIONALIDAD ---

    const panel = document.getElementById('avatar-switcher-panel');
    const dropZone = document.getElementById('avatar-drop-zone');
    const fileInput = document.getElementById('avatar-file-input');
    const statusMessage = document.getElementById('avatar-status-message');
    const playerNameDisplayContainer = document.getElementById('player-name-display-container');
    const playerNameField = document.getElementById('player-name-field');
    const copyNameIcon = document.getElementById('copy-name-icon');

    // Ocultar el contenedor del nombre al inicio si no hay nombre guardado
    playerNameDisplayContainer.style.display = 'none';

    /**
     * Copia el texto al portapapeles.
     * @param {string} text El texto a copiar.
     */
    function copyTextToClipboard(text) {
        if (!navigator.clipboard) {
            console.error('La API del portapapeles no está disponible.');
            statusMessage.textContent = 'Tu navegador no soporta copiar.';
            return;
        }
        navigator.clipboard.writeText(text).then(function() {
            statusMessage.textContent = `"${text}" copiado al portapapeles.`;
            console.log('Nombre copiado al portapapeles.');
        }, function(err) {
            console.error('Falló al copiar el nombre:', err);
            statusMessage.textContent = '¡Fallo al copiar el nombre!';
        });
    }

    /**
     * Descarga una imagen desde una URL al ordenador del usuario.
     * @param {string} url La URL de la imagen.
     * @param {string} filename El nombre con el que se guardará el archivo.
     * @param {string} playerName El nombre del jugador para mostrar en el campo del panel.
     */
    function downloadImage(url, filename, playerName) {
        statusMessage.textContent = `Descargando ${filename}...`;
        GM_xmlhttpRequest({
            method: 'GET',
            url: url,
            responseType: 'blob',
            onload: function(response) {
                const urlCreator = window.URL || window.webkitURL;
                const imageUrl = urlCreator.createObjectURL(response.response);
                const a = document.createElement('a');
                a.href = imageUrl;
                a.download = filename;
                document.body.appendChild(a);
                a.click();
                document.body.removeChild(a);
                urlCreator.revokeObjectURL(imageUrl);

                // Actualizar el campo de texto con el nombre y mostrarlo
                playerNameField.value = playerName;
                playerNameDisplayContainer.style.display = 'flex'; // Mostrar el campo de nombre
                localStorage.setItem('lastDownloadedPlayerName', playerName); // Guardar para autocompletar en recarga
                localStorage.setItem('autoPasteNameFlag', 'true'); // Indicar que se debe pegar en recarga

                statusMessage.textContent = `${filename} descargado. Nombre "${playerName}" listo para pegar.`;
            },
            onerror: function() {
                statusMessage.textContent = '¡Fallo en la descarga!';
            }
        });
    }

    /**
     * Sube el archivo de imagen seleccionado al servidor de Drawaria.
     * @param {File} file El archivo de imagen.
     */
    async function handleFileUpload(file) {
        if (!file || !file.type.startsWith('image/')) {
            statusMessage.textContent = 'Por favor, selecciona un archivo de imagen.';
            return;
        }

        statusMessage.textContent = 'Subiendo...';
        const reader = new FileReader();
        reader.onload = async function(e) {
            let base64ImageData = e.target.result;
            // Estandarizar el tipo MIME para máxima compatibilidad
            base64ImageData = base64ImageData.replace(/^data:image\/\w+;/, "data:image/jpeg;");

            const isLoggedIn = typeof window.LOGGEDIN !== 'undefined' && window.LOGGEDIN;
            const uploadUrl = isLoggedIn ? 'https://drawaria.online/saveavatar' : 'https://drawaria.online/uploadavatarimage';

            try {
                const response = await fetch(uploadUrl, {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
                    },
                    body: 'imagedata=' + encodeURIComponent(base64ImageData)
                });

                if (response.ok && response.status === 200) {
                    const responseText = await response.text();
                    if (responseText && responseText.trim()) {
                        statusMessage.textContent = '¡Subida exitosa!';
                        alert('¡Avatar subido con éxito! La página se recargará para ver los cambios.');
                        location.reload(); // Recargar para aplicar el avatar y el nombre
                    } else {
                        throw new Error('El servidor devolvió una respuesta vacía o inválida.');
                    }
                } else {
                    throw new Error(`El servidor respondió con estado: ${response.status}`);
                }
            } catch (error) {
                console.error('Fallo en la subida:', error);
                statusMessage.textContent = '¡Fallo en la subida! Revisa la consola.';
                alert('Fallo en la subida. El servidor pudo haber rechazado la imagen. Revisa la consola (F12) para detalles.');
            }
        };
        reader.readAsDataURL(file);
    }

    // --- 3. LÓGICA DE INTERACCIÓN (CLICS, ARRASTRAR, ETC.) ---

    // Lógica para hacer el panel movible.
    let isDragging = false;
    let offsetX, offsetY;
    panel.addEventListener('mousedown', (e) => {
        // Asegurarse de que no estamos arrastrando elementos interactivos dentro del panel
        if (e.target !== fileInput && e.target !== playerNameField && e.target !== copyNameIcon && e.target !== dropZone && e.target.tagName !== 'LABEL') {
            isDragging = true;
            offsetX = e.clientX - panel.offsetLeft;
            offsetY = e.clientY - panel.offsetTop;
            panel.style.transition = 'none'; // Desactivar transición mientras se arrastra
        }
    });
    document.addEventListener('mouseup', () => {
        isDragging = false;
        panel.style.transition = ''; // Reactivar transición
    });
    document.addEventListener('mousemove', (e) => {
        if (isDragging) {
            panel.style.left = `${e.clientX - offsetX}px`;
            panel.style.top = `${e.clientY - offsetY}px`;
        }
    });

    // Eventos para la zona de arrastrar y soltar.
    dropZone.addEventListener('dragover', (e) => {
        e.preventDefault();
        dropZone.classList.add('hover');
    });
    dropZone.addEventListener('dragleave', () => {
        dropZone.classList.remove('hover');
    });
    dropZone.addEventListener('drop', (e) => {
        e.preventDefault();
        dropZone.classList.remove('hover');
        const file = e.dataTransfer.files[0];
        handleFileUpload(file);
    });

    // Evento para el botón de subida de archivo.
    fileInput.addEventListener('change', (e) => {
        const file = e.target.files[0];
        handleFileUpload(file);
    });

    // Evento para el icono de copiar nombre.
    copyNameIcon.addEventListener('click', () => {
        copyTextToClipboard(playerNameField.value);
    });

    // Listener principal para descargar el avatar y guardar el nombre al hacer clic.
    document.body.addEventListener('click', async function(event) {
        const playerRow = event.target.closest('.playerlist-row');

        if (playerRow) {
            const playerAvatarImg = playerRow.querySelector('.playerlist-avatar');
            const playerNameLink = playerRow.querySelector('.playerlist-name a');

            if (playerAvatarImg && playerNameLink) {
                event.preventDefault(); // Evitar cualquier acción por defecto del clic
                event.stopPropagation();

                const avatarSrc = playerAvatarImg.src;
                const playerName = playerNameLink.textContent.trim();
                const filename = `${playerName.replace(/[^a-z0-9]/gi, '_')}.jpg`;

                // Descargar la imagen y guardar el nombre para autocompletado/visualización
                downloadImage(avatarSrc, filename, playerName);
            }
        }
    });

    // --- 4. LÓGICA DE INICIO (AUTOCOMPLETADO AL CARGAR PÁGINA) ---
    // Se ejecuta al cargar el script (document-idle)
    const lastDownloadedName = localStorage.getItem('lastDownloadedPlayerName');
    const autoPasteFlag = localStorage.getItem('autoPasteNameFlag');

    if (lastDownloadedName && autoPasteFlag === 'true') {
        const selfPlayerNameInput = document.getElementById('playername');
        if (selfPlayerNameInput) {
            selfPlayerNameInput.value = lastDownloadedName;
            selfPlayerNameInput.dispatchEvent(new Event('input', { bubbles: true }));
            statusMessage.textContent = `Nombre "${lastDownloadedName}" establecido automáticamente.`;
            console.log(`Nombre de perfil establecido automáticamente a: ${lastDownloadedName}`);
        } else {
            // Si el campo de nombre no está disponible inmediatamente (ej. en la pantalla de login)
            // lo mostramos en el panel y esperamos la interacción manual.
            playerNameField.value = lastDownloadedName;
            playerNameDisplayContainer.style.display = 'flex';
            statusMessage.textContent = `Nombre "${lastDownloadedName}" listo para pegar.`;
            console.warn('Campo de nombre de perfil (#playername) no encontrado en la carga automática.');
        }
        // Limpiar las banderas después de procesar para evitar re-pegar en futuras recargas no deseadas.
        localStorage.removeItem('lastDownloadedPlayerName');
        localStorage.removeItem('autoPasteNameFlag');
    } else if (lastDownloadedName) {
        // Si hay un nombre guardado pero no la bandera de auto-pegar (ej. recarga manual, o error previo),
        // solo lo mostramos en el panel.
        playerNameField.value = lastDownloadedName;
        playerNameDisplayContainer.style.display = 'flex';
        statusMessage.textContent = `Nombre "${lastDownloadedName}" listo para pegar.`;
    }

})();