// ==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 = `