diff --git a/Auto-Image.js b/Auto-Image.js index 01026ca..54126fd 100644 --- a/Auto-Image.js +++ b/Auto-Image.js @@ -5,12 +5,12 @@ TRANSPARENCY_THRESHOLD: 100, WHITE_THRESHOLD: 250, LOG_INTERVAL: 10, - PAINTING_SPEED: { + PAINTING_SPEED: { MIN: 1, // Minimum 1 pixel per second MAX: 1000, // Maximum 1000 pixels per second DEFAULT: 5, // Default 5 pixels per second - }, - PAINTING_SPEED_ENABLED: false, + }, + SKIP_CORRECT_PIXELS: true, // Skip pixels that already have correct color // Optimized CSS Classes for reuse CSS_CLASSES: { BUTTON_PRIMARY: ` @@ -133,6 +133,17 @@ } } + const loadSkipPixelsPreference = () => { + try { + const saved = localStorage.getItem("wplace_skip_correct_pixels") + if (saved !== null) { + CONFIG.SKIP_CORRECT_PIXELS = saved === 'true' + } + } catch (e) { + console.warn("Could not load skip correct pixels preference:", e) + } + } + // BILINGUAL TEXT STRINGS const TEXT = { en: { @@ -162,6 +173,7 @@ missingRequirements: "❌ Load an image and select a position first", progress: "Progress", pixels: "Pixels", + painted: "Painted", charges: "Charges", estimatedTime: "Estimated time", initMessage: "Click 'Start Auto-BOT' to begin", @@ -193,7 +205,11 @@ language: "Language", themeSettings: "Theme Settings", themeSettingsDesc: "Choose your preferred color theme for the interface.", - languageSelectDesc: "Select your preferred language. Changes will take effect immediately.", + languageSelectDesc: "Select your preferred language. Changes will take effect immediately.", + skipCorrectPixels: "Skip Correct Pixels", + skipCorrectPixelsDesc: "Skip pixels that already have the correct color and count them as painted. Note: May not work due to canvas security restrictions.", + pixelsSkipped: "Pixels skipped: {count}", + speedSettingDesc: "Adjust the painting speed from {min} to {max} pixels per second. Higher speeds may result in longer update times on the WPlace server." }, pt: { title: "WPlace Auto-Image", @@ -222,6 +238,7 @@ missingRequirements: "❌ Carregue uma imagem e selecione uma posição primeiro", progress: "Progresso", pixels: "Pixels", + painted: "Pintados", charges: "Cargas", estimatedTime: "Tempo estimado", initMessage: "Clique em 'Iniciar Auto-BOT' para começar", @@ -253,7 +270,11 @@ language: "Idioma", themeSettings: "Configurações de Tema", themeSettingsDesc: "Escolha seu tema de cores preferido para a interface.", - languageSelectDesc: "Selecione seu idioma preferido. As alterações terão efeito imediatamente.", + languageSelectDesc: "Selecione seu idioma preferido. As alterações terão efeito imediatamente.", + skipCorrectPixels: "Pular Pixels Corretos", + skipCorrectPixelsDesc: "Pular pixels que já têm a cor correta e contá-los como pintados. Nota: Pode não funcionar devido a restrições de segurança do canvas.", + pixelsSkipped: "Pixels pulados: {count}", + speedSettingDesc: "Ajuste a velocidade de pintura de {min} a {max} pixels por segundo. Velocidades mais altas podem resultar em tempos de atualização mais longos no servidor WPlace." }, vi: { title: "WPlace Auto-Image", @@ -282,6 +303,7 @@ missingRequirements: "❌ Hãy tải lên hình ảnh và chọn vị trí trước", progress: "Tiến trình", pixels: "Pixel", + painted: "Đã vẽ", charges: "Điện tích", estimatedTime: "Thời gian ước tính", initMessage: "Nhấp 'Khởi động Auto-BOT' để bắt đầu", @@ -314,6 +336,10 @@ themeSettings: "Cài đặt Giao diện", themeSettingsDesc: "Chọn chủ đề màu sắc yêu thích cho giao diện.", languageSelectDesc: "Chọn ngôn ngữ ưa thích. Thay đổi sẽ có hiệu lực ngay lập tức.", + skipCorrectPixels: "Bỏ qua Pixel đúng màu", + skipCorrectPixelsDesc: "Bỏ qua các pixel đã có màu đúng và tính chúng là đã vẽ. Lưu ý: Có thể không hoạt động do hạn chế bảo mật canvas.", + pixelsSkipped: "Pixel đã bỏ qua: {count}", + speedSettingDesc: "Điều chỉnh tốc độ vẽ từ {min} đến {max} pixel mỗi giây. Tốc độ cao có thể làm trong wplace server update mất thời gian hơn." }, fr: { title: "WPlace Auto-Image", @@ -342,6 +368,7 @@ missingRequirements: "❌ Veuillez charger une image et sélectionner une position d'abord", progress: "Progrès", pixels: "Pixels", + painted: "Peints", charges: "Charges", estimatedTime: "Temps estimé", initMessage: "Cliquez sur 'Démarrer Auto-BOT' pour commencer", @@ -374,6 +401,10 @@ themeSettings: "Paramètres de Thème", themeSettingsDesc: "Choisissez votre thème de couleurs préféré pour l'interface.", languageSelectDesc: "Sélectionnez votre langue préférée. Les changements prendront effet immédiatement.", + skipCorrectPixels: "Ignorer les Pixels Corrects", + skipCorrectPixelsDesc: "Ignorer les pixels qui ont déjà la bonne couleur et les compter comme peints. Note: Peut ne pas fonctionner en raison de restrictions de sécurité du canvas.", + pixelsSkipped: "Pixels ignorés: {count}", + speedSettingDesc: "Ajustez la vitesse de peinture de {min} à {max} pixels par seconde. Des vitesses plus élevées peuvent entraîner des temps de mise à jour plus longs sur le serveur WPlace." }, } @@ -384,6 +415,7 @@ processing: false, totalPixels: 0, paintedPixels: 0, + skippedPixels: 0, // Track skipped pixels availableColors: [], currentCharges: 0, cooldown: CONFIG.COOLDOWN_DEFAULT, @@ -552,6 +584,154 @@ colorDistance: (a, b) => Math.sqrt(Math.pow(a[0] - b[0], 2) + Math.pow(a[1] - b[1], 2) + Math.pow(a[2] - b[2], 2)), + // Debug function to test canvas access + testCanvasAccess: () => { + console.log("=== Canvas Access Debug ===") + + const canvases = document.querySelectorAll('canvas') + console.log(`Found ${canvases.length} canvas elements`) + + canvases.forEach((canvas, index) => { + console.log(`Canvas ${index}:`, { + width: canvas.width, + height: canvas.height, + id: canvas.id, + className: canvas.className, + style: canvas.style.cssText + }) + + try { + const ctx = canvas.getContext('2d') + if (ctx) { + // Try to read a pixel from center + const x = Math.floor(canvas.width / 2) + const y = Math.floor(canvas.height / 2) + const imageData = ctx.getImageData(x, y, 1, 1) + const data = imageData.data + console.log(` Pixel at (${x},${y}): RGB(${data[0]}, ${data[1]}, ${data[2]})`) + } + } catch (error) { + console.log(` Error reading canvas ${index}:`, error.message) + } + }) + + console.log("=== End Debug ===") + }, + + // Simplified canvas pixel reading for WPlace + getWPlacePixelColor: (x, y) => { + try { + console.log(`Attempting to read pixel at (${x},${y})...`) + + // Find the main WPlace canvas - try different approaches + let canvas = null + + // Method 1: Look for canvas in main container + const containers = ['#app', '[data-testid="canvas-container"]', '.canvas-container', 'main', 'body'] + for (const selector of containers) { + const container = document.querySelector(selector) + if (container) { + const foundCanvas = container.querySelector('canvas') + if (foundCanvas && foundCanvas.width > 100 && foundCanvas.height > 100) { + canvas = foundCanvas + console.log(`Found canvas via container ${selector}: ${canvas.width}x${canvas.height}`) + break + } + } + } + + // Method 2: Direct canvas selectors + if (!canvas) { + const selectors = [ + 'canvas[width][height]', + 'canvas.pixelcanvas', + 'canvas.canvas', + 'canvas[data-testid="canvas"]', + 'canvas' + ] + + for (const selector of selectors) { + const canvases = document.querySelectorAll(selector) + for (const c of canvases) { + // Check if canvas has reasonable dimensions and is visible + if (c.width > 100 && c.height > 100 && + c.offsetWidth > 0 && c.offsetHeight > 0) { + canvas = c + console.log(`Found canvas via selector ${selector}: ${canvas.width}x${canvas.height}`) + break + } + } + if (canvas) break + } + } + + // Method 3: Find the largest canvas + if (!canvas) { + const allCanvases = document.querySelectorAll('canvas') + let largest = null + let maxSize = 0 + + for (const c of allCanvases) { + const size = c.width * c.height + if (size > maxSize && c.offsetWidth > 0 && c.offsetHeight > 0) { + maxSize = size + largest = c + } + } + + if (largest) { + canvas = largest + console.log(`Found largest canvas: ${canvas.width}x${canvas.height}`) + } + } + + if (!canvas) { + console.warn("No suitable canvas found") + return null + } + + // Check if coordinates are within canvas bounds + if (x < 0 || y < 0 || x >= canvas.width || y >= canvas.height) { + console.warn(`Coordinates (${x},${y}) outside canvas bounds ${canvas.width}x${canvas.height}`) + return null + } + + const ctx = canvas.getContext('2d') + if (!ctx) { + console.warn("Could not get canvas context") + return null + } + + // Get pixel data + const imageData = ctx.getImageData(x, y, 1, 1) + const data = imageData.data + + const color = [data[0], data[1], data[2]] + console.log(`Successfully read pixel at (${x},${y}): RGB(${color.join(',')})`) + return color + + } catch (error) { + console.warn(`Failed to read pixel at (${x},${y}):`, error.message) + return null + } + }, + + // Check if current pixel matches target color + pixelMatches: (currentColor, targetColor, tolerance = 10) => { + if (!currentColor || !targetColor) return false + + const [cr, cg, cb] = currentColor + const [tr, tg, tb] = targetColor + + const distance = Math.sqrt( + Math.pow(cr - tr, 2) + + Math.pow(cg - tg, 2) + + Math.pow(cb - tb, 2) + ) + + return distance <= tolerance + }, + isWhitePixel: (r, g, b) => r >= CONFIG.WHITE_THRESHOLD && g >= CONFIG.WHITE_THRESHOLD && b >= CONFIG.WHITE_THRESHOLD, @@ -967,6 +1147,7 @@ loadThemePreference() loadLanguagePreference() + loadSkipPixelsPreference() const theme = getCurrentTheme() @@ -2142,8 +2323,9 @@ padding: 0; z-index: 10002; display: none; - min-width: 380px; - max-width: 420px; + width: 720px; + max-width: 90vw; + max-height: 85vh; color: white; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; box-shadow: 0 20px 40px rgba(0,0,0,0.3), 0 0 0 1px rgba(255,255,255,0.1); @@ -2177,206 +2359,205 @@ -