您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Pixel companions With player selector and very optimized
// ==UserScript== // @name Drawaria Interactive Pixel Companions // @namespace http://tampermonkey.net/ // @version 3.5 // @description Pixel companions With player selector and very optimized // @author YouTubeDrawaria // @match https://drawaria.online/* // @match https://*.drawaria.online/* // @grant none // @license MIT // @icon https://www.google.com/s2/favicons?sz=64&domain=drawaria.online // ==/UserScript== (function() { 'use strict'; /* ---------- SISTEMA BASE OPTIMIZADO ---------- */ let drawariaSocket = null; let drawariaCanvas = null; let drawariaCtx = null; // Queue optimizado para comandos con batching inteligente const commandQueue = []; let batchProcessor = null; const BATCH_SIZE = 8; const BATCH_INTERVAL = 60; // Variables de control del sistema let systemActive = false; let selectedPlayerId = null; let selectedPlayerName = null; let activeComponents = { hearts: true, sword: true, shield: true }; // Función auxiliar para delays function sleep(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } // Intercept WebSocket optimizado const originalWebSocketSend = WebSocket.prototype.send; WebSocket.prototype.send = function (...args) { if (!drawariaSocket && this.url && this.url.includes('drawaria')) { drawariaSocket = this; console.log('🔗 [PIXEL COMPANIONS] Socket capturado para Pixel Companions'); startBatchProcessor(); } return originalWebSocketSend.apply(this, args); }; function startBatchProcessor() { if (batchProcessor) return; batchProcessor = setInterval(() => { if (!drawariaSocket || drawariaSocket.readyState !== WebSocket.OPEN || commandQueue.length === 0) { return; } const batch = commandQueue.splice(0, BATCH_SIZE); batch.forEach(cmd => { try { drawariaSocket.send(cmd); } catch (e) { console.warn('⚠️ [PIXEL COMPANIONS] Error enviando comando:', e); } }); }, BATCH_INTERVAL); } /* ---------- PATRONES PIXEL ART OPTIMIZADOS ---------- */ const pixelPatterns = { 'heart': [ " RR RR ", "RRRR RRRR", "RRRRRRRRR", " RRRRRRR ", " RRRRR ", " RRR ", " R " ], 'sword': [ " W ", " W ", " W ", " W ", " W ", " W ", " W ", " BBBBB ", " B ", " B " ], 'shield': [ " BBBBB ", " BWWWWWB ", "BWWWWWWB", "BWWWWWWB", "BWWWWWWB", "BWWWWWWB", " BWWWWB ", " BWWB ", " BB " ] }; const specificColorSchemes = { heart: { classic: { 'R': '#FF0000', 'W': '#FFFFFF', 'B': '#000000', ' ': null }, dark: { 'R': '#330000', 'W': '#333333', 'B': '#111111', ' ': null } }, sword: { classic: { 'W': '#00FFFF', 'B': '#0000FF', ' ': null }, dark: { 'W': '#006666', 'B': '#000066', ' ': null } }, shield: { classic: { 'W': '#FFFF00', 'B': '#000000', ' ': null }, dark: { 'W': '#666600', 'B': '#111111', ' ': null } } }; /* ---------- GESTIÓN DE JUGADORES SIMPLIFICADA (COPIADA DEL OTRO SCRIPT) ---------- */ class PlayerManager { constructor() { this.validPlayers = []; this.updateInterval = null; } updatePlayerOptions() { const playerSelect = document.getElementById('player-selector'); if (!playerSelect) return; // Guardar la selección actual antes de limpiar const currentSelection = playerSelect.value; // Clear existing options playerSelect.innerHTML = ''; // Try multiple selectors for better compatibility const playerElements = document.querySelectorAll('.spawnedavatar[data-playerid], .playerlist-row[data-playerid]'); const validPlayers = []; playerElements.forEach(el => { const playerId = el.dataset.playerid; // Skip if no player ID or if it's the current player if (!playerId || playerId === '0' || el.dataset.self === 'true') { return; } // Try different ways to get player name let playerName = ''; // Method 1: Check for nickname in avatar const nicknameEl = el.querySelector('.nickname, .playerlist-name a, .player-name'); if (nicknameEl) { playerName = nicknameEl.textContent.trim(); } // Method 2: Check parent elements if (!playerName) { const parentRow = el.closest('.playerlist-row'); if (parentRow) { const nameEl = parentRow.querySelector('.playerlist-name a, .player-name'); if (nameEl) { playerName = nameEl.textContent.trim(); } } } // Method 3: Use player ID as fallback if (!playerName) { playerName = `Player ${playerId}`; } // Avoid duplicates if (!validPlayers.some(p => p.id === playerId)) { validPlayers.push({ id: playerId, name: playerName }); } }); console.log('🎯 [PIXEL COMPANIONS] Players found:', validPlayers); // Debug log // Actualizar la lista de jugadores válidos this.validPlayers = validPlayers; if (validPlayers.length === 0) { const opt = document.createElement('option'); opt.value = ''; opt.textContent = '❌ No players available'; opt.disabled = true; playerSelect.appendChild(opt); const startBtn = document.getElementById('start-system-btn'); if (startBtn) startBtn.disabled = true; console.log('🎯 [PIXEL COMPANIONS] No hay jugadores disponibles'); } else { // Opción para todos los jugadores const allOpt = document.createElement('option'); allOpt.value = 'all'; allOpt.textContent = `🌍 All Players (${validPlayers.length})`; playerSelect.appendChild(allOpt); // Poblar la lista con los jugadores válidos validPlayers.forEach(player => { const opt = document.createElement('option'); opt.value = player.id; opt.textContent = `🎯 ${player.name}`; opt.dataset.playerName = player.name; // Guardar nombre para referencia playerSelect.appendChild(opt); }); // Intentar mantener la selección anterior const stillExists = currentSelection === 'all' || validPlayers.some(p => p.id === currentSelection); if (currentSelection && stillExists) { // El jugador previamente seleccionado todavía existe, mantener selección playerSelect.value = currentSelection; // Actualizar nombre seleccionado if (currentSelection === 'all') { selectedPlayerName = 'Todos los jugadores'; } else { const selectedPlayer = validPlayers.find(p => p.id === currentSelection); selectedPlayerName = selectedPlayer ? selectedPlayer.name : null; } console.log('🎯 [PIXEL COMPANIONS] Manteniendo selección:', selectedPlayerName); } else if (currentSelection && !stillExists) { // El jugador previamente seleccionado ya no existe console.log('⚠️ [PIXEL COMPANIONS] El jugador seleccionado salió de la sala'); // Seleccionar "All Players" por defecto playerSelect.value = 'all'; selectedPlayerId = 'all'; selectedPlayerName = 'Todos los jugadores'; } else { // Primera vez o sin selección previa playerSelect.value = 'all'; selectedPlayerId = 'all'; selectedPlayerName = 'Todos los jugadores'; } const startBtn = document.getElementById('start-system-btn'); if (startBtn) startBtn.disabled = false; console.log(`🎯 [PIXEL COMPANIONS] Lista actualizada: ${validPlayers.length} jugadores`); console.log('👥 [PIXEL COMPANIONS] Nombres:', validPlayers.map(p => p.name).join(', ')); } // Actualizar variables globales selectedPlayerId = playerSelect.value; } startAutoUpdate() { if (this.updateInterval) return; this.updateInterval = setInterval(() => { this.updatePlayerOptions(); }, 2000); // Actualizar inmediatamente this.updatePlayerOptions(); console.log('🔄 [PIXEL COMPANIONS] Auto-actualización de jugadores iniciada'); } stopAutoUpdate() { if (this.updateInterval) { clearInterval(this.updateInterval); this.updateInterval = null; console.log('⏹️ [PIXEL COMPANIONS] Auto-actualización de jugadores detenida'); } } } /* ---------- SISTEMA DE DIBUJO OPTIMIZADO ---------- */ function enqueueDrawCommand(x1, y1, x2, y2, color, thickness) { if (!drawariaCanvas || !drawariaSocket || !systemActive) return; const normX1 = (x1 / drawariaCanvas.width).toFixed(4); const normY1 = (y1 / drawariaCanvas.height).toFixed(4); const normX2 = (x2 / drawariaCanvas.width).toFixed(4); const normY2 = (y2 / drawariaCanvas.height).toFixed(4); const cmd = `42["drawcmd",0,[${normX1},${normY1},${normX2},${normY2},false,${-Math.abs(thickness)},"${color}",0,0,{}]]`; commandQueue.push(cmd); if (drawariaCtx) { drawariaCtx.strokeStyle = color; drawariaCtx.lineWidth = thickness; drawariaCtx.lineCap = 'round'; drawariaCtx.beginPath(); drawariaCtx.moveTo(x1, y1); drawariaCtx.lineTo(x2, y2); drawariaCtx.stroke(); } } /* ---------- SISTEMA PRINCIPAL MEJORADO ---------- */ class EnhancedPixelCompanionSystem { constructor() { this.initialized = false; this.lives = 3; this.lastPlayerPositions = new Map(); this.playerManager = new PlayerManager(); this.MOVEMENT_THRESHOLD = 4; this.UPDATE_INTERVAL = 80; this.lastUpdateTime = 0; this.COLLISION_COOLDOWN = 3000; this.lastCollisionTime = 0; this.companionStates = new Map(); this.animationState = { damageSequence: false, swordAttack: false, shieldDefend: false }; this.cachedPatterns = this.preOptimizePatterns(); this.init(); } init() { const checkGameReady = () => { const gameCanvas = document.getElementById('canvas'); if (gameCanvas) { this.canvasElement = gameCanvas; drawariaCanvas = gameCanvas; this.canvasContext = gameCanvas.getContext('2d'); drawariaCtx = gameCanvas.getContext('2d'); this.initialized = true; this.createControlInterface(); console.log('✅ [PIXEL COMPANIONS] Sistema inicializado correctamente'); } else { setTimeout(checkGameReady, 100); } }; checkGameReady(); } preOptimizePatterns() { const optimized = {}; Object.keys(pixelPatterns).forEach(patternName => { optimized[patternName] = this.optimizePatternToLines(pixelPatterns[patternName]); }); return optimized; } optimizePatternToLines(pattern) { const lines = []; for (let row = 0; row < pattern.length; row++) { let currentLine = null; for (let col = 0; col < pattern[row].length; col++) { const char = pattern[row][col]; if (char !== ' ') { if (!currentLine || currentLine.char !== char) { if (currentLine) lines.push(currentLine); currentLine = { char, startCol: col, endCol: col, row }; } else { currentLine.endCol = col; } } else { if (currentLine) { lines.push(currentLine); currentLine = null; } } } if (currentLine) lines.push(currentLine); } return lines; } getTargetPlayerCoords(playerId = null) { if (!playerId || playerId === 'all') { const allPlayers = []; const avatars = document.querySelectorAll('.spawnedavatar[data-playerid]:not([data-playerid="0"]):not(.self)'); avatars.forEach(avatar => { if (!this.canvasElement) return; const cRect = this.canvasElement.getBoundingClientRect(); const aRect = avatar.getBoundingClientRect(); if (aRect.width > 0 && aRect.height > 0) { allPlayers.push({ id: avatar.dataset.playerid || `player_${allPlayers.length}`, x: Math.round((aRect.left - cRect.left) + (aRect.width / 2)), y: Math.round((aRect.top - cRect.top) + (aRect.height / 2)), width: aRect.width, height: aRect.height }); } }); return allPlayers.length > 0 ? allPlayers : null; } const targetPlayers = []; const avatars = document.querySelectorAll(`.spawnedavatar[data-playerid="${playerId}"]`); avatars.forEach(avatar => { if (!this.canvasElement) return; const cRect = this.canvasElement.getBoundingClientRect(); const aRect = avatar.getBoundingClientRect(); if (aRect.width > 0 && aRect.height > 0) { targetPlayers.push({ id: playerId, x: Math.round((aRect.left - cRect.left) + (aRect.width / 2)), y: Math.round((aRect.top - cRect.top) + (aRect.height / 2)), width: aRect.width, height: aRect.height }); } }); return targetPlayers.length > 0 ? targetPlayers : null; } detectCollisionWithOtherPlayers() { if (selectedPlayerId === 'all') return false; const myPos = this.getTargetPlayerCoords(selectedPlayerId); if (!myPos || myPos.length === 0) return false; const now = Date.now(); if (now - this.lastCollisionTime < this.COLLISION_COOLDOWN) { return false; } const otherPlayers = document.querySelectorAll('.spawnedavatar.spawnedavatar-otherplayer'); const collisionDistance = 45; for (let otherPlayer of otherPlayers) { if (!this.canvasElement) continue; const cRect = this.canvasElement.getBoundingClientRect(); const otherRect = otherPlayer.getBoundingClientRect(); const otherX = (otherRect.left - cRect.left) + (otherRect.width / 2); const otherY = (otherRect.top - cRect.top) + (otherRect.height / 2); const distance = Math.sqrt( Math.pow(myPos.x - otherX, 2) + Math.pow(myPos.y - otherY, 2) ); if (distance < collisionDistance) { this.lastCollisionTime = now; return true; } } return false; } drawOptimizedPixelArt(patternName, colorScheme, pixelSize, centerX, centerY, rotation = 0, eraseMode = false) { const lines = this.cachedPatterns[patternName]; if (!lines) return; let colors; if (eraseMode) { colors = Object.keys(specificColorSchemes[patternName][colorScheme] || {}) .reduce((acc, key) => { acc[key] = key === ' ' ? null : '#FFFFFF'; return acc; }, {}); } else { colors = specificColorSchemes[patternName] ? specificColorSchemes[patternName][colorScheme] : specificColorSchemes.heart[colorScheme]; } const patternCenter = Math.floor(pixelPatterns[patternName].length / 2); lines.forEach(line => { if (!colors[line.char]) return; const startX = centerX + (line.startCol - patternCenter) * pixelSize; const endX = centerX + (line.endCol - patternCenter) * pixelSize + pixelSize; const y = centerY + (line.row - patternCenter) * pixelSize; enqueueDrawCommand(startX, y, endX, y, colors[line.char], pixelSize * 1.2); }); } async executeDamageSequence() { if (this.animationState.damageSequence || this.lives <= 0) return; this.animationState.damageSequence = true; console.log(`💔 [PIXEL COMPANIONS] ¡Daño recibido! Vidas restantes: ${this.lives - 1}`); const heartsToDeactivate = [2, 1, 0]; for (let i = 0; i < Math.min(heartsToDeactivate.length, this.lives); i++) { const heartIndex = heartsToDeactivate[i]; if (this.companions && this.companions.hearts[heartIndex]) { this.companions.hearts[heartIndex].active = false; this.companions.hearts[heartIndex].needsRedraw = true; } await new Promise(r => setTimeout(r, 800)); if (i >= this.lives - 1) break; } this.lives--; if (this.lives <= 0) { console.log('💀 [PIXEL COMPANIONS] ¡Sin vidas! Reiniciando sistema...'); await new Promise(r => setTimeout(r, 2000)); this.lives = 3; if (this.companions) { this.companions.hearts.forEach(heart => { heart.active = true; heart.needsRedraw = true; }); } console.log('🔄 [PIXEL COMPANIONS] Sistema reiniciado con 3 vidas'); } else { await new Promise(r => setTimeout(r, 500)); if (this.companions) { this.companions.hearts.forEach(heart => { heart.active = true; heart.needsRedraw = true; }); } } this.animationState.damageSequence = false; } async executeSwordAttack() { if (this.animationState.swordAttack) return; this.animationState.swordAttack = true; console.log('⚔️ [PIXEL COMPANIONS] ¡Ejecutando ataque con espada!'); await new Promise(r => setTimeout(r, 600)); if (this.companions && this.companions.sword) { this.companions.sword.rotation = Math.PI / 3; this.companions.sword.needsRedraw = true; } await new Promise(r => setTimeout(r, 500)); if (this.companions && this.companions.sword) { this.companions.sword.rotation = 0; this.companions.sword.needsRedraw = true; } await new Promise(r => setTimeout(r, 500)); this.animationState.swordAttack = false; console.log('⚔️ [PIXEL COMPANIONS] Ataque con espada completado'); } async executeShieldDefense() { if (this.animationState.shieldDefend) return; this.animationState.shieldDefend = true; console.log('🛡️ [PIXEL COMPANIONS] ¡Activando defensa con escudo!'); await new Promise(r => setTimeout(r, 400)); if (this.companions && this.companions.shield) { this.companions.shield.defending = true; this.companions.shield.needsRedraw = true; } await new Promise(r => setTimeout(r, 800)); if (this.companions && this.companions.shield) { this.companions.shield.defending = false; this.companions.shield.needsRedraw = true; } this.animationState.shieldDefend = false; console.log('🛡️ [PIXEL COMPANIONS] Defensa con escudo completada'); } // NEW: Clean Canvas functionality async cleanCanvas() { if (!drawariaCanvas) return; console.log('🧹 [PIXEL COMPANIONS] Limpiando canvas...'); // Draw a giant white rectangle over entire canvas const canvasWidth = drawariaCanvas.width; const canvasHeight = drawariaCanvas.height; // Send multiple white rectangles to ensure complete coverage for (let y = 0; y < canvasHeight; y += 100) { for (let x = 0; x < canvasWidth; x += 100) { const width = Math.min(100, canvasWidth - x); const height = Math.min(100, canvasHeight - y); enqueueDrawCommand(x, y, x + width, y + height, '#FFFFFF', Math.max(width, height)); await sleep(5); // Menor delay para una limpieza más rápida } } // Clear local canvas if (drawariaCtx) { drawariaCtx.clearRect(0, 0, canvasWidth, canvasHeight); } console.log('🧹 [PIXEL COMPANIONS] Canvas limpiado completamente!'); } updateCompanions() { if (!systemActive || !this.initialized) return; const now = Date.now(); if (now - this.lastUpdateTime < this.UPDATE_INTERVAL) return; const targetPlayers = this.getTargetPlayerCoords(selectedPlayerId); if (!targetPlayers) return; if (selectedPlayerId !== 'all') { const collision = this.detectCollisionWithOtherPlayers(); if (collision && !this.animationState.damageSequence) { this.executeDamageSequence(); this.executeSwordAttack(); this.executeShieldDefense(); } } targetPlayers.forEach(player => { this.updateCompanionForPlayer(player); }); this.lastUpdateTime = now; } updateCompanionForPlayer(player) { const playerId = player.id; if (!this.companionStates.has(playerId)) { this.companionStates.set(playerId, { hearts: Array(3).fill().map(() => ({ active: true, lastX: -9999, lastY: -9999, needsRedraw: true })), sword: { rotation: 0, lastX: -9999, lastY: -9999, needsRedraw: true }, shield: { rotation: 0, lastX: -9999, lastY: -9999, needsRedraw: true } }); } const state = this.companionStates.get(playerId); const lastPos = this.lastPlayerPositions.get(playerId) || { x: 0, y: 0 }; const deltaX = Math.abs(player.x - lastPos.x); const deltaY = Math.abs(player.y - lastPos.y); const significantMovement = deltaX > this.MOVEMENT_THRESHOLD || deltaY > this.MOVEMENT_THRESHOLD; if (activeComponents.hearts) { for (let i = 0; i < 3; i++) { const heartX = player.x + (i - 1) * 32; const heartY = player.y - player.height / 2 - 25; if (significantMovement || state.hearts[i].needsRedraw) { if (state.hearts[i].lastX !== -9999) { this.drawOptimizedPixelArt('heart', 'classic', 3, state.hearts[i].lastX, state.hearts[i].lastY, 0, true); } const scheme = state.hearts[i].active ? 'classic' : 'dark'; this.drawOptimizedPixelArt('heart', scheme, 3, heartX, heartY, 0, false); state.hearts[i].lastX = heartX; state.hearts[i].lastY = heartY; state.hearts[i].needsRedraw = false; } } } if (activeComponents.sword) { const swordX = player.x + player.width / 2 + 30; const swordY = player.y; if (significantMovement || state.sword.needsRedraw) { if (state.sword.lastX !== -9999) { this.drawOptimizedPixelArt('sword', 'classic', 5, state.sword.lastX, state.sword.lastY, 0, true); } this.drawOptimizedPixelArt('sword', 'classic', 5, swordX, swordY, state.sword.rotation, false); state.sword.lastX = swordX; state.sword.lastY = swordY; state.sword.needsRedraw = false; } } if (activeComponents.shield) { const shieldX = player.x - player.width / 2 - 30; const shieldY = player.y; if (significantMovement || state.shield.needsRedraw) { if (state.shield.lastX !== -9999) { this.drawOptimizedPixelArt('shield', 'classic', 5, state.shield.lastX, state.shield.lastY, 0, true); } this.drawOptimizedPixelArt('shield', 'classic', 5, shieldX, shieldY, 0, false); state.shield.lastX = shieldX; state.shield.lastY = shieldY; state.shield.needsRedraw = false; } } if (significantMovement) { this.lastPlayerPositions.set(playerId, { x: player.x, y: player.y }); } } startSystem() { if (!this.initialized) { console.log('❌ [PIXEL COMPANIONS] Sistema no inicializado. Esperando canvas...'); return; } if (!selectedPlayerId) { console.log('❌ [PIXEL COMPANIONS] No hay jugador seleccionado'); return; } systemActive = true; this.playerManager.startAutoUpdate(); this.companions = { hearts: Array(3).fill().map(() => ({ active: true, lastX: -9999, lastY: -9999, needsRedraw: true })), sword: { rotation: 0, lastX: -9999, lastY: -9999, needsRedraw: true }, shield: { rotation: 0, lastX: -9999, lastY: -9999, needsRedraw: true } }; const updateLoop = () => { if (systemActive && this.initialized) { this.updateCompanions(); this.updateStatusDisplay(); } if (systemActive) { requestAnimationFrame(updateLoop); } }; updateLoop(); console.log('🎮 [PIXEL COMPANIONS] Sistema iniciado exitosamente'); console.log(`🎯 [PIXEL COMPANIONS] Target: ${selectedPlayerName || 'Jugador desconocido'}`); console.log(`⚙️ [PIXEL COMPANIONS] Componentes activos: ${Object.entries(activeComponents).filter(([,v]) => v).map(([k]) => k).join(', ')}`); } async stopSystem() { console.log('⏹️ [PIXEL COMPANIONS] Deteniendo sistema...'); systemActive = false; this.playerManager.stopAutoUpdate(); // Limpiar el canvas antes de resetear estados await this.cleanCanvas(); // Resetear la cola de comandos commandQueue.length = 0; console.log('🧹 [PIXEL COMPANIONS] Cola de comandos reseteada (Queue: 0)'); // Limpiar estados this.companionStates.clear(); this.lastPlayerPositions.clear(); // Resetear animaciones this.animationState = { damageSequence: false, swordAttack: false, shieldDefend: false }; // Resetear vidas this.lives = 3; console.log('⏹️ [PIXEL COMPANIONS] Sistema detenido completamente'); console.log('🧹 [PIXEL COMPANIONS] Canvas limpiado y cola reseteada'); } createControlInterface() { const existingPanel = document.getElementById('pixel-companions-control'); if (existingPanel) existingPanel.remove(); const controlPanel = document.createElement('div'); controlPanel.id = 'pixel-companions-control'; controlPanel.style.cssText = ` position: fixed; top: 20px; right: 20px; z-index: 9999; background: linear-gradient(135deg, #1a1a2e, #16213e); color: white; padding: 20px; border-radius: 15px; font-family: 'Segoe UI', Arial, sans-serif; border: 2px solid #4fd1c7; min-width: 320px; box-shadow: 0 0 30px rgba(79,209,199,0.4); font-size: 14px; `; controlPanel.innerHTML = ` <div style="text-align: center; font-weight: bold; color: #4fd1c7; margin-bottom: 15px;"> 🎮 PIXEL COMPANIONS v3.4 - SIMPLE METHOD </div> <div style="margin-bottom: 15px;"> <label style="display: block; margin-bottom: 5px; color: #FFD700;">🎯 Target Player:</label> <select id="player-selector" style="width: 100%; padding: 8px; border-radius: 5px; background: #2d2d2d; color: white; border: 1px solid #4fd1c7;"> <option value="">🔍 Scanning players...</option> </select> </div> <div style="margin-bottom: 15px;"> <label style="display: block; margin-bottom: 8px; color: #FFD700;">⚙️ Active Components:</label> <div style="display: flex; gap: 10px; flex-wrap: wrap;"> <label style="display: flex; align-items: center; gap: 5px; cursor: pointer;"> <input type="checkbox" id="hearts-toggle" checked style="accent-color: #FF0000;"> <span>💖 Hearts</span> </label> <label style="display: flex; align-items: center; gap: 5px; cursor: pointer;"> <input type="checkbox" id="sword-toggle" checked style="accent-color: #00FFFF;"> <span>⚔️ Sword</span> </label> <label style="display: flex; align-items: center; gap: 5px; cursor: pointer;"> <input type="checkbox" id="shield-toggle" checked style="accent-color: #FFFF00;"> <span>🛡️ Shield</span> </label> </div> </div> <div style="display: flex; gap: 10px; margin-bottom: 15px;"> <button id="start-system-btn" style="flex: 1; padding: 10px; background: linear-gradient(135deg, #00FF00, #32CD32); color: white; border: none; border-radius: 8px; font-weight: bold; cursor: pointer;" disabled> ▶️ START </button> <button id="stop-system-btn" style="flex: 1; padding: 10px; background: linear-gradient(135deg, #FF4444, #CC0000); color: white; border: none; border-radius: 8px; font-weight: bold; cursor: pointer;" disabled> ⏹️ STOP </button> </div> <div id="system-status" style="text-align: center; padding: 10px; background: #333; border-radius: 5px; margin-bottom: 10px;"> ⏸️ System: <span style="color: #FF6B6B;">STOPPED</span> | Ready to start </div> <div id="companion-stats" style="font-size: 12px; color: #888;"> 📊 Players tracked: 0 | Queue: 0 | Console Mode: ON </div> <div style="font-size: 11px; color: #666; margin-top: 10px; text-align: center;"> 📝 Console logs (F12) | 🔧 Simple & Reliable Player Detection </div> `; document.body.appendChild(controlPanel); this.setupEventListeners(); } setupEventListeners() { const playerSelect = document.getElementById('player-selector'); const heartsToggle = document.getElementById('hearts-toggle'); const swordToggle = document.getElementById('sword-toggle'); const shieldToggle = document.getElementById('shield-toggle'); const startBtn = document.getElementById('start-system-btn'); const stopBtn = document.getElementById('stop-system-btn'); playerSelect?.addEventListener('change', (e) => { selectedPlayerId = e.target.value; if (selectedPlayerId === 'all') { selectedPlayerName = 'Todos los jugadores'; } else if (selectedPlayerId) { const selectedOption = e.target.options[e.target.selectedIndex]; selectedPlayerName = selectedOption.dataset.playerName || selectedOption.textContent.replace('🎯 ', '') || `Jugador ${selectedPlayerId}`; } else { selectedPlayerName = null; } console.log(`🎯 [PIXEL COMPANIONS] Target cambiado a: ${selectedPlayerName || 'Ninguno'}`); if (startBtn) startBtn.disabled = !selectedPlayerId; }); heartsToggle?.addEventListener('change', (e) => { activeComponents.hearts = e.target.checked; console.log(`💖 [PIXEL COMPANIONS] Corazones: ${e.target.checked ? 'Activados' : 'Desactivados'}`); }); swordToggle?.addEventListener('change', (e) => { activeComponents.sword = e.target.checked; console.log(`⚔️ [PIXEL COMPANIONS] Espada: ${e.target.checked ? 'Activada' : 'Desactivada'}`); }); shieldToggle?.addEventListener('change', (e) => { activeComponents.shield = e.target.checked; console.log(`🛡️ [PIXEL COMPANIONS] Escudo: ${e.target.checked ? 'Activado' : 'Desactivado'}`); }); startBtn?.addEventListener('click', () => { if (!selectedPlayerId) { console.log('🚫 [PIXEL COMPANIONS] Error: No hay jugador seleccionado'); return; } this.startSystem(); startBtn.disabled = true; if (stopBtn) stopBtn.disabled = false; }); stopBtn?.addEventListener('click', async () => { // Deshabilitar botón mientras se ejecuta la limpieza stopBtn.disabled = true; stopBtn.textContent = '🧹 CLEANING...'; await this.stopSystem(); // Restaurar botón y habilitar start stopBtn.textContent = '⏹️ STOP'; if (startBtn) startBtn.disabled = false; stopBtn.disabled = true; }); // Inicializar actualización de jugadores con delay setTimeout(() => { this.playerManager.startAutoUpdate(); }, 1000); } updateStatusDisplay() { const statusDiv = document.getElementById('system-status'); const statsDiv = document.getElementById('companion-stats'); if (statusDiv) { const status = systemActive ? `▶️ System: <span style="color: #00FF00;">ACTIVE</span> | Target: ${selectedPlayerName || 'Unknown'}` : `⏸️ System: <span style="color: #FF6B6B;">STOPPED</span> | Ready to start`; statusDiv.innerHTML = status; } if (statsDiv) { const componentsList = Object.entries(activeComponents) .filter(([, active]) => active) .map(([name]) => name.charAt(0).toUpperCase() + name.slice(1)) .join(', ') || 'None'; statsDiv.textContent = `📊 Players tracked: ${this.playerManager.validPlayers.length} | Queue: ${commandQueue.length} | Components: ${componentsList}`; } } } /* ---------- INICIALIZACIÓN ---------- */ let enhancedCompanionSystem = null; const initEnhancedSystem = () => { if (!enhancedCompanionSystem) { console.log('🚀 [PIXEL COMPANIONS] Inicializando Enhanced Pixel Companions System v3.4 (SIMPLE METHOD)...'); enhancedCompanionSystem = new EnhancedPixelCompanionSystem(); setTimeout(() => { console.log(''); console.log('✅ [PIXEL COMPANIONS] ENHANCED PIXEL COMPANIONS v3.4 LOADED! (SIMPLE METHOD)'); console.log('🔧 [PIXEL COMPANIONS] COPIADO: Método simple y confiable del otro script'); console.log('👥 [PIXEL COMPANIONS] Player Detection: 3 métodos simples (nickname → parent → fallback)'); console.log('🎯 [PIXEL COMPANIONS] Player Selector: Nombres únicos y sin duplicados'); console.log('⚙️ [PIXEL COMPANIONS] Component Control: Toggle Hearts/Sword/Shield'); console.log('🎮 [PIXEL COMPANIONS] System Control: Botones Start/Stop'); console.log('📊 [PIXEL COMPANIONS] Live Stats: Monitoreo en tiempo real'); console.log('💖 [PIXEL COMPANIONS] Hearts (Rojo) | ⚔️ Sword (Aqua+Azul) | 🛡️ Shield (Amarillo)'); console.log('📝 [PIXEL COMPANIONS] Debug logs: "Players found" en consola'); console.log('🎛️ [PIXEL COMPANIONS] Panel de control en la esquina superior derecha'); console.log('🧹 [PIXEL COMPANIONS] NEW: Canvas cleaning & Queue reset al presionar STOP'); console.log(''); }, 1000); } }; // Inicialización cuando DOM esté listo if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', initEnhancedSystem); } else { setTimeout(initEnhancedSystem, 500); } // Fallback de inicialización setTimeout(initEnhancedSystem, 2000); console.log('🌟 [PIXEL COMPANIONS] Enhanced Drawaria Pixel Companions v3.4 (SIMPLE METHOD) loaded! 🌟'); console.log('🧹 [PIXEL COMPANIONS] NEW FEATURES: Canvas cleaning + Queue reset on STOP'); })();