From 0e8c28e5f365e5f162de562ca3487aa766f72672 Mon Sep 17 00:00:00 2001 From: kyuketski Date: Sat, 30 Aug 2025 17:53:09 +0300 Subject: [PATCH] refactor: improve readability, logging, and pixel/color processing * Consolidated multi-line comments into single-line comments where appropriate to reduce clutter. * Simplified and clarified inline comments for better code readability and maintainability. * Refactored sitekey detection logic to use a reusable `trySitekey` function, reducing redundancy and improving maintainability. * Enhanced fallback logic in `detectSitekey` to handle edge cases more effectively. * Updated token generation logic to prioritize reusing pre-generated or cached tokens, optimizing performance. * Added detailed debug logs for Turnstile token capture, token generation, validation processes, and pixel comparison. * Improved formatting of complex log messages, dynamic strings, and template literals for better readability and debugging. * Reworked how available colors are extracted and validated to ensure proper handling of edge cases. * Added checks for null or insufficient color data during upload, improving error feedback to users. * Enhanced skipped pixel tracking by restructuring logic for transparency, white pixels, and unavailable colors. * Refactored batch processing to handle region changes more efficiently and log progress accurately. * Updated color extraction logic to handle scenarios where no color elements are found. * Simplified and standardized checkbox, select, slider, and toggle rendering for settings UI. * Ensured proper alignment and spacing in multi-line template literals for themes, languages, and other dropdowns. * Fixed minor typos, inconsistencies, and formatting issues across multiple modules. These changes improve maintainability, debugging visibility, and robustness of pixel/color processing while enhancing overall user experience without altering core functionality. --- Auto-Image.js | 388 +++++++++++++++++++++++++++++++++++--------------- 1 file changed, 272 insertions(+), 116 deletions(-) diff --git a/Auto-Image.js b/Auto-Image.js index 29c878c..88e5158 100644 --- a/Auto-Image.js +++ b/Auto-Image.js @@ -604,9 +604,11 @@ enable() { this.isEnabled = true; } + disable() { this.isEnabled = false; } + clear() { this.disable(); this.imageBitmap = null; @@ -1030,10 +1032,8 @@ await Utils.sleep(100); } - console.warn( - `❌ Timeout waiting for tiles: ${requiredTiles.length} required, - ${requiredTiles.filter((k) => this.originalTiles.has(k)).length} loaded` - ); + console.warn(`❌ Timeout waiting for tiles: ${requiredTiles.length} required, + ${requiredTiles.filter((k) => this.originalTiles.has(k)).length} loaded`); return false; } } @@ -1116,26 +1116,56 @@ } async function handleCaptchaWithRetry() { - const startTime = Date.now(); - try { - const sitekey = Utils.detectSitekey(); - console.log('πŸ”‘ Generating Turnstile token for sitekey:', sitekey); + const startTime = performance.now(); - if (typeof window !== 'undefined' && window.navigator) { - console.log('🧭 UA:', window.navigator.userAgent, 'Platform:', window.navigator.platform); + try { + const { sitekey, token: preGeneratedToken } = await Utils.obtainSitekeyAndToken(); + + if (!sitekey) { + throw new Error('No valid sitekey found'); } - const token = await Utils.generatePaintToken(sitekey); - if (token && token.length > 20) { - const elapsed = Math.round(Date.now() - startTime); + console.log('πŸ”‘ Using sitekey:', sitekey); + + if (typeof window !== 'undefined' && window.navigator) { + console.log( + '🧭 UA:', + window.navigator.userAgent.substring(0, 50) + '...', + 'Platform:', + window.navigator.platform + ); + } + + let token = null; + + if ( + preGeneratedToken && + typeof preGeneratedToken === 'string' && + preGeneratedToken.length > 20 + ) { + console.log('♻️ Reusing pre-generated Turnstile token'); + token = preGeneratedToken; + } else { + if (isTokenValid()) { + console.log('♻️ Using existing cached token (from previous session)'); + token = turnstileToken; + } else { + console.log('πŸ” Generating new token with executeTurnstile...'); + token = await Utils.executeTurnstile(sitekey, 'paint'); + if (token) setTurnstileToken(token); + } + } + + if (token && typeof token === 'string' && token.length > 20) { + const elapsed = Math.round(performance.now() - startTime); console.log(`βœ… Turnstile token generated successfully in ${elapsed}ms`); return token; } else { - throw new Error('Invalid or empty token received'); + throw new Error(`Invalid or empty token received - Length: ${token?.length || 0}`); } } catch (error) { - const elapsed = Math.round(Date.now() - startTime); - console.log(`❌ Turnstile token generation failed after ${elapsed}ms:`, error); + const elapsed = Math.round(performance.now() - startTime); + console.error(`❌ Turnstile token generation failed after ${elapsed}ms:`, error); throw error; } } @@ -1178,7 +1208,18 @@ try { const payload = JSON.parse(args[1].body); if (payload.t) { - console.log('βœ… Turnstile Token Captured:', payload.t); + // πŸ“Š Debug log + console.log( + `πŸ”βœ… Turnstile Token Captured - Type: ${typeof payload.t}, Value: ${ + payload.t + ? typeof payload.t === 'string' + ? payload.t.length > 50 + ? payload.t.substring(0, 50) + '...' + : payload.t + : JSON.stringify(payload.t) + : 'null/undefined' + }, Length: ${payload.t?.length || 0}` + ); window.postMessage({ source: 'turnstile-capture', token: payload.t }, '*'); } } catch (_) { @@ -1279,8 +1320,7 @@ if (hours > 0) return `${hours}h ${minutes}m ${seconds}s`; if (minutes > 0) return `${minutes}m ${seconds}s`; return `${seconds}s`; - }, - // Turnstile Generator Integration - Optimized with widget reuse and proper cleanup + }, // Turnstile Generator Integration - Optimized with widget reuse and proper cleanup turnstileLoaded: false, _turnstileContainer: null, _turnstileOverlay: null, @@ -1579,10 +1619,6 @@ }); }, - async generatePaintToken(sitekey) { - return this.executeTurnstile(sitekey, 'paint'); - }, - // Cleanup method for when the script is disabled/reloaded cleanupTurnstile() { if (this._turnstileWidgetId && window.turnstile?.remove) { @@ -1607,11 +1643,17 @@ this._lastSitekey = null; }, - detectSitekey(fallback = '0x4AAAAAABpqJe8FO0N84q0F') { + async obtainSitekeyAndToken(fallback = '0x4AAAAAABpqJe8FO0N84q0F') { // Cache sitekey to avoid repeated DOM queries if (this._cachedSitekey) { console.log('πŸ” Using cached sitekey:', this._cachedSitekey); - return this._cachedSitekey; + + return isTokenValid() + ? { + sitekey: this._cachedSitekey, + token: turnstileToken, + } + : { sitekey: this._cachedSitekey, token: null }; } // List of potential sitekeys to try @@ -1620,77 +1662,101 @@ '0x4AAAAAAAJ7xjKAp6Mt_7zw', // Alternative WPlace sitekey '0x4AAAAAADm5QWx6Ov2LNF2g', // Another common sitekey ]; + const trySitekey = async (sitekey, source) => { + if (!sitekey || sitekey.length < 10) return null; + + console.log(`πŸ” Testing sitekey from ${source}:`, sitekey); + const token = await this.executeTurnstile(sitekey); + + if (token && token.length >= 20) { + console.log(`βœ… Valid token generated from ${source} sitekey`); + setTurnstileToken(token); + this._cachedSitekey = sitekey; + return { sitekey, token }; + } else { + console.log(`❌ Failed to get token from ${source} sitekey`); + return null; + } + }; try { - // Try to find sitekey in data attributes + // 1️⃣ data-sitekey attribute const sitekeySel = document.querySelector('[data-sitekey]'); if (sitekeySel) { const sitekey = sitekeySel.getAttribute('data-sitekey'); - if (sitekey && sitekey.length > 10) { - this._cachedSitekey = sitekey; - console.log('πŸ” Sitekey detected from data attribute:', sitekey); - return sitekey; + const result = await trySitekey(sitekey, 'data attribute'); + if (result) { + return result; } } - // Try turnstile element + // 2️⃣ Turnstile element const turnstileEl = document.querySelector('.cf-turnstile'); - if (turnstileEl?.dataset?.sitekey && turnstileEl.dataset.sitekey.length > 10) { - this._cachedSitekey = turnstileEl.dataset.sitekey; - console.log('πŸ” Sitekey detected from turnstile element:', this._cachedSitekey); - return this._cachedSitekey; + if (turnstileEl?.dataset?.sitekey) { + const sitekey = turnstileEl.dataset.sitekey; + const result = await trySitekey(sitekey, 'turnstile element'); + if (result) { + return result; + } } - // Try to find sitekey in meta tags + // 3️⃣ Meta tags const metaTags = document.querySelectorAll( 'meta[name*="turnstile"], meta[property*="turnstile"]' ); for (const meta of metaTags) { const content = meta.getAttribute('content'); - if (content && content.length > 10) { - this._cachedSitekey = content; - console.log('πŸ” Sitekey detected from meta tag:', this._cachedSitekey); - return this._cachedSitekey; + const result = await trySitekey(content, 'meta tag'); + if (result) { + return result; } } - // Try global variable - if ( - typeof window !== 'undefined' && - window.__TURNSTILE_SITEKEY && - window.__TURNSTILE_SITEKEY.length > 10 - ) { - this._cachedSitekey = window.__TURNSTILE_SITEKEY; - console.log('πŸ” Sitekey detected from global variable:', this._cachedSitekey); - return this._cachedSitekey; + // 4️⃣ Global variable + if (window.__TURNSTILE_SITEKEY) { + const result = await trySitekey(window.__TURNSTILE_SITEKEY, 'global variable'); + if (result) { + return result; + } } - // Try script tags for inline sitekey + // 5️⃣ Script tags const scripts = document.querySelectorAll('script'); for (const script of scripts) { const content = script.textContent || script.innerHTML; - const sitekeyMatch = content.match(/sitekey['":\s]+(['"0-9a-zA-X_-]{20,})/i); - if (sitekeyMatch && sitekeyMatch[1] && sitekeyMatch[1].length > 10) { - this._cachedSitekey = sitekeyMatch[1].replace(/['"]/g, ''); - console.log('πŸ” Sitekey detected from script content:', this._cachedSitekey); - return this._cachedSitekey; + const match = content.match( + /(?:sitekey|data-sitekey)['"\s\[\]:\=\(]*['"]?([0-9a-zA-Z_-]{20,})['"]?/i + ); + if (match && match[1]) { + const extracted = match[1].replace(/['"]/g, ''); + const result = await trySitekey(extracted, 'script content'); + if (result) { + return result; + } } } - // If no sitekey found through detection, try the known working sitekeys - console.log('πŸ” No sitekey detected, trying known working sitekeys...'); + // 6️⃣ Known potential sitekeys + console.log('πŸ” Testing known potential sitekeys...'); for (const testSitekey of potentialSitekeys) { - console.log('πŸ” Trying sitekey:', testSitekey); - this._cachedSitekey = testSitekey; - return testSitekey; + const result = await trySitekey(testSitekey, 'known list'); + if (result) { + return result; + } } } catch (error) { - console.warn('Error detecting sitekey:', error); + console.warn('⚠️ Error during sitekey detection:', error); } - console.log('πŸ” Using fallback sitekey:', fallback); - this._cachedSitekey = fallback; - return fallback; + // 7️⃣ Fallback + console.log('πŸ”§ Trying fallback sitekey:', fallback); + const fallbackResult = await trySitekey(fallback, 'fallback'); + if (fallbackResult) { + return fallbackResult; + } + + console.error('❌ No working sitekey or token found.'); + return { sitekey: null, token: null }; }, createElement: (tag, props = {}, children = []) => { @@ -1892,11 +1958,15 @@ }, resolveColor(targetRgb, availableColors, exactMatch = false) { - if (!availableColors || availableColors.length === 0) return { id: null, rgb: targetRgb }; + if (!availableColors || availableColors.length === 0) + return { + id: null, + rgb: targetRgb, + }; - const cacheKey = `${targetRgb[0]},${targetRgb[1]},${targetRgb[2]}|${ - state.colorMatchingAlgorithm - }|${state.enableChromaPenalty ? 'c' : 'nc'}|${state.chromaPenaltyWeight}|${exactMatch ? 'exact' : 'closest'}`; + const cacheKey = `${targetRgb[0]},${targetRgb[1]},${targetRgb[2]}|${state.colorMatchingAlgorithm}|${ + state.enableChromaPenalty ? 'c' : 'nc' + }|${state.chromaPenaltyWeight}|${exactMatch ? 'exact' : 'closest'}`; if (colorCache.has(cacheKey)) return colorCache.get(cacheKey); @@ -2049,7 +2119,10 @@ extractAvailableColors: () => { const colorElements = document.querySelectorAll('.tooltip button[id^="color-"]'); - + if (colorElements.length === 0) { + console.log('❌ No color elements found on page'); + return null; + } // Separate available and unavailable colors const availableColors = []; const unavailableColors = []; @@ -2089,7 +2162,9 @@ console.log('\n--- AVAILABLE COLORS ---'); availableColors.forEach((color, index) => { console.log( - `${index + 1}. ID: ${color.id}, Name: "${color.name}", RGB: (${color.rgb[0]}, ${color.rgb[1]}, ${color.rgb[2]})` + `${ + index + 1 + }. ID: ${color.id}, Name: "${color.name}", RGB: (${color.rgb[0]}, ${color.rgb[1]}, ${color.rgb[2]})` ); }); } @@ -2098,7 +2173,9 @@ console.log('\n--- UNAVAILABLE COLORS ---'); unavailableColors.forEach((color, index) => { console.log( - `${index + 1}. ID: ${color.id}, Name: "${color.name}", RGB: (${color.rgb[0]}, ${color.rgb[1]}, ${color.rgb[2]}) [LOCKED]` + `${ + index + 1 + }. ID: ${color.id}, Name: "${color.name}", RGB: (${color.rgb[0]}, ${color.rgb[1]}, ${color.rgb[2]}) [LOCKED]` ); }); } @@ -2993,6 +3070,7 @@ .querySelector('#unselectPaidBtn') ?.addEventListener('click', () => unselectAllPaidColors()); } + async function handleCaptcha() { const startTime = performance.now(); @@ -3005,7 +3083,12 @@ // Generator mode (pure) or Hybrid mode - try generator first try { // Use optimized token generation with automatic sitekey detection - const sitekey = Utils.detectSitekey(); + const { sitekey, token: preGeneratedToken } = await Utils.obtainSitekeyAndToken(); + + if (!sitekey) { + throw new Error('No valid sitekey found'); + } + console.log('πŸ”‘ Generating Turnstile token for sitekey:', sitekey); console.log( '🧭 UA:', @@ -3019,8 +3102,32 @@ await Utils.loadTurnstile(); } - const token = await Utils.generatePaintToken(sitekey); + let token = null; + // βœ… Reuse pre-generated token if available and valid + if ( + preGeneratedToken && + typeof preGeneratedToken === 'string' && + preGeneratedToken.length > 20 + ) { + console.log('♻️ Reusing pre-generated token from sitekey detection phase'); + token = preGeneratedToken; + } + // βœ… Or use globally cached token if still valid + else if (isTokenValid()) { + console.log('♻️ Using existing cached token (from previous operation)'); + token = turnstileToken; + } + // βœ… Otherwise generate a new one + else { + console.log('πŸ” No valid pre-generated or cached token, creating new one...'); + token = await Utils.executeTurnstile(sitekey, 'paint'); + if (token) { + setTurnstileToken(token); + } + } + + // πŸ“Š Debug log console.log( `πŸ” Token received - Type: ${typeof token}, Value: ${ token @@ -3033,6 +3140,7 @@ }, Length: ${token?.length || 0}` ); + // βœ… Final validation if (typeof token === 'string' && token.length > 20) { const duration = Math.round(performance.now() - startTime); console.log(`βœ… Turnstile token generated successfully in ${duration}ms`); @@ -3371,7 +3479,9 @@ z-index: 99999; color: ${theme.text || 'white'}; font-family: ${theme.fontFamily || "'Segoe UI', Tahoma, Geneva, Verdana, sans-serif"}; - box-shadow: ${theme.boxShadow || '0 20px 40px rgba(0,0,0,0.3), 0 0 0 1px rgba(255,255,255,0.1)'}; + box-shadow: ${ + theme.boxShadow || '0 20px 40px rgba(0,0,0,0.3), 0 0 0 1px rgba(255,255,255,0.1)' + }; backdrop-filter: ${theme.backdropFilter || 'blur(10px)'}; overflow: hidden; animation: settingsSlideIn 0.4s ease-out; @@ -3407,9 +3517,15 @@

Generator mode creates tokens automatically. Hybrid mode falls back to manual when generator fails. Manual mode only uses pixel placement. @@ -3429,7 +3545,9 @@

- Overlay Opacity + Overlay Opacity
${Math.round(state.overlayOpacity * 100)}%
@@ -3714,7 +3842,9 @@ ${Object.keys(CONFIG.THEMES) .map( (themeName) => - `` + `` ) .join('')} @@ -3955,8 +4085,12 @@
- +
@@ -3978,7 +4114,9 @@ Enable Dithering
Floyd–Steinberg error diffusion in preview and applied output
- +