您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Menu de acciones draggable para Drawaria.online, usando el CSS proporcionado por el usuario.
// ==UserScript== // @name Drawaria Draggable Action Menu Back! // @namespace http://tampermonkey.net/ // @version 1.0 // @description Menu de acciones draggable para Drawaria.online, usando el CSS proporcionado por el usuario. // @author YouTubeDrawaria // @match https://drawaria.online/* // @icon https://www.google.com/s2/favicons?sz=64&domain=drawaria.online // @grant none // @license MIT // ==/UserScript== (function() { 'use strict'; if (!window.sockets) { window.sockets = []; } const originalSend = WebSocket.prototype.send; WebSocket.prototype.send = function(...args) { if (window.sockets.indexOf(this) === -1) { window.sockets.push(this); // console.log('WebSocket instance captured:', this); } return originalSend.call(this, ...args); }; function sendSocketMessage(messageArray) { if (window.sockets && window.sockets.length > 0) { const gameSocket = window.sockets[0]; const messageString = "42" + JSON.stringify(messageArray); console.log('Sending message:', messageString); gameSocket.send(messageString); } else { console.error('No WebSocket connection found to send message.'); } } // Add Stylesheet - Usando el CSS proporcionado por el usuario function addCustomStylesheet() { const style = document.createElement('style'); // ESTILOS CSS PROPORCIONADOS POR EL USUARIO (con mínimas adiciones necesarias) style.innerHTML = ` .action-menu { /* Nombre de clase del CSS del usuario */ position: absolute; top: 226.969px; /* Del CSS del usuario */ left: 30px; /* Del CSS del usuario */ display: flex; flex-direction: column; align-items: center; /* Del CSS del usuario */ background: linear-gradient(135deg, #8e2de2, #4a00e0); /* Del CSS del usuario */ border-radius: 10px; /* Del CSS del usuario */ padding: 20px; /* Del CSS del usuario */ box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2); /* Del CSS del usuario */ z-index: 10000; /* Manteniendo un z-index alto */ animation: fadeIn 0.5s ease-in-out; /* Del CSS del usuario */ } .action-button { margin: 10px; padding: 15px 20px; cursor: pointer; background: linear-gradient(135deg, #ffd700, #ffb90f); /* Amarillo base */ color: white; border-style: solid; border-width: 2px; /* Grosor del borde para que sea visible */ /* Simulación de borde 3D: claro abajo/izquierda, oscuro arriba/derecha */ border-color: #A07C0F #FFF2D0 #FFF2D0 #A07C0F; /* arriba, derecha, abajo, izquierda */ /* Arriba: oscuro, Derecha: claro, Abajo: claro, Izquierda: oscuro */ /* Ajuste según imagen: Parece más bien un borde claro abajo/izquierda y oscuro arriba/derecha */ /* border-color: #A07C0F #A07C0F #FFF2D0 #FFF2D0; /* arriba, derecha, abajo, izquierda */ /* Mejor aún, como lo describiste: blanco abajo/izquierda, oscuro arriba/derecha */ border-color: #7d600b #7d600b #fff9e6 #fff9e6; /* oscuro arriba y derecha, blanco abajo e izquierda */ /* Probemos esto que se acerca más a tu descripción "borde blanco por abajo y la izquierda y uno oscuro por arriba y la derecha" */ /* Para el color oscuro, usaré un tono más oscuro del amarillo del botón, y para el claro, un amarillo muy pálido o blanco hueso. */ /* Versión final basada en tu descripción: */ border-top-color: #b8860b; /* Oscuro arriba */ border-right-color: #b8860b; /* Oscuro derecha */ border-bottom-color: #ffffff; /* Blanco abajo */ border-left-color: #ffffff; /* Blanco izquierda */ border-radius: 5px; /* box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); */ /* La sombra puede interferir con el efecto de borde, considera quitarla o reducirla */ box-shadow: 1px 1px 3px rgba(0,0,0,0.1); /* Sombra más sutil si se mantiene */ transition: transform 0.2s, box-shadow 0.2s, color 0.2s, border-color 0.2s; font-weight: normal; /* Cambiado a normal basado en tu código, pero la maqueta parecía bold */ text-align: center; min-width: 150px; } .action-button:hover { transform: translateY(-3px); box-shadow: 0 6px 8px rgba(0, 0, 0, 0.2); color: #333333; /* Opcional: Mantener o invertir el efecto de borde en hover */ /* Podrías querer que el borde se aplane o cambie */ border-top-color: #a3750a; /* Un poco más oscuro en hover */ border-right-color: #a3750a; /* Un poco más oscuro en hover */ border-bottom-color: #f0f0f0; /* Un poco menos brillante en hover */ border-left-color: #f0f0f0; /* Un poco menos brillante en hover */ } .draggable { /* Del CSS del usuario */ cursor: move; } @keyframes fadeIn { /* Del CSS del usuario */ from { opacity: 0; transform: translateY(-20px); } to { opacity: 1; transform: translateY(0); } } `; document.head.appendChild(style); } // Crear y añadir el menú de acciones al DOM function createActionMenu() { // Usar los nombres de clase del CSS proporcionado: 'action-menu' y 'draggable' const menu = document.createElement('div'); menu.className = 'action-menu draggable'; // Aplicando clases del CSS del usuario menu.id = 'customActionMenu'; // ID único para el menú const buttons = [ { text: 'Report', action: handleReport }, { text: 'Rules', action: handleRules }, { text: 'AutoKick', action: handleAutoKick } ]; buttons.forEach(btnInfo => { // Usar el nombre de clase del CSS proporcionado: 'action-button' const button = document.createElement('button'); button.className = 'action-button'; // Aplicando clase del CSS del usuario button.textContent = btnInfo.text; button.addEventListener('click', (event) => { event.stopPropagation(); btnInfo.action(); }); menu.appendChild(button); }); document.body.appendChild(menu); makeElementDraggable(menu); // La función draggable sigue siendo la misma } // --- Las funciones handleReport, handleRules, handleAutoKick, makeElementDraggable e init permanecen iguales --- // --- (Copiadas de la respuesta anterior para completitud, sin cambios en su lógica interna) --- function handleReport() { console.log('Report action triggered (automatic, no prompt)'); // Si los reportes se enviaban solos, es posible que: // 1. El objetivo fuera implícito (ej. el jugador actual dibujando). // Para esto, necesitaríamos obtener ese nombre de usuario. // 2. Se enviaba un placeholder o un nombre vacío. // Opción: Enviar el socket con un nombre vacío. // ADVERTENCIA: Si el servidor espera un nombre de usuario específico para la acción de tipo 3 (kick), // enviar un nombre vacío podría no tener ningún efecto o un efecto inesperado. const targetUsernameForAutomaticReport = ""; // Intentar con un nombre vacío sendSocketMessage(['clientnotify', -1, 3, [true, targetUsernameForAutomaticReport]]); // NOTA: Si este enfoque no funciona (es decir, nadie es kickeado o reportado), // significaría que el script original obtenía el nombre del jugador de otra manera // (por ejemplo, el jugador que está dibujando actualmente) o usaba un socket diferente // para un "reporte general" que no tomaba un nombre. // // Si recuerdas que el botón "Report" kickeaba al jugador que estaba dibujando, // necesitaríamos añadir lógica para encontrar el nombre de ese jugador en la página // y usarlo en lugar de "". } function handleRules() { console.log('Rules action triggered'); sendSocketMessage(['clientnotify', -1, 100, [2]]); // alert("Rules message sent to chat."); } function handleAutoKick() { console.log('AutoKick action triggered'); if (window['___BOT'] && typeof window['___BOT'].room.join === 'function') { try { window['___BOT'].room.join(''); } catch (error) { console.error("Error executing ___BOT.room.join: ", error); } } else { console.warn('___BOT object or room.join method not found.'); } } function makeElementDraggable(element) { let offsetX, offsetY, isDragging = false; element.addEventListener('mousedown', (e) => { // Solo iniciar drag si se hace clic directamente en el menú (si tiene clase draggable) // o en este caso, si el target es el propio menú, no los botones. if (e.target === element) { isDragging = true; offsetX = e.clientX - element.getBoundingClientRect().left; offsetY = e.clientY - element.getBoundingClientRect().top; element.style.userSelect = 'none'; } }); document.addEventListener('mousemove', (e) => { if (isDragging) { element.style.left = `${e.clientX - offsetX}px`; element.style.top = `${e.clientY - offsetY}px`; } }); document.addEventListener('mouseup', () => { if (isDragging) { isDragging = false; element.style.userSelect = 'auto'; } }); } function init() { addCustomStylesheet(); setTimeout(createActionMenu, 1500); } if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', init); } else { init(); } })();