diff --git a/Extension/background.js b/Extension/background.js index 0217179..6ccde21 100644 --- a/Extension/background.js +++ b/Extension/background.js @@ -592,6 +592,7 @@ const cookieDomain = ".backend.wplace.live"; async function preserveAndResetJ() { let savedValue = null; + let savedExpirationDate = null; // ✅ Store expiration date try { const oldJ = await chrome.cookies.get({ @@ -601,7 +602,9 @@ async function preserveAndResetJ() { if (oldJ && oldJ.value) { savedValue = oldJ.value.trim(); + savedExpirationDate = oldJ.expirationDate; // ✅ Capture expiration console.log("[bg] Saved j cookie:", savedValue); + console.log("[bg] Cookie expires at:", savedExpirationDate ? new Date(savedExpirationDate * 1000).toISOString() : 'session'); const accountInfo = await checkTokenAndGetInfo(savedValue); @@ -619,12 +622,14 @@ async function preserveAndResetJ() { ...accountInfo, // Update with fresh data from API token: accountInfo.token, // Ensure token is updated name: accountInfo.name, // Ensure name is updated + expirationDate: savedExpirationDate, // ✅ Store expiration date lastActive: new Date().toISOString() // Update last seen }; - console.log(`✅ ID ${accountInfo.ID} found. Updated account info.`); + console.log(`✅ ID ${accountInfo.ID} found. Updated account info with expiration.`); } else { + accountInfo.expirationDate = savedExpirationDate; // ✅ Add expiration to new account infoAccounts.push(accountInfo); - console.log(`✅ New account added: ${accountInfo.name} (${accountInfo.ID}).`); + console.log(`✅ New account added: ${accountInfo.name} (${accountInfo.ID}) with expiration.`); } await chrome.storage.local.set({ infoAccounts }); @@ -650,7 +655,7 @@ async function preserveAndResetJ() { }); if (savedValue) { - setCookie(savedValue); + setCookie(savedValue, savedExpirationDate); // ✅ Pass expiration date } else { console.log("[bg] No j to restore, leaving nuked"); } @@ -774,42 +779,57 @@ chrome.webNavigation.onCompleted.addListener( { url: [{ hostContains: "wplace.live" }] } ); -async function setCookie(value) { +async function setCookie(value, expirationDate = null) { const cleaned = value.trim(); console.log("[bg] setCookie CALLED with:", cleaned); + if (expirationDate) { + console.log("[bg] Setting cookie expiration:", new Date(expirationDate * 1000).toISOString()); + } else { + console.log("[bg] No expiration provided - will use server default or calculate"); + } return new Promise((resolve, reject) => { - chrome.cookies.set( - { - url: "https://backend.wplace.live/", - name: "j", - value: cleaned, - domain: cookieDomain, - path: "/", - }, - (cookie) => { - if (chrome.runtime.lastError) { - console.error( - "[bg] cookie set error:", - chrome.runtime.lastError.message - ); - reject(new Error(chrome.runtime.lastError.message)); - } else { - console.log("[bg] cookie set result:", cookie); + const cookieDetails = { + url: "https://backend.wplace.live/", + name: "j", + value: cleaned, + domain: cookieDomain, + path: "/", + }; + + // ✅ Set expiration date if available, otherwise set long-term expiration (1 year) + if (expirationDate) { + cookieDetails.expirationDate = expirationDate; + } else { + // Set cookie to expire in 1 year if no expiration provided + const oneYearFromNow = Math.floor(Date.now() / 1000) + (365 * 24 * 60 * 60); + cookieDetails.expirationDate = oneYearFromNow; + console.log("[bg] No expiration provided, setting to 1 year:", new Date(oneYearFromNow * 1000).toISOString()); + } - chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => { - if (tabs.length > 0) { - chrome.tabs.sendMessage(tabs[0].id, { - type: "cookieSet", - value: cleaned, - }); - } - }); + chrome.cookies.set(cookieDetails, (cookie) => { + if (chrome.runtime.lastError) { + console.error( + "[bg] cookie set error:", + chrome.runtime.lastError.message + ); + reject(new Error(chrome.runtime.lastError.message)); + } else { + console.log("[bg] cookie set result:", cookie); + console.log("[bg] Cookie will expire:", cookie.expirationDate ? new Date(cookie.expirationDate * 1000).toISOString() : 'session'); - resolve(cookie); - } + chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => { + if (tabs.length > 0) { + chrome.tabs.sendMessage(tabs[0].id, { + type: "cookieSet", + value: cleaned, + }); + } + }); + + resolve(cookie); } - ); + }); }); } diff --git a/Extension/lang/de.json b/Extension/lang/de.json index 3af0fbf..7e5dcbb 100644 --- a/Extension/lang/de.json +++ b/Extension/lang/de.json @@ -3,7 +3,7 @@ "toggleOverlay": "Vorschau umschalten", "scanColors": "Farben scannen", "uploadImage": "Bild hochladen", - "resizeImage": "Bildgröße ändern", + "resizeImage": "Bild verarbeiten/bearbeiten", "selectPosition": "Position wählen", "startPainting": "Malen starten", "stopPainting": "Malen stoppen", @@ -11,7 +11,8 @@ "noColorsFound": "❌ Öffne die Farbpalette und versuche es erneut!", "colorsFound": "✅ {count} verfügbare Farben gefunden. Bereit zum Hochladen.", "loadingImage": "🖼️ Bild wird geladen...", - "imageLoaded": "✅ Bild mit {count} gültigen Pixeln geladen", + "imageLoaded": "✅ Bild mit {count} gültigen Pixeln geladen ⚠️ Verarbeiten Sie das Bild zuerst über \"Bild verarbeiten/bearbeiten\", bevor Sie es platzieren!", + "imageNeedsProcessing": "Bild muss verarbeitet werden ⚠️", "imageError": "❌ Fehler beim Laden des Bildes", "selectPositionAlert": "Male den ersten Pixel an der Stelle, an der dein Kunstwerk beginnen soll!", "waitingPosition": "👆 Warte, bis du den Referenzpixel malst...", @@ -149,6 +150,10 @@ "paintTransparentPixelsDescription": "Wenn aktiviert, werden transparente Template-Pixel gemalt", "paintUnavailablePixels": "Nicht verfügbare Pixel malen", "paintUnavailablePixelsDescription": "Wenn aktiviert, werden nicht verfügbare Template-Farben mit der nächsten verfügbaren Farbe gemalt", + "paintingModeAuto": "Automatisch", + "paintingModeAssist": "Assistieren", + "paintingModeAutoDesc": "Bot malt automatisch Pixel", + "paintingModeAssistDesc": "Overlay leitet Ihre manuelle Pixelplatzierung", "colorsUpdated": "✅ Verfügbare Farben erhöht {oldCount} -> {newCount}, {diffCount} neue Farben gefunden", "overlayTilesNotLoaded": "❌ Erforderliche Kartenkacheln nicht geladen. Verbindung prüfen oder erneut versuchen.", "paintingBatchFailed": "❌ Batch-Senden nach mehreren Versuchen fehlgeschlagen. Malen gestoppt.", diff --git a/Extension/lang/en.json b/Extension/lang/en.json index f1bd500..0f7cd46 100644 --- a/Extension/lang/en.json +++ b/Extension/lang/en.json @@ -3,7 +3,7 @@ "toggleOverlay": "Toggle Overlay", "scanColors": "Scan Colors", "uploadImage": "Upload", - "resizeImage": "Resize", + "resizeImage": "Process/Edit Image", "selectPosition": "Select Position", "startPainting": "Start", "stopPainting": "Stop", @@ -12,7 +12,8 @@ "colorsUpdated": "✅ Available colors increased {oldCount} -> {newCount}, {diffCount} new colors found", "colorsFound": "✅ {count} available colors found. Ready to upload.", "loadingImage": "🖼️ Loading image...", - "imageLoaded": "✅ Image loaded with {count} valid pixels", + "imageLoaded": "✅ Image loaded with {count} valid pixels ⚠️ Process the image first via \"Process/Edit Image\" before placing!", + "imageNeedsProcessing": "Image needs processing ⚠️", "imageError": "❌ Error loading image", "selectPositionAlert": "Paint the first pixel at the location where you want the art to start!", "waitingPosition": "👆 Waiting for you to paint the reference pixel...", @@ -157,5 +158,9 @@ "paintTransparentPixels": "Paint Transparent", "paintTransparentPixelsDescription": "If enabled, template transparent pixels will be painted", "paintUnavailablePixels": "Paint Unavailable", - "paintUnavailablePixelsDescription": "If enabled, template colors that are unavailable will be painted using the closest available color" + "paintUnavailablePixelsDescription": "If enabled, template colors that are unavailable will be painted using the closest available color", + "paintingModeAuto": "Auto", + "paintingModeAssist": "Assist", + "paintingModeAutoDesc": "Bot will automatically paint pixels", + "paintingModeAssistDesc": "Overlay will guide your manual pixel placement" } \ No newline at end of file diff --git a/Extension/lang/es.json b/Extension/lang/es.json index 5987aea..e2a8600 100644 --- a/Extension/lang/es.json +++ b/Extension/lang/es.json @@ -3,7 +3,7 @@ "toggleOverlay": "Alternar superposición", "scanColors": "Escanear colores", "uploadImage": "Subir imagen", - "resizeImage": "Cambiar tamaño", + "resizeImage": "Procesar/Editar imagen", "selectPosition": "Seleccionar posición", "startPainting": "Iniciar", "stopPainting": "Detener", @@ -12,7 +12,8 @@ "colorsUpdated": "✅ Colores disponibles aumentados {oldCount} -> {newCount}, {diffCount} nuevos colores encontrados", "colorsFound": "✅ Se encontraron {count} colores disponibles. Listo para subir.", "loadingImage": "🖼️ Cargando imagen...", - "imageLoaded": "✅ Imagen cargada con {count} píxeles válidos", + "imageLoaded": "✅ Imagen cargada con {count} píxeles válidos ⚠️ ¡Procesa la imagen primero mediante \"Procesar/Editar imagen\" antes de colocarla!", + "imageNeedsProcessing": "La imagen necesita procesamiento ⚠️", "imageError": "❌ Error al cargar la imagen", "selectPositionAlert": "¡Pinta el primer píxel en la ubicación donde quieres que comience el arte!", "waitingPosition": "👆 Esperando que pintes el píxel de referencia...", @@ -157,5 +158,9 @@ "paintTransparentPixels": "Pintar píxeles transparentes", "paintTransparentPixelsDescription": "Si está activado, se pintarán los píxeles transparentes de la plantilla", "paintUnavailablePixels": "Pintar píxeles no disponibles", - "paintUnavailablePixelsDescription": "Si está activado, los colores de plantilla no disponibles se pintarán usando el color disponible más cercano" + "paintUnavailablePixelsDescription": "Si está activado, los colores de plantilla no disponibles se pintarán usando el color disponible más cercano", + "paintingModeAuto": "Automático", + "paintingModeAssist": "Asistir", + "paintingModeAutoDesc": "El bot pintará píxeles automáticamente", + "paintingModeAssistDesc": "La superposición guiará tu colocación manual de píxeles" } diff --git a/Extension/lang/fr.json b/Extension/lang/fr.json index 6a83089..7948a65 100644 --- a/Extension/lang/fr.json +++ b/Extension/lang/fr.json @@ -3,7 +3,7 @@ "toggleOverlay": "Basculer l'overlay", "scanColors": "Scanner les couleurs", "uploadImage": "Télécharger l'image", - "resizeImage": "Redimensionner l'image", + "resizeImage": "Traiter/Éditer l'image", "selectPosition": "Sélectionner la position", "startPainting": "Commencer à peindre", "stopPainting": "Arrêter de peindre", @@ -11,7 +11,8 @@ "noColorsFound": "❌ Ouvrez la palette de couleurs sur le site et réessayez!", "colorsFound": "✅ {count} couleurs trouvées. Prêt à télécharger.", "loadingImage": "🖼️ Chargement de l'image...", - "imageLoaded": "✅ Image chargée avec {count} pixels valides", + "imageLoaded": "✅ Image chargée avec {count} pixels valides ⚠️ Traitez d'abord l'image via \"Traiter/Éditer l'image\" avant de la placer!", + "imageNeedsProcessing": "L'image nécessite un traitement ⚠️", "imageError": "❌ Erreur lors du chargement de l'image", "selectPositionAlert": "Peignez le premier pixel à l'endroit où vous voulez que l'art commence!", "waitingPosition": "👆 En attente que vous peigniez le pixel de référence...", @@ -151,6 +152,10 @@ "paintTransparentPixelsDescription": "Si activé, les pixels transparents du modèle seront peints", "paintUnavailablePixels": "Peindre les pixels indisponibles", "paintUnavailablePixelsDescription": "Si activé, les couleurs de modèle non disponibles seront peintes avec la couleur disponible la plus proche", + "paintingModeAuto": "Auto", + "paintingModeAssist": "Assistance", + "paintingModeAutoDesc": "Le bot peindra automatiquement les pixels", + "paintingModeAssistDesc": "La superposition guidera votre placement manuel de pixels", "colorsUpdated": "✅ Couleurs disponibles augmentées {oldCount} -> {newCount}, {diffCount} nouvelles couleurs trouvées", "overlayTilesNotLoaded": "❌ Tuiles de carte requises non chargées. Vérifiez la connexion ou réessayez.", "paintingBatchFailed": "❌ Échec de l'envoi du lot après plusieurs tentatives. Peinture arrêtée.", diff --git a/Extension/lang/id.json b/Extension/lang/id.json index b4f8bc7..7cfde44 100644 --- a/Extension/lang/id.json +++ b/Extension/lang/id.json @@ -3,7 +3,7 @@ "toggleOverlay": "Toggle Overlay", "scanColors": "Pindai Warna", "uploadImage": "Unggah Gambar", - "resizeImage": "Ubah Ukuran Gambar", + "resizeImage": "Proses/Edit Gambar", "selectPosition": "Pilih Posisi", "startPainting": "Mulai Melukis", "stopPainting": "Berhenti Melukis", @@ -11,7 +11,8 @@ "noColorsFound": "❌ Buka palet warna di situs dan coba lagi!", "colorsFound": "✅ {count} warna ditemukan. Siap untuk diunggah.", "loadingImage": "🖼️ Memuat gambar...", - "imageLoaded": "✅ Gambar dimuat dengan {count} piksel valid", + "imageLoaded": "✅ Gambar dimuat dengan {count} piksel valid ⚠️ Proses gambar terlebih dahulu melalui \"Proses/Edit Gambar\" sebelum menempatkan!", + "imageNeedsProcessing": "Gambar perlu diproses ⚠️", "imageError": "❌ Kesalahan saat memuat gambar", "selectPositionAlert": "Lukis piksel pertama di lokasi tempat karya seni akan dimulai!", "waitingPosition": "👆 Menunggu Anda melukis piksel referensi...", @@ -151,6 +152,10 @@ "paintTransparentPixelsDescription": "Jika diaktifkan, piksel transparan template akan dicat", "paintUnavailablePixels": "Cat piksel tidak tersedia", "paintUnavailablePixelsDescription": "Jika diaktifkan, warna template yang tidak tersedia akan dicat dengan warna tersedia terdekat", + "paintingModeAuto": "Otomatis", + "paintingModeAssist": "Bantu", + "paintingModeAutoDesc": "Bot akan melukis piksel secara otomatis", + "paintingModeAssistDesc": "Overlay akan memandu penempatan piksel manual Anda", "colorsUpdated": "✅ Warna tersedia meningkat {oldCount} -> {newCount}, {diffCount} warna baru ditemukan", "overlayTilesNotLoaded": "❌ Ubin peta yang diperlukan tidak dimuat. Periksa koneksi atau coba lagi.", "paintingBatchFailed": "❌ Gagal mengirim batch setelah beberapa percobaan. Melukis dihentikan.", diff --git a/Extension/lang/ja.json b/Extension/lang/ja.json index f247837..8500d4b 100644 --- a/Extension/lang/ja.json +++ b/Extension/lang/ja.json @@ -3,7 +3,7 @@ "toggleOverlay": "オーバーレイ切替", "scanColors": "色をスキャン", "uploadImage": "画像をアップロード", - "resizeImage": "画像サイズ変更", + "resizeImage": "画像の処理/編集", "selectPosition": "位置を選択", "startPainting": "描画開始", "stopPainting": "描画停止", @@ -11,7 +11,8 @@ "noColorsFound": "❌ サイトでカラーパレットを開いて再試行してください!", "colorsFound": "✅ 利用可能な色 {count} 件を検出。アップロード可能。", "loadingImage": "🖼️ 画像を読み込み中...", - "imageLoaded": "✅ 画像を読み込みました。有効なピクセル {count}", + "imageLoaded": "✅ 画像を読み込みました。有効なピクセル {count} ⚠️ 配置する前に「画像の処理/編集」で画像を処理してください!", + "imageNeedsProcessing": "画像の処理が必要です ⚠️", "imageError": "❌ 画像の読み込みエラー", "selectPositionAlert": "作品を開始したい位置に最初のピクセルを置いてください!", "waitingPosition": "👆 参照ピクセルの描画を待っています...", @@ -151,6 +152,10 @@ "paintTransparentPixelsDescription": "有効にすると、テンプレートの透明ピクセルが描画されます", "paintUnavailablePixels": "利用不可のピクセルを描画", "paintUnavailablePixelsDescription": "有効にすると、利用できないテンプレートの色は最も近い利用可能な色で描画されます", + "paintingModeAuto": "自動", + "paintingModeAssist": "アシスト", + "paintingModeAutoDesc": "ボットが自動的にピクセルを描画します", + "paintingModeAssistDesc": "オーバーレイが手動ピクセル配置をガイドします", "colorsUpdated": "✅ 利用可能な色が増加 {oldCount} -> {newCount}、{diffCount} 個の新しい色が見つかりました", "overlayTilesNotLoaded": "❌ 必要なマップタイルがロードされていません。接続を確認するか、再試行してください。", "paintingBatchFailed": "❌ 複数回の試行後、バッチ送信に失敗しました。描画を停止しました。", diff --git a/Extension/lang/ko.json b/Extension/lang/ko.json index 836b18f..7e083b6 100644 --- a/Extension/lang/ko.json +++ b/Extension/lang/ko.json @@ -3,7 +3,7 @@ "toggleOverlay": "오버레이 전환", "scanColors": "색상 스캔", "uploadImage": "이미지 업로드", - "resizeImage": "크기 조정", + "resizeImage": "이미지 처리/편집", "selectPosition": "위치 선택", "startPainting": "그리기 시작", "stopPainting": "그리기 중지", @@ -11,7 +11,8 @@ "noColorsFound": "❌ 색상 팔레트를 열고 다시 시도하세요!", "colorsFound": "✅ {count}개의 사용 가능한 색상을 찾았습니다. 업로드 준비 완료.", "loadingImage": "🖼️ 이미지 로딩 중...", - "imageLoaded": "✅ {count}개의 유효한 픽셀이 포함된 이미지를 로드했습니다", + "imageLoaded": "✅ {count}개의 유효한 픽셀이 포함된 이미지를 로드했습니다 ⚠️ 배치하기 전에 \"이미지 처리/편집\"을 통해 먼저 이미지를 처리하세요!", + "imageNeedsProcessing": "이미지 처리가 필요합니다 ⚠️", "imageError": "❌ 이미지 로딩 오류", "selectPositionAlert": "작품이 시작될 위치에 첫 번째 픽셀을 그리세요!", "waitingPosition": "👆 참조 픽셀 그릴 때까지 대기 중...", @@ -151,6 +152,10 @@ "paintTransparentPixelsDescription": "활성화하면 템플릿 투명 픽셀이 칠해집니다", "paintUnavailablePixels": "사용 불가능한 픽셀 칠하기", "paintUnavailablePixelsDescription": "활성화하면 사용할 수 없는 템플릿 색상을 가장 가까운 사용 가능한 색상으로 칠합니다", + "paintingModeAuto": "자동", + "paintingModeAssist": "보조", + "paintingModeAutoDesc": "봇이 자동으로 픽셀을 칠합니다", + "paintingModeAssistDesc": "오버레이가 수동 픽셀 배치를 안내합니다", "colorsUpdated": "✅ 사용 가능한 색상 증가 {oldCount} -> {newCount}, {diffCount}개의 새 색상 발견", "overlayTilesNotLoaded": "❌ 필요한 맵 타일이 로드되지 않았습니다. 연결을 확인하거나 다시 시도하세요.", "paintingBatchFailed": "❌ 여러 번 시도 후 배치 전송 실패. 그리기가 중지되었습니다.", diff --git a/Extension/lang/lang/es-MX.json b/Extension/lang/lang/es-MX.json index f702f52..96ba564 100644 --- a/Extension/lang/lang/es-MX.json +++ b/Extension/lang/lang/es-MX.json @@ -3,7 +3,7 @@ "toggleOverlay": "Alternar superposición", "scanColors": "Escanear colores", "uploadImage": "Subir imagen", - "resizeImage": "Cambiar tamaño de imagen", + "resizeImage": "Procesar/Editar imagen", "selectPosition": "Seleccionar posición", "startPainting": "Iniciar pintado", "stopPainting": "Detener pintado", @@ -11,7 +11,8 @@ "noColorsFound": "❌ ¡Abre la paleta de colores en el sitio e inténtalo de nuevo!", "colorsFound": "✅ Se encontraron {count} colores disponibles. Listo para subir.", "loadingImage": "🖼️ Cargando imagen...", - "imageLoaded": "✅ Imagen cargada con {count} píxeles válidos", + "imageLoaded": "✅ Imagen cargada con {count} píxeles válidos ⚠️ ¡Procesa la imagen primero mediante \"Procesar/Editar imagen\" antes de colocarla!", + "imageNeedsProcessing": "La imagen necesita procesamiento ⚠️", "imageError": "❌ Error al cargar la imagen", "selectPositionAlert": "¡Pinta el primer píxel en la ubicación donde quieres que comience el arte!", "waitingPosition": "👆 Esperando que pintes el píxel de referencia...", @@ -140,5 +141,13 @@ "hideStats": "Ocultar estadísticas", "paintOptions": "Opciones de pintado", "paintWhitePixels": "Pintar píxeles blancos", - "paintTransparentPixels": "Pintar píxeles transparentes" + "paintWhitePixelsDescription": "Si está activado, se pintarán los píxeles blancos de la plantilla.", + "paintTransparentPixels": "Pintar píxeles transparentes", + "paintTransparentPixelsDescription": "Si está activado, se pintarán los píxeles transparentes de la plantilla", + "paintUnavailablePixels": "Pintar píxeles no disponibles", + "paintUnavailablePixelsDescription": "Si está activado, los colores de plantilla no disponibles se pintarán usando el color disponible más cercano", + "paintingModeAuto": "Automático", + "paintingModeAssist": "Asistir", + "paintingModeAutoDesc": "El bot pintará píxeles automáticamente", + "paintingModeAssistDesc": "La superposición guiará tu colocación manual de píxeles" } diff --git a/Extension/lang/pt.json b/Extension/lang/pt.json index ed6bcb2..253774c 100644 --- a/Extension/lang/pt.json +++ b/Extension/lang/pt.json @@ -3,7 +3,7 @@ "toggleOverlay": "Toggle Overlay", "scanColors": "Escanear Cores", "uploadImage": "Upload da Imagem", - "resizeImage": "Redimensionar Imagem", + "resizeImage": "Processar/Editar Imagem", "selectPosition": "Selecionar Posição", "startPainting": "Iniciar Pintura", "stopPainting": "Parar Pintura", @@ -11,7 +11,8 @@ "noColorsFound": "❌ Abra a paleta de cores no site e tente novamente!", "colorsFound": "✅ {count} cores encontradas. Pronto para upload.", "loadingImage": "🖼️ Carregando imagem...", - "imageLoaded": "✅ Imagem carregada com {count} pixels válidos", + "imageLoaded": "✅ Imagem carregada com {count} pixels válidos ⚠️ Processe a imagem primeiro via \"Processar/Editar Imagem\" antes de colocar!", + "imageNeedsProcessing": "A imagem precisa de processamento ⚠️", "imageError": "❌ Erro ao carregar imagem", "selectPositionAlert": "Pinte o primeiro pixel на localização onde deseja que a arte comece!", "waitingPosition": "👆 Aguardando você pintar o pixel de referência...", @@ -150,6 +151,10 @@ "paintTransparentPixelsDescription": "Se ativado, pixels transparentes do modelo serão pintados", "paintUnavailablePixels": "Pintar pixels indisponíveis", "paintUnavailablePixelsDescription": "Se ativado, cores de modelo indisponíveis serão pintadas usando a cor disponível mais próxima", + "paintingModeAuto": "Automático", + "paintingModeAssist": "Assistir", + "paintingModeAutoDesc": "Bot pintará pixels automaticamente", + "paintingModeAssistDesc": "Sobreposição guiará sua colocação manual de pixels", "colorsUpdated": "✅ Cores disponíveis aumentadas {oldCount} -> {newCount}, {diffCount} novas cores encontradas", "overlayTilesNotLoaded": "❌ Blocos de mapa necessários não carregados. Verifique a conexão ou tente novamente.", "paintingBatchFailed": "❌ Falha ao enviar lote após várias tentativas. Pintura interrompida.", diff --git a/Extension/lang/ru.json b/Extension/lang/ru.json index c1d81c2..1bba518 100644 --- a/Extension/lang/ru.json +++ b/Extension/lang/ru.json @@ -3,7 +3,7 @@ "toggleOverlay": "Toggle Overlay", "scanColors": "Сканировать цвета", "uploadImage": "Загрузить изображение", - "resizeImage": "Изменить размер изображения", + "resizeImage": "Обработать/Редактировать изображение", "selectPosition": "Выбрать позицию", "startPainting": "Начать рисование", "stopPainting": "Остановить рисование", @@ -11,7 +11,8 @@ "noColorsFound": "❌ Откройте палитру цветов на сайте и попробуйте снова!", "colorsFound": "✅ Найдено доступных цветов: {count}. Готово к загрузке.", "loadingImage": "🖼️ Загрузка изображения...", - "imageLoaded": "✅ Изображение загружено, валидных пикселей: {count}", + "imageLoaded": "✅ Изображение загружено, валидных пикселей: {count} ⚠️ Сначала обработайте изображение через \"Обработать/Редактировать изображение\" перед размещением!", + "imageNeedsProcessing": "Изображение требует обработки ⚠️", "imageError": "❌ Ошибка при загрузке изображения", "selectPositionAlert": "Нарисуйте первый пиксель в месте, откуда начнётся рисунок!", "waitingPosition": "👆 Ожидание, пока вы нарисуете опорный пиксель...", @@ -150,6 +151,10 @@ "paintTransparentPixelsDescription": "Если включено, прозрачные пиксели шаблона будут рисоваться", "paintUnavailablePixels": "Рисовать недоступные пиксели", "paintUnavailablePixelsDescription": "Если включено, недоступные цвета шаблона будут рисоваться ближайшим доступным цветом", + "paintingModeAuto": "Авто", + "paintingModeAssist": "Помощь", + "paintingModeAutoDesc": "Бот будет автоматически рисовать пиксели", + "paintingModeAssistDesc": "Оверлей будет направлять вашу ручную расстановку пикселей", "colorsUpdated": "✅ Доступные цвета увеличены {oldCount} -> {newCount}, найдено {diffCount} новых цветов", "overlayTilesNotLoaded": "❌ Необходимые тайлы карты не загружены. Проверьте соединение или попробуйте снова.", "paintingBatchFailed": "❌ Не удалось отправить пакет после нескольких попыток. Рисование остановлено.", diff --git a/Extension/lang/tr.json b/Extension/lang/tr.json index dc990e4..e4e038b 100644 --- a/Extension/lang/tr.json +++ b/Extension/lang/tr.json @@ -3,7 +3,7 @@ "toggleOverlay": "Katmanı Aç/Kapat", "scanColors": "Renkleri Tara", "uploadImage": "Resim Yükle", - "resizeImage": "Resmi Yeniden Boyutlandır", + "resizeImage": "Resmi İşle/Düzenle", "selectPosition": "Konum Seç", "startPainting": "Boyamayı Başlat", "stopPainting": "Boyamayı Durdur", @@ -11,7 +11,8 @@ "noColorsFound": "❌ Sitede renk paletini açın ve tekrar deneyin!", "colorsFound": "✅ {count} uygun renk bulundu. Yüklemeye hazır.", "loadingImage": "🖼️ Resim yükleniyor...", - "imageLoaded": "✅ Resim {count} geçerli piksel ile yüklendi", + "imageLoaded": "✅ Resim {count} geçerli piksel ile yüklendi ⚠️ Yerleştirmeden önce \"Resmi İşle/Düzenle\" yoluyla resmi işleyin!", + "imageNeedsProcessing": "Resim işleme gerektirir ⚠️", "imageError": "❌ Resim yüklenirken hata oluştu", "selectPositionAlert": "Sanatı başlatmak istediğiniz ilk pikseli boyayın!", "waitingPosition": "👆 Referans pikseli boyamanız bekleniyor...", @@ -151,6 +152,10 @@ "paintTransparentPixelsDescription": "Etkinleştirilirse, şablon şeffaf pikselleri boyanacaktır", "paintUnavailablePixels": "Kullanılamayan pikselleri boya", "paintUnavailablePixelsDescription": "Etkinleştirilirse, kullanılamayan şablon renkleri en yakın uygun renkle boyanacaktır", + "paintingModeAuto": "Otomatik", + "paintingModeAssist": "Yardımcı", + "paintingModeAutoDesc": "Bot pikselleri otomatik olarak boyayacak", + "paintingModeAssistDesc": "Katman, manuel piksel yerleştirmenizi yönlendirecek", "colorsUpdated": "✅ Uygun renkler arttı {oldCount} -> {newCount}, {diffCount} yeni renk bulundu", "overlayTilesNotLoaded": "❌ Gerekli harita karoları yüklenmedi. Bağlantıyı kontrol edin veya yeniden deneyin.", "paintingBatchFailed": "❌ Toplu gönderim birkaç denemeden sonra başarısız oldu. Boyama durduruldu.", diff --git a/Extension/lang/uk.json b/Extension/lang/uk.json index 17e1aa1..71338bd 100644 --- a/Extension/lang/uk.json +++ b/Extension/lang/uk.json @@ -3,7 +3,7 @@ "toggleOverlay": "Перемкнути оверлей", "scanColors": "Сканувати кольори", "uploadImage": "Завантажити зображення", - "resizeImage": "Змінити розмір зображення", + "resizeImage": "Обробити/Редагувати зображення", "selectPosition": "Вибрати позицію", "startPainting": "Почати малювання", "stopPainting": "Зупинити малювання", @@ -11,7 +11,8 @@ "noColorsFound": "❌ Відкрий палітру кольорів на сайті та спробуй ще раз!", "colorsFound": "✅ Знайдено {count} доступних кольорів. Готово до завантаження.", "loadingImage": "🖼️ Завантаження зображення...", - "imageLoaded": "✅ Зображення завантажено. Валідних пікселів: {count}", + "imageLoaded": "✅ Зображення завантажено. Валідних пікселів: {count} ⚠️ Спочатку обробіть зображення через \"Обробити/Редагувати зображення\" перед розміщенням!", + "imageNeedsProcessing": "Зображення потребує обробки ⚠️", "imageError": "❌ Помилка завантаження зображення", "selectPositionAlert": "Намалюй перший піксель у місці, де має починатися арт!", "waitingPosition": "👆 Очікування на малювання референсного пікселя...", @@ -151,6 +152,10 @@ "paintTransparentPixelsDescription": "Якщо ввімкнено, прозорі пікселі шаблону будуть намальовані", "paintUnavailablePixels": "Малювати недоступні пікселі", "paintUnavailablePixelsDescription": "Якщо ввімкнено, недоступні кольори шаблону будуть намальовані найближчим доступним кольором", + "paintingModeAuto": "Авто", + "paintingModeAssist": "Допомога", + "paintingModeAutoDesc": "Бот буде автоматично малювати пікселі", + "paintingModeAssistDesc": "Оверлей буде направляти ваше ручне розташування пікселів", "colorsUpdated": "✅ Доступні кольори збільшено {oldCount} -> {newCount}, знайдено {diffCount} нових кольорів", "overlayTilesNotLoaded": "❌ Необхідні тайли карти не завантажені. Перевір з'єднання або спробуй знову.", "paintingBatchFailed": "❌ Не вдалося відправити пакет після кількох спроб. Малювання зупинено.", diff --git a/Extension/lang/vi.json b/Extension/lang/vi.json index d4c964a..d477249 100644 --- a/Extension/lang/vi.json +++ b/Extension/lang/vi.json @@ -3,7 +3,7 @@ "toggleOverlay": "Bật/tắt lớp phủ", "scanColors": "Quét màu", "uploadImage": "Tải lên hình ảnh", - "resizeImage": "Thay đổi kích thước", + "resizeImage": "Xử lý/Chỉnh sửa hình ảnh", "selectPosition": "Chọn vị trí", "startPainting": "Bắt đầu vẽ", "stopPainting": "Dừng vẽ", @@ -11,7 +11,8 @@ "noColorsFound": "❌ Hãy mở bảng màu trên trang web và thử lại!", "colorsFound": "✅ Tìm thấy {count} màu. Sẵn sàng để tải lên.", "loadingImage": "🖼️ Đang tải hình ảnh...", - "imageLoaded": "✅ Đã tải hình ảnh với {count} pixel hợp lệ", + "imageLoaded": "✅ Đã tải hình ảnh với {count} pixel hợp lệ ⚠️ Xử lý hình ảnh trước qua \"Xử lý/Chỉnh sửa hình ảnh\" trước khi đặt!", + "imageNeedsProcessing": "Hình ảnh cần xử lý ⚠️", "imageError": "❌ Lỗi khi tải hình ảnh", "selectPositionAlert": "Vẽ pixel đầu tiên tại vị trí bạn muốn tác phẩm nghệ thuật bắt đầu!", "waitingPosition": "👆 Đang chờ bạn vẽ pixel tham chiếu...", @@ -151,6 +152,10 @@ "paintTransparentPixelsDescription": "Nếu được bật, các pixel trong suốt của mẫu sẽ được vẽ", "paintUnavailablePixels": "Vẽ pixel không khả dụng", "paintUnavailablePixelsDescription": "Nếu được bật, màu mẫu không khả dụng sẽ được vẽ bằng màu khả dụng gần nhất", + "paintingModeAuto": "Tự động", + "paintingModeAssist": "Trợ giúp", + "paintingModeAutoDesc": "Bot sẽ tự động vẽ pixel", + "paintingModeAssistDesc": "Lớp phủ sẽ hướng dẫn việc đặt pixel thủ công của bạn", "colorsUpdated": "✅ Màu khả dụng tăng {oldCount} -> {newCount}, tìm thấy {diffCount} màu mới", "overlayTilesNotLoaded": "❌ Ô bản đồ cần thiết chưa được tải. Kiểm tra kết nối hoặc thử lại.", "paintingBatchFailed": "❌ Gửi lô thất bại sau nhiều lần thử. Dừng vẽ.", diff --git a/Extension/lang/zh-CN.json b/Extension/lang/zh-CN.json index ef67cd7..c0ae5da 100644 --- a/Extension/lang/zh-CN.json +++ b/Extension/lang/zh-CN.json @@ -3,7 +3,7 @@ "toggleOverlay": "切换覆盖层", "scanColors": "扫描颜色", "uploadImage": "上传图像", - "resizeImage": "调整大小", + "resizeImage": "处理/编辑图像", "selectPosition": "选择位置", "startPainting": "开始绘制", "stopPainting": "停止绘制", @@ -11,7 +11,8 @@ "noColorsFound": "❌ 请在网站上打开调色板后再试!", "colorsFound": "✅ 找到 {count} 个可用颜色,准备上传。", "loadingImage": "🖼️ 正在加载图像...", - "imageLoaded": "✅ 图像已加载,包含 {count} 个有效像素", + "imageLoaded": "✅ 图像已加载,包含 {count} 个有效像素 ⚠️ 放置前请先通过\"处理/编辑图像\"处理图像!", + "imageNeedsProcessing": "图像需要处理 ⚠️", "imageError": "❌ 加载图像时出错", "selectPositionAlert": "请在你想让作品开始的位置绘制第一个像素!", "waitingPosition": "👆 正在等待你绘制参考像素...", @@ -151,6 +152,10 @@ "paintTransparentPixelsDescription": "如果启用,将绘制模板透明像素", "paintUnavailablePixels": "绘制不可用像素", "paintUnavailablePixelsDescription": "如果启用,不可用的模板颜色将使用最接近的可用颜色绘制", + "paintingModeAuto": "自动", + "paintingModeAssist": "辅助", + "paintingModeAutoDesc": "机器人将自动绘制像素", + "paintingModeAssistDesc": "叠加层将引导您手动放置像素", "colorsUpdated": "✅ 可用颜色增加 {oldCount} -> {newCount},找到 {diffCount} 个新颜色", "overlayTilesNotLoaded": "❌ 所需的地图图块未加载。检查连接或重试。", "paintingBatchFailed": "❌ 多次尝试后批量发送失败。绘制已停止。", diff --git a/Extension/lang/zh-TW.json b/Extension/lang/zh-TW.json index bbb8792..7dfad9d 100644 --- a/Extension/lang/zh-TW.json +++ b/Extension/lang/zh-TW.json @@ -3,7 +3,7 @@ "toggleOverlay": "切換覆蓋層", "scanColors": "掃描顏色", "uploadImage": "上傳圖像", - "resizeImage": "調整大小", + "resizeImage": "處理/編輯圖像", "selectPosition": "選擇位置", "startPainting": "開始繪製", "stopPainting": "停止繪製", @@ -11,7 +11,8 @@ "noColorsFound": "❌ 請在網站上打開調色板後再試!", "colorsFound": "✅ 找到 {count} 個可用顏色,準備上傳。", "loadingImage": "🖼️ 正在載入圖像...", - "imageLoaded": "✅ 圖像已載入,包含 {count} 個有效像素", + "imageLoaded": "✅ 圖像已載入,包含 {count} 個有效像素 ⚠️ 放置前請先透過\"處理/編輯圖像\"處理圖像!", + "imageNeedsProcessing": "圖像需要處理 ⚠️", "imageError": "❌ 載入圖像時出錯", "selectPositionAlert": "請在你想讓作品開始的位置繪製第一個像素!", "waitingPosition": "👆 正在等待你繪製參考像素...", @@ -151,6 +152,10 @@ "paintTransparentPixelsDescription": "如果啟用,將繪製範本透明像素", "paintUnavailablePixels": "繪製不可用像素", "paintUnavailablePixelsDescription": "如果啟用,不可用的範本顏色將使用最接近的可用顏色繪製", + "paintingModeAuto": "自動", + "paintingModeAssist": "輔助", + "paintingModeAutoDesc": "機器人將自動繪製像素", + "paintingModeAssistDesc": "疊加層將引導您手動放置像素", "colorsUpdated": "✅ 可用顏色增加 {oldCount} -> {newCount},找到 {diffCount} 個新顏色", "overlayTilesNotLoaded": "❌ 所需的地圖圖塊未載入。檢查連線或重試。", "paintingBatchFailed": "❌ 多次嘗試後批次傳送失敗。繪製已停止。", diff --git a/Extension/manifest.json b/Extension/manifest.json index 3d9a0f4..ffc9443 100644 --- a/Extension/manifest.json +++ b/Extension/manifest.json @@ -1,7 +1,7 @@ { "manifest_version": 3, "name": "WPlace AutoBOT Script Launcher", - "version": "2.0.6", + "version": "2.0.7", "description": "Launch and manage automation scripts for WPlace", "icons": { "16": "icons/icon16.png", diff --git a/Extension/popup/popup.html b/Extension/popup/popup.html index b36c0d0..5885de6 100644 --- a/Extension/popup/popup.html +++ b/Extension/popup/popup.html @@ -113,7 +113,7 @@ diff --git a/Extension/popup/popup.js b/Extension/popup/popup.js index 13e32b8..da51066 100644 --- a/Extension/popup/popup.js +++ b/Extension/popup/popup.js @@ -315,6 +315,17 @@ async function switchToAccount(index) { console.log('✅ Account switched successfully'); + // Auto-refresh the page after account switch + const [tab] = await chrome.tabs.query({ active: true, currentWindow: true }); + if (tab && tab.url.includes('wplace.live')) { + console.log('🔄 Auto-refreshing page after account switch'); + await chrome.tabs.reload(tab.id); + + // Close popup after a short delay + setTimeout(() => { + window.close(); + }, 500); + } } else { throw new Error(response?.error || 'Failed to switch account'); diff --git a/Extension/scripts/Auto-Image.js b/Extension/scripts/Auto-Image.js index 93d5040..3dd47e4 100644 --- a/Extension/scripts/Auto-Image.js +++ b/Extension/scripts/Auto-Image.js @@ -57,8 +57,8 @@ localStorage.removeItem("lp"); }, OVERLAY: { OPACITY_DEFAULT: 0.6, - BLUE_MARBLE_DEFAULT: false, - ditheringEnabled: true, + BLUE_MARBLE_DEFAULT: true, // Enable blue marble effect by default + ditheringEnabled: false, // Default dithering OFF }, // --- START: Color data from colour-converter.js --- // New color structure with proper ID mapping COLOR_MAP: { @@ -692,7 +692,9 @@ localStorage.removeItem("lp"); toggleOverlay: 'Toggle Overlay', scanColors: 'Scan Colors', uploadImage: 'Upload Image', - resizeImage: 'Resize Image', + resizeImage: 'Process/Edit Image', + processImageFirst: '⚠️ Process the image first via "Process/Edit Image" before placing!', + imageNeedsProcessing: 'Image needs processing', selectPosition: 'Select Position', startPainting: 'Start Painting', stopPainting: 'Stop Painting', @@ -1014,6 +1016,7 @@ localStorage.removeItem("lp"); const state = { running: false, imageLoaded: false, + imageProcessed: false, // Track if image has been processed through resize panel processing: false, totalPixels: 0, paintedPixels: 0, @@ -1087,6 +1090,7 @@ localStorage.removeItem("lp"); accountIndex: 0, // Keep for backward compatibility with existing logic // Legacy state removed - now using accountManager instead isFetchingAllAccounts: false, + paintingMode: 'auto', // 'auto' or 'assist' - default to auto }; // Expose state globally for the utils manager and other modules @@ -1173,12 +1177,198 @@ localStorage.removeItem("lp"); } }); + // Helper function to find closest color ID for assist mode + function findClosestColorId(r, g, b) { + let minDistance = Infinity; + let closestColorId = null; + + for (const colorData of Object.values(CONFIG.COLOR_MAP)) { + if (!colorData.rgb) continue; + + const distance = Math.sqrt( + Math.pow(r - colorData.rgb.r, 2) + + Math.pow(g - colorData.rgb.g, 2) + + Math.pow(b - colorData.rgb.b, 2) + ); + + if (distance < minDistance) { + minDistance = distance; + closestColorId = colorData.id; + } + } + + return closestColorId; + } + const originalFetch = window.fetch; // Setup fetch interceptions + console.log('🚀 [Auto-Image] Fetch interception initialized'); + + // Expose state for debugging + window.__WPLACE_AUTOBOT_STATE__ = state; window.fetch = async function (...args) { + let url = args[0] instanceof Request ? args[0].url : args[0]; + + // Parse URL if it's a string + let urlObj = null; + if (typeof url === 'string') { + try { + urlObj = new URL(url); + } catch (e) { + // Invalid URL, proceed normally + } + } + + // ASSIST MODE: Intercept pixel placement requests + if (state.paintingMode === 'assist' && urlObj !== null && urlObj.pathname.startsWith('/s0/pixel')) { + console.log(`🎯 [Assist Mode] Intercepting pixel placement:`, urlObj.pathname); + console.log(`🔍 [Assist Mode] Check state - imageData:`, !!state.imageData, 'startPosition:', !!state.startPosition, 'body:', !!args[1]?.body); + + // Check if we have overlay data + if (state.imageData && state.startPosition && args[1]?.body) { + try { + // Parse region coordinates from URL path: /s0/pixel/{tileX}/{tileY} + const pathParts = urlObj.pathname.split('/'); + const regionX = parseInt(pathParts[3]); + const regionY = parseInt(pathParts[4]); + + console.log(`📦 [Assist Mode] Region coords: (${regionX}, ${regionY})`); + + // Parse request body + const payload = typeof args[1].body === 'string' ? JSON.parse(args[1].body) : args[1].body; + console.log(`📝 [Assist Mode] Original payload:`, JSON.stringify(payload)); + + // Debug: Check what's in state.region + console.log(`🔍 [Assist Mode] state.region:`, state.region); + console.log(`🔍 [Assist Mode] state.startPosition:`, state.startPosition); + + // CRITICAL FIX: The issue is that startPosition is in TILE-LOCAL coordinates (0-999) + // but we're clicking on a tile at (1732, 1014). We need to find which tile + // our image overlay is on by checking all loaded tiles. + + // For now, let's use the REQUEST's tile coordinates as a reference + // If the user is clicking within this tile, check if our LOCAL startPosition + // would overlap with the click position + let startX, startY; + + // COORDINATE RECONSTRUCTION + // state.startPosition = LOCAL coords within a 1000x1000 tile (0-999) + // state.region = TILE coordinates {x, y} (e.g., {x: 1732, y: 1014}) + // Absolute canvas coords = region.x * 1000 + startPosition.x + + if (state.region && state.region.x !== undefined && state.region.y !== undefined) { + // Use saved region to reconstruct absolute coordinates + startX = state.region.x * 1000 + state.startPosition.x; + startY = state.region.y * 1000 + state.startPosition.y; + console.log(`[Assist Mode] Using saved region: tile=(${state.region.x},${state.region.y}) + local=(${state.startPosition.x},${state.startPosition.y}) = absolute (${startX},${startY})`); + } else { + // Fallback: assume image is on the clicked tile (may be wrong!) + // Since startPosition appears to be LOCAL coords within a tile, + // we need to convert them to absolute by finding which tile they're on. + // The simplest approach: assume the image is on the tile being clicked! + startX = regionX * 1000 + state.startPosition.x; + startY = regionY * 1000 + state.startPosition.y; + console.log(`[Assist Mode] No saved region - assuming image on clicked tile (${regionX},${regionY}): absolute = (${startX},${startY})`); + } + console.log(`� [Assist Mode] Assuming image is on clicked tile: absolute coords = (${startX},${startY})`); + + const { width, height } = state.imageData; + + console.log(`🖼️ [Assist Mode] Image bounds: start=(${startX},${startY}), size=${width}x${height}`); + + // Calculate which tiles the image spans + // Note: startX/startY are ABSOLUTE canvas coordinates (e.g., 1732432 means tile 1732, pixel 432) + const imageStartTileX = Math.floor(startX / 1000); + const imageStartTileY = Math.floor(startY / 1000); + const imageEndTileX = Math.floor((startX + width - 1) / 1000); + const imageEndTileY = Math.floor((startY + height - 1) / 1000); + + console.log(`🗺️ [Assist Mode] Image tiles: X[${imageStartTileX}-${imageEndTileX}], Y[${imageStartTileY}-${imageEndTileY}]`); + console.log(`🎯 [Assist Mode] Checking if region (${regionX},${regionY}) overlaps...`); + + if (regionX >= imageStartTileX && regionX <= imageEndTileX && + regionY >= imageStartTileY && regionY <= imageEndTileY) { + + console.log(`✅ [Assist Mode] Region (${regionX},${regionY}) overlaps with image - modifying pixels`); + + // Modify the colors array based on overlay data + if (payload.coords && payload.colors) { + let modifiedCount = 0; + + for (let i = 0; i < payload.coords.length; i += 2) { + // Calculate absolute pixel position + const absoluteX = regionX * 1000 + payload.coords[i]; + const absoluteY = regionY * 1000 + payload.coords[i + 1]; + + // Calculate position relative to our image + const imgX = absoluteX - startX; + const imgY = absoluteY - startY; + + console.log(`🎨 [Assist Mode] Pixel ${i/2}: absolute=(${absoluteX},${absoluteY}), relative=(${imgX},${imgY})`); + + // Check if pixel is within our image bounds + if (imgX >= 0 && imgX < width && imgY >= 0 && imgY < height) { + // Get color from processed image data + // Note: state.imageData uses 'pixels' property, not 'data' + const pixelData = state.imageData.pixels || state.imageData.data; + if (!pixelData) { + console.error(`❌ [Assist Mode] No pixel data available in state.imageData`); + continue; + } + + const pixelIndex = (imgY * width + imgX) * 4; + const r = pixelData[pixelIndex]; + const g = pixelData[pixelIndex + 1]; + const b = pixelData[pixelIndex + 2]; + const a = pixelData[pixelIndex + 3]; + + console.log(`🎨 [Assist Mode] Color at (${imgX},${imgY}): rgba(${r},${g},${b},${a}), original colorId: ${payload.colors[i/2]}`); + + // Skip transparent pixels + if (a < CONFIG.TRANSPARENCY_THRESHOLD) { + console.log(`⏭️ [Assist Mode] Skipping transparent pixel`); + continue; + } + + // Find matching color from palette + const colorId = findClosestColorId(r, g, b); + console.log(`🔍 [Assist Mode] Found closest colorId: ${colorId}`); + if (colorId) { + const oldColorId = payload.colors[i / 2]; + payload.colors[i / 2] = colorId; + console.log(`✏️ [Assist Mode] Changed colorId from ${oldColorId} to ${colorId}`); + modifiedCount++; + } + } else { + console.log(`❌ [Assist Mode] Pixel out of bounds`); + } + } + + // Update request body with modified payload + args[1] = { + ...args[1], + body: JSON.stringify(payload) + }; + + console.log(`✅ [Assist Mode] Modified ${modifiedCount} pixel color(s)`); + console.log(`📝 [Assist Mode] Modified payload:`, JSON.stringify(payload)); + } else { + console.warn(`⚠️ [Assist Mode] Payload missing coords or colors`); + } + } else { + console.log(`⏭️ [Assist Mode] Region (${regionX},${regionY}) does NOT overlap with image`); + } + } catch (error) { + console.error('❌ [Assist Mode] Error intercepting pixel placement:', error); + console.error(error.stack); + } + } else { + console.warn('⚠️ [Assist Mode] No overlay data available - imageData:', !!state.imageData, 'startPosition:', !!state.startPosition); + } + } + const response = await originalFetch.apply(this, args); - const url = args[0] instanceof Request ? args[0].url : args[0]; // TILE REQUEST logging removed to reduce console spam @@ -1304,6 +1494,37 @@ localStorage.removeItem("lp"); } return getText(key, params); }, + + // Open website color palette if not already open + openColorPalette: () => { + try { + // Check if color palette modal is already open + const paletteModal = document.querySelector('dialog[open]'); + if (paletteModal) { + console.log('✅ Color palette already open'); + return true; + } + + // Search for Paint/Pintar button (like Auto-Farm does) + const allButtons = Array.from(document.querySelectorAll('button')); + const paletteButton = allButtons.find(btn => + /(Pintar|Paint)/i.test(btn.textContent.trim()) + ); + + if (paletteButton) { + console.log('🎨 Opening color palette automatically...'); + paletteButton.click(); + return true; + } + + console.warn('⚠️ Color palette button not found'); + return false; + } catch (error) { + console.error('❌ Error opening color palette:', error); + return false; + } + }, + showAlert: (message, type) => { if (window.globalUtilsManager) { window.globalUtilsManager.showAlert(message, type); @@ -2476,12 +2697,19 @@ localStorage.removeItem("lp"); ${Utils.t('stopPainting')} -
-
+