// ==UserScript== // @name FB Auto Report V36.67 (Multi-Language Ultra + HK) // @namespace http://tampermonkey.net/ // @version 36.67 // @description V36.67: Giao diện Đen-Hồng-Xám Bạc. Hỗ trợ đa ngôn ngữ: Anh (US), Nhật, Nepal, Hindi, Pháp, và Hồng Kông (繁體中文). Tối ưu click siêu tốc. // @author Gemini & User // @match https://www.facebook.com/* // @grant none // ==/UserScript== (async () => { 'use strict'; // ========================================== // CẤU HÌNH THỜI GIAN (TỐI ƯU TỐC ĐỘ) // ========================================== const DELAY_TIME = 1500; const INPUT_DELAY = 3000; // Bảng màu giao diện Đen - Hồng - Xám Bạc const PALETTE = { bg: "rgba(20, 20, 20, 0.98)", accent: "#00FF00", silver: "#00FF00", text: "#FFFF00", btnBg: "#00FFFF", btnHover: "#FF0000" }; // ========================================== // TỪ ĐIỂN ĐA NGÔN NGỮ (DICTIONARY FOR BUTTONS) // Đã bổ sung tiếng Trung phồn thể (Hồng Kông) chuẩn Facebook // ========================================== const LANG_DICT = { "Menu (3 chấm)": ["Profile settings see more options", "プロフィール設定", "प्रोफाइल सेटिङहरू", "प्रोफ़ाइल सेटिंग", "Paramètres profil", "個人檔案設定"], "Report profile": ["Report profile", "プロフィールを報告", "प्रोफाइलको रिपोर्ट गर्नुहोस्", "प्रोफ़ाइल की रिपोर्ट करें", "Signaler le profil", "尋求協助 or 檢舉個人檔案", "檢舉個人檔案", "尋求協助或檢舉"], "Something about this profile": ["Something about this profile", "このプロフィールに関する ng", "यस प्रोफाइलको बारेमा केहि", "इस प्रोफ़ाइल के बारे में कुछ", "Quelque chose à propos de ce profil", "與此個人檔案相關的其他問題"], "Fake profile": ["Fake profile", "偽プロフィール", "नक्कली प्रोफाइल", "नकली प्रोफ़ाइल", "Faux profil", "虛假個人檔案"], "They’re not a real person": ["They’re not a real person", "実在の人物ではない", "तिनीहरू वास्तविक व्यक्ति होइनन्", "वे वास्तविक व्यक्ति नहीं हैं", "Ce n’est pas une vraie personne", "這不是真實用戶"], "A celebrity or public figure": ["A celebrity or public figure", "著名人または公人", "एक सेलिब्रेटी वा सार्वजनिक व्यक्तित्व", "कोई सेलिब्रिटी या सार्वजनिक हस्ती", "Une célébrité ou une personnalité publique", "名人或公眾人物"], "Problem involving someone under 18": ["Problem involving someone under 18", "18歳未満の人が関わる問題", "18 वर्ष मुनिका कोही संलग्न समस्या", "18 वर्ष से कम उम्र के किसी व्यक्ति से जुड़ी समस्या", "Problème impliquant un mineur", "涉及未滿 18 歲兒少的問題"], "Physical abuse": ["Physical abuse", "身体的虐待", "शारीरिक दुर्व्यवहार", "शारीरिक शोषण", "Maltraitance physique", "身體虐待"], "Violent, hateful content": ["Violent, hateful or disturbing content", " violent, hateful", "हिंसात्मक, घृणास्पद वा विचलित गर्ने सामग्री", "हिंसक, घृणास्पद या परेशान करने वाली सामग्री", "Contenu violent, haineux ou dérangeant", "暴力、仇恨或令人不安的内容", "暴力、仇恨或令人不安的內容"], "Credible threat to safety": ["Credible threat to safety", "安全に対する現実的な脅威", "सुरक्षाको लागि विश्वसनीय खतरा", "सुरक्षा के लिए गंभीर खतरा", "Menace crédible pour la sécurité", "對安全造成切實威脅"], "Scam, fraud": ["Scam, fraud or false information", "詐欺、不正行為、虚偽の情報", "घोटाला, जालसाजी वा गलत जानकारी", "स्कैम, धोखाधड़ी या गलत जानकारी", "Arnaque, fraude ou fausse information", "詐騙、欺詐或不實訊息", "詐騙、欺詐或不實信息"], "Fraud or scam": ["Fraud or scam", "詐欺または不正行為", "जालसाजी वा घोटाला", "धोखाधड़ी या स्कैम", "Fraude ou arnaque", "欺詐或詐騙"], "Spam": ["Spam", "スパム", "स्पाम", "स्पैम", "Spam", "垃圾訊息", "垃圾信息"], "Something else": ["Something else", "その他", "अरू केही", "कुछ और", "Autre chose", "其他原因"], // Các nút điều hướng hệ thống "Next": ["Next", "Tiếp", "Tiếp tục", "次へ", "अर्को", "आगे बढ़ें", "Suivant", "下一步"], "Submit": ["Submit", "Gửi", "Send", "送信", "पेस गर्नुहोस्", "सबमिट करें", "Envoyer", "提交"], "Done": ["Done", "Xong", "Hoàn tất", "Đóng", "Close", "完了", "भयो", "हो गया", "Terminé", "完成"] }; const INPUT_XPATH = "//*[@aria-label=\"Facebook Page name or URL\" or @aria-label=\"FacebookページのネームまたはURL\" or @aria-label=\"फेसबुक पेजको नाम वा URL\" or @aria-label=\"फेसबुक पेज का नाम या यूआरएल\" or @aria-label=\"Nom de la Page Facebook ou URL\" or @aria-label=\"Facebook 粉絲專頁名稱或網址\"]"; // ========================================== // DANH SÁCH 54 BƯỚC // ========================================== const steps = [ // --- CỤM 1: Fake Profile --- { "step": 1, "name": "Menu (3 chấm)" }, { "step": 2, "name": "Report profile" }, { "step": 3, "name": "Something about this profile" }, { "step": 4, "name": "Fake profile" }, { "step": 5, "name": "They’re not a real person" }, { "step": 6, "name": "Submit" }, { "step": 7, "name": "Next" }, { "step": 8, "name": "Done" }, // --- CỤM 2: Celebrity --- { "step": 9, "name": "Menu (3 chấm)" }, { "step": 10, "name": "Report profile" }, { "step": 11, "name": "Something about this profile" }, { "step": 12, "name": "Fake profile" }, { "step": 13, "name": "A celebrity or public figure" }, { "step": 14, "name": "NHẬP TÊN: Meta", "xpath": INPUT_XPATH, "inputData": "Meta" }, { "step": 15, "name": "Click Chọn Meta", "specialAction": "CLICK_META_RESULT" }, { "step": 16, "name": "Next" }, { "step": 17, "name": "Submit" }, { "step": 18, "name": "Next" }, { "step": 19, "name": "Done" }, // --- CỤM 3: Under 18 --- { "step": 20, "name": "Menu (3 chấm)" }, { "step": 21, "name": "Report profile" }, { "step": 22, "name": "Something about this profile" }, { "step": 23, "name": "Problem involving someone under 18" }, { "step": 24, "name": "Physical abuse" }, { "step": 25, "name": "Submit" }, { "step": 26, "name": "Next" }, { "step": 27, "name": "Done" }, // --- CỤM 4: Violent --- { "step": 28, "name": "Menu (3 chấm)" }, { "step": 29, "name": "Report profile" }, { "step": 30, "name": "Something about this profile" }, { "step": 31, "name": "Violent, hateful content" }, { "step": 32, "name": "Credible threat to safety" }, { "step": 33, "name": "Submit" }, { "step": 34, "name": "Next" }, { "step": 35, "name": "Done" }, // --- CỤM 5: Scam (Fraud) --- { "step": 36, "name": "Menu (3 chấm)" }, { "step": 37, "name": "Report profile" }, { "step": 38, "name": "Something about this profile" }, { "step": 39, "name": "Scam, fraud" }, { "step": 40, "name": "Fraud or scam" }, { "step": 41, "name": "Submit" }, { "step": 42, "name": "Next" }, { "step": 43, "name": "Done" }, // --- CỤM 6: Scam (Spam) --- { "step": 44, "name": "Menu (3 chấm)" }, { "step": 45, "name": "Report profile" }, { "step": 46, "name": "Something about this profile" }, { "step": 47, "name": "Scam, fraud" }, { "step": 48, "name": "Spam" }, { "step": 49, "name": "Done" }, // --- CỤM 7: Something else --- { "step": 50, "name": "Menu (3 chấm)" }, { "step": 51, "name": "Report profile" }, { "step": 52, "name": "Something about this profile" }, { "step": 53, "name": "Something else" }, { "step": 54, "name": "Done" } ]; // ========================================== // OPTIMIZED CORE ENGINE // ========================================== const sleep = ms => new Promise(r => setTimeout(r, ms)); function getElementByXpath(path) { if (!path) return null; return document.evaluate(path, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue; } function safeClick(element) { if (!element) return; let blocker = element.closest('[aria-hidden="true"]'); if (blocker) blocker.removeAttribute('aria-hidden'); element.scrollIntoView({block: "center", inline: "center"}); const opts = { bubbles: true, cancelable: true, view: window }; requestAnimationFrame(() => { element.dispatchEvent(new PointerEvent('pointerdown', opts)); element.dispatchEvent(new MouseEvent('mousedown', opts)); element.focus?.(); element.dispatchEvent(new PointerEvent('pointerup', opts)); element.dispatchEvent(new MouseEvent('mouseup', opts)); element.dispatchEvent(new MouseEvent('click', opts)); }); } async function waitForElementToDisappear(element) { let maxWait = 40; while (maxWait > 0) { if (!element.isConnected || element.offsetParent === null) { return true; } await sleep(50); maxWait--; } return false; } async function waitForGlobalLoading(statusCallback) { let maxWait = 60; let isWaiting = false; while (maxWait > 0) { let loadingIcon = document.querySelector('[role="progressbar"], img[src*="loading"], i[class*="loading"]'); if (loadingIcon && loadingIcon.offsetParent !== null) { isWaiting = true; if(statusCallback) statusCallback("⏳ Loading...", PALETTE.accent); await sleep(50); maxWait--; } else { if(isWaiting) await sleep(200); return; } } } function findMultiLangButton(stepName) { let keywords = LANG_DICT[stepName] || [stepName]; let all = [...document.querySelectorAll('div[role="menuitem"], div[role="button"], button, span, div[role="dialog"] span, div[aria-label], div[tabindex="0"]')]; all = all.filter(el => el.offsetParent !== null && el.offsetWidth > 0); for (let el of all) { let txt = (el.innerText || "").trim().toLowerCase(); let label = (el.getAttribute("aria-label") || "").trim().toLowerCase(); for (let k of keywords) { let lowerK = k.toLowerCase(); if (txt === lowerK || label === lowerK || txt.includes(lowerK) || label.includes(lowerK)) { let parentBtn = el.closest('div[role="button"], button, div[role="menuitem"], div[tabindex="0"]'); return parentBtn ? parentBtn : el; } } } return null; } function simulateInput(element, text) { element.focus(); let lastValue = element.value; element.value = text; let event = new Event('input', { bubbles: true }); let tracker = element._valueTracker; if (tracker) { tracker.setValue(lastValue); } element.dispatchEvent(event); element.dispatchEvent(new Event('change', { bubbles: true })); } async function clickMetaResult(statusEl) { let retry = 10; while (retry > 0) { let options = document.querySelectorAll('div[role="listbox"] span, ul[role="listbox"] span, div[role="presentation"] span'); for (let span of options) { let txt = span.innerText.trim(); if (txt === "Meta") { statusEl.innerText = "Select 'Meta'..."; span.style.border = `2px solid ${PALETTE.accent}`; safeClick(span); return true; } } let imgs = document.querySelectorAll('div[role="listbox"] img'); if (imgs.length > 0) { safeClick(imgs[0]); return true; } statusEl.innerText = `Searching Meta (${retry})`; await sleep(300); retry--; } return false; } // [ANTI-SLEEP LOGIC] let audioLoop = null; let titleInterval = null; const SILENT_AUDIO = 'data:audio/mp3;base64,SUQzBAAAAAAAI1RTU0UAAAAPAAADTGF2ZjU4LjIwLjEwMAAAAAAAAAAAAAAA//OEAAAAAAAAAAAAAAAAAAAAAAAASW5mbwAAAA8AAAAEAAABIADAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMD//////////////////////////////////////////////////////////////////wAAADFMYXZjNTguMzUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUAIAAAAASAA8AxAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//OEAAAAAAAAAAAAAAAAAAAAAAAATGF2YzU4LjM1LjEwMAAAAAAAAAAAAAAA//OEAAAAAAAAAAAAAAAAAAAAAAAATGF2YzU4LjM1LjEwMAAAAAAAAAAAAAAA//OEAAAAAAAAAAAAAAAAAAAAAAAATGF2YzU4LjM1LjEwMAAAAAAAAAAAAAAA//OEAAAAAAAAAAAAAAAAAAAAAAAATGF2YzU4LjM1LjEwMAAAAAAAAAAAAAAA//OEAAAAAAAAAAAAAAAAAAAAAAAATGF2YzU4LjM1LjEwMAAAAAAAAAAAAAAA'; function toggleAntiSleep(enable) { if (enable) { if (!audioLoop) { audioLoop = new Audio(SILENT_AUDIO); audioLoop.loop = true; audioLoop.volume = 0.01; } audioLoop.play().catch(e => console.log("Tab Active Mode Initialized.")); let tick = false; if (titleInterval) clearInterval(titleInterval); titleInterval = setInterval(() => { document.title = tick ? "⚡ ACTIVE..." : "💖 FB Auto Report"; tick = !tick; }, 2000); } else { if (audioLoop) audioLoop.pause(); if (titleInterval) { clearInterval(titleInterval); document.title = "Facebook"; } } } // ========================================== // UI CONTROL (MODERN PINK - BLACK DESIGN) // ========================================== let isPaused = false; let shouldStop = false; let isMini = false; const panel = document.createElement("div"); const getFullStyle = () => ({ position: "fixed", top: "60px", left: "20px", width: "270px", background: PALETTE.bg, color: PALETTE.text, padding: "16px", borderRadius: "12px", zIndex: 999999, border: `1px solid ${PALETTE.accent}`, fontFamily: "'Segoe UI', Roboto, Helvetica, Arial, sans-serif", fontSize: "13px", boxShadow: `0 8px 32px rgba(255, 42, 133, 0.15)`, transition: "all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1)", backdropFilter: "blur(4px)" }); Object.assign(panel.style, getFullStyle()); const renderPanel = () => { if (isMini) { panel.innerHTML = `
💵
Running...
`; panel.style.width = "180px"; panel.style.padding = "8px 12px"; panel.style.border = `1px solid ${PALETTE.accent}`; const bar = panel.querySelector("#miniBar"); const stt = panel.querySelector("#miniStt"); const btnExpand = panel.querySelector("#btnExpand"); btnExpand.onclick = () => { isMini = false; renderPanel(); }; return { bar, stt }; } else { panel.innerHTML = `

🛡️ FB REPORT V12.16

Trạng thái: Sẵn sàng
`; Object.assign(panel.style, getFullStyle()); const btnMinimize = panel.querySelector("#btnMinimize"); btnMinimize.onclick = () => { isMini = true; renderPanel(); }; bindMainEvents(); return { stt: panel.querySelector("#stt"), bar: panel.querySelector("#progressBar") }; } }; document.body.appendChild(panel); renderPanel(); function bindMainEvents() { if(isMini) return; const btnStart = panel.querySelector("#btnStart"); const btnPause = panel.querySelector("#btnPause"); const btnStop = panel.querySelector("#btnStop"); const btnResumeDiv = panel.querySelector("#btnResume"); const btnResume = btnResumeDiv.querySelector("button"); if (btnStart) btnStart.onclick = startProcess; if (btnPause) btnPause.onclick = () => { isPaused = true; updateUIState(); }; if (btnResume) btnResume.onclick = () => { isPaused = false; updateUIState(); }; if (btnStop) btnStop.onclick = () => { if(confirm("Xác nhận DỪNG hoàn toàn?")) { shouldStop = true; isPaused = false; toggleAntiSleep(false); updateStatus("Stopped", "#e0245e"); } }; } function updateUIState() { if(isMini) return; const btnStart = panel.querySelector("#btnStart"); const btnPause = panel.querySelector("#btnPause"); const btnStop = panel.querySelector("#btnStop"); const btnResumeDiv = panel.querySelector("#btnResume"); if (!btnStart) return; if (audioLoop && !audioLoop.paused) { btnStart.style.display = "none"; btnStop.style.display = "block"; if (isPaused) { btnPause.style.display = "none"; btnResumeDiv.style.display = "block"; } else { btnPause.style.display = "block"; btnResumeDiv.style.display = "none"; } } else { btnStart.style.display = "block"; btnPause.style.display = "none"; btnStop.style.display = "none"; btnResumeDiv.style.display = "none"; } } function updateStatus(text, color = PALETTE.text) { if (isMini) { const el = panel.querySelector("#miniStt"); if (el) { el.innerText = text; el.style.color = color; } } else { const el = panel.querySelector("#stt"); if (el) { el.innerText = text; el.style.color = color; } } } function updateProgress(percent) { if (isMini) { const el = panel.querySelector("#miniBar"); if (el) el.style.width = percent + "%"; } else { const el = panel.querySelector("#progressBar"); if (el) el.style.width = percent + "%"; } } // --- MAIN PROCESS --- async function startProcess() { let maxLoops = 1, delayMinutes = 0, useAntiSleep = true; if (!isMini) { maxLoops = parseInt(panel.querySelector("#inpMaxLoop").value) || 1; delayMinutes = parseInt(panel.querySelector("#inpDelayMin").value) || 0; useAntiSleep = panel.querySelector("#chkAntiSleep").checked; } let currentLoop = 0; shouldStop = false; isPaused = false; if (useAntiSleep) toggleAntiSleep(true); updateUIState(); while (currentLoop < maxLoops && !shouldStop) { currentLoop++; console.log(`%c[LOOP] Vòng ${currentLoop}/${maxLoops}`, `color: ${PALETTE.accent}; font-size: 14px; font-weight: bold;`); for (let i = 0; i < steps.length; i++) { if (shouldStop) break; while (isPaused) { await sleep(300); if (shouldStop) break; } let step = steps[i]; updateStatus(`[Loop ${currentLoop}] Step ${step.step}: ${step.name}`, PALETTE.accent); updateProgress((step.step / 54) * 100); if (step.specialAction === "CLICK_META_RESULT") { let dummyStt = { innerText: "" }; let success = await clickMetaResult(dummyStt); updateStatus(dummyStt.innerText || "Selecting Meta...", PALETTE.silver); if (!success) { let inputEl = getElementByXpath(INPUT_XPATH); if(inputEl) inputEl.dispatchEvent(new KeyboardEvent('keydown', {key: 'Enter', keyCode: 13, bubbles: true})); } await waitForGlobalLoading(updateStatus); await sleep(DELAY_TIME); continue; } let el = null; for(let retry=0; retry<8; retry++){ if (shouldStop) break; if (step.xpath) el = getElementByXpath(step.xpath); if (!el) { el = findMultiLangButton(step.name); } if(el) break; await sleep(500); } if (shouldStop) break; if (el) { if (step.inputData) { el.style.border = `2px solid ${PALETTE.accent}`; simulateInput(el, step.inputData); updateStatus("Waiting for list...", PALETTE.silver); await sleep(INPUT_DELAY); } else { el.style.border = `2px solid ${PALETTE.accent}`; safeClick(el); if (step.name === "Next" || step.name === "Submit") { updateStatus("Waiting for hide...", PALETTE.silver); await waitForElementToDisappear(el); } await waitForGlobalLoading(updateStatus); await sleep(DELAY_TIME); } } else { shouldStop = true; console.error(`❌ ERROR: Could not find button "${step.name}"`); updateStatus(`Missing button '${step.name}'`, "#e0245e"); alert(`LỖI TẠI BƯỚC ${step.step}!\nKhông tìm thấy nút (Button not found): ${step.name}`); break; } } if (shouldStop) break; if (currentLoop < maxLoops) { if (delayMinutes > 0) { let secondsLeft = delayMinutes * 60; while (secondsLeft > 0 && !shouldStop) { updateStatus(`Next loop in: ${secondsLeft}s`, "#00FF00"); await sleep(1000); secondsLeft--; } } else await sleep(1000); } } if (!shouldStop) { updateStatus("COMPLETED 🎉", "#00FF00"); updateProgress(100); alert(`Đã hoàn thành xuất sắc ${currentLoop} vòng lặp!`); } toggleAntiSleep(false); updateUIState(); }; })();