您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
The ultimate Facebook Marketplace listing deletion machine - now with AI-powered evasion and ninja-like stealth
// ==UserScript== // @name FBMP Listing Manager // @namespace http://tampermonkey.net/ // @version 3.9 // @description The ultimate Facebook Marketplace listing deletion machine - now with AI-powered evasion and ninja-like stealth // @author The Phantom Deleter // @match https://www.facebook.com/marketplace/you/selling?order=* // @grant none // @license MIT // ==/UserScript== console.log("🧪 [FBMP Terminator] Script loaded."); (function() { 'use strict'; // Mission Control Configuration const config = { running: false, cycle: 0, maxCycles: 50, coolDown: 5, stealthMode: true, aiBehavior: "random", // "random", "sold", "unsold", "no_answer" maxFailures: 3, version: "3.9" }; // AI Response Bank const aiResponses = { deletion: [ "Terminating listing with extreme prejudice", "Making listing disappear like magic", "Sending listing to the shadow realm", "Executing order 66 on this listing" ], failure: [ "Target evaded deletion!", "The listing fought back!", "Mission failed, we'll get 'em next time", "Facebook countermeasures detected!" ], waiting: [ "Maintaining operational security", "Hiding from Facebook's watchful eyes", "Simulating human browsing patterns", "Calculating next move..." ] }; // Stealth Operations function getRandomDelay() { return config.stealthMode ? 1000 + Math.random() * 2000 : // Random delay between 1-5s in stealth mode 500 + Math.random() * 700; // Faster operation when stealth is off } function getAIResponse(type) { const responses = aiResponses[type]; return responses[Math.floor(Math.random() * responses.length)]; } // Tactical UI Elements function createTerminatorUI() { const panel = document.createElement('div'); panel.id = 'terminator-panel'; panel.style.cssText = ` position: fixed; bottom: 10px; left: 10px; z-index: 9999; padding: 15px; background: linear-gradient(135deg, #1a1a1a 0%, #000 100%); border-radius: 10px; color: #ffffff; font-family: 'Courier New', monospace; font-size: 13px; border: 1px solid #00ff00; box-shadow: 0 0 15px rgba(0, 255, 0, 0.3); `; panel.innerHTML = ` <h3 style="margin-top:0;border-bottom:1px solid #fff;padding-bottom:5px;color:#fff;text-align: center;"> Listing Manager v${config.version} </h3> <div style="margin-bottom:10px;"> <label style="color:#fff;">Listing yang dihapus: <input type="number" id="maxCycles" value="${config.maxCycles}" style="width:60px;background:#111;color:#0f0;border:1px solid #333;"></label><br> <label style="color:#fff;">Cool Down: <input type="number" id="coolDown" value="${config.coolDown}" style="width:60px;background:#111;color:#0f0;border:1px solid #333;">s</label><br> <label style="display:block;margin-top:5px;color:#fff;"> <input type="checkbox" id="stealthMode" ${config.stealthMode ? 'checked' : ''}> Stealth Mode </label> <select id="aiBehavior" style="margin-top:5px;background:#111;color:#0f0;border:1px solid #333;width:100%"> <option value="random">Random Behavior</option> <option value="sold">Mark as Sold</option> <option value="unsold">Mark as Unsold</option> <option value="no_answer">No Answer</option> </select> <select id="operationMode" style="margin-top:5px;background:#111;color:#0f0;border:1px solid #333;width:100%"> <option value="terminator">TERMINATOR MODE</option> <option value="update">UPDATE MODE</option> <option value="repost">REPOST MODE</option> </select> </div> <button id="toggleButton" style="background:linear-gradient(180deg, #00cc00 0%, #009900 100%);border:none;color:white;padding:5px 10px;border-radius:3px;cursor:pointer;font-weight:bold;"> ▶ START </button> <div style="margin-top:10px;font-size:12px;"> Status: <span id="statusIndicator" style="color:#ff0;">STANDBY</span> </div> <textarea id="terminator-log" rows="10" cols="35" readonly style="width:100%;resize:none;background:#111;color:#fff;border:1px solid #333;margin-top:10px;font-family:monospace;"></textarea> `; const style = document.createElement('style'); style.textContent = ` @keyframes pulse { 0% { transform: scale(1); } 50% { transform: scale(0.98); } 100% { transform: scale(1); } } `; document.body.appendChild(panel); document.getElementById('toggleButton').addEventListener('click', () => { config.running = !config.running; const status = document.getElementById('statusIndicator'); const button = document.getElementById('toggleButton'); if (config.running) { button.innerHTML = '⏹ HENTIKAN'; button.style.background = 'linear-gradient(180deg, #ff3300 0%, #cc0000 100%)'; status.textContent = 'ACTIVE'; status.style.color = '#0f0'; log('DIAKTIFKAN ULANG'); const mode = document.getElementById('operationMode').value; log(`MODE: ${mode.toUpperCase()}`); if (mode === 'terminator') { startTerminationSequence(); } else if (mode === 'repost') { startRepostSequence(); // ← pastikan kamu membuat fungsi ini }else if (mode === 'update') { startUpdateSequence(); // ← pastikan kamu membuat fungsi ini } }else { button.innerHTML = '▶ START'; button.style.background = 'linear-gradient(180deg, #00cc00 0%, #009900 100%)'; status.textContent = 'STANDBY'; status.style.color = '#ff0'; log('SCRIPT DIJEDA'); } }); document.getElementById('stealthMode').addEventListener('change', (e) => { config.stealthMode = e.target.checked; log(`STEALTH MODE ${config.stealthMode ? 'ENABLED' : 'DISABLED'}`); }); document.getElementById('aiBehavior').addEventListener('change', (e) => { config.aiBehavior = e.target.value; log(`AI BEHAVIOR SET TO: ${e.target.value.toUpperCase()}`); }); // Perbarui coolDown secara langsung saat input berubah document.getElementById('coolDown').addEventListener('input', (e) => { const val = parseInt(e.target.value); if (!isNaN(val) && val > 0) { config.coolDown = val; log(`⏳ CoolDown diubah menjadi: ${val} detik`); } }); } // Mission Logging System function log(message) { const logBox = document.getElementById('terminator-log'); if (logBox) { const timestamp = new Date().toLocaleTimeString(); logBox.value += `[${timestamp}] ${message}\n`; logBox.scrollTop = logBox.scrollHeight; } } async function sleep(ms) { for (let i = 0; i < ms; i += 200) { if (!config.running) throw new Error("TERMINATED"); await new Promise(resolve => setTimeout(resolve, 200)); } } // Tactical Element Location function isVisible(elem) { return !!(elem && (elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length)); } function humanLikeClick(elem) { if (!elem) return false; const rect = elem.getBoundingClientRect(); const x = rect.left + rect.width / 2; const y = rect.top + rect.height / 2; const options = { bubbles: true, cancelable: true, composed: true, clientX: x, clientY: y, pointerType: 'mouse' }; elem.dispatchEvent(new PointerEvent('pointerdown', options)); elem.dispatchEvent(new PointerEvent('pointerup', options)); elem.dispatchEvent(new PointerEvent('click', options)); return true; } // ====== START OF startTerminationSequence() ====== // async function startTerminationSequence() { try { config.maxCycles = parseInt(document.getElementById("maxCycles").value) || 50; config.coolDown = parseInt(document.getElementById("coolDown").value) || 5; log("Cooldown dari input:", config.coolDown); log(`Memulai Urutan Penghapusan - ${config.maxCycles} TARGETS`); log(`STRATEGY: ${config.aiBehavior.toUpperCase()} | STEALTH: ${config.stealthMode ? 'ON' : 'OFF'}`); // Beralih ke Tampilan Daftar (List View) const listButton = [...document.querySelectorAll('div[aria-label="Tampilan Daftar"]')].find(isVisible); if (listButton && listButton.getAttribute('aria-pressed') === 'false') { humanLikeClick(listButton); log("📃 Beralih ke Tampilan Daftar..."); await sleep(1000); } let consecutiveFailures = 0; for (config.cycle = 1; config.cycle <= config.maxCycles; config.cycle++) { if (!config.running) break; log(`MISSION ${config.cycle} OF ${config.maxCycles}`); // Phase 1: Engage ellipsis if (!await engageEllipsis()) { consecutiveFailures++; log(`WARNING: TARGET MENGHINDAR (${consecutiveFailures}/${config.maxFailures})`); if (consecutiveFailures >= config.maxFailures) { log("CRITICAL FAILURE - MEMULAI PENGELAKAN"); window.location.href = "/marketplace/you/selling"; return; } continue; } else { consecutiveFailures = 0; } await sleep(500); // Phase 2: Engage deletion if (!await engageElement("Hapus tawaran")) { log("DIHENTIKAN - TARGET TERTUTUP"); continue; } await sleep(500); // Phase 3: Confirm deletion if (!await engageDeleteConfirmation("Hapus")) { log("KONFIRMASI GAGAL - MUNGKIN MASIH AKTIF"); continue; } // Phase 4: AI Reason Step (conditional) await sleep(300); const reasonExists = Array.from(document.querySelectorAll('span')) .some(span => ["Ya, terjual di Facebook", "Ya, terjual di tempat lain", "Tidak, belum terjual", "Memilih tidak menjawab"] .includes(span.textContent.trim())); if (reasonExists) { const responseText = getStrategicResponse(); await engageElement(responseText); await engageElement("Berikutnya"); } else { const nextBtn = Array.from(document.querySelectorAll('span')) .find(span => span.textContent.trim() === "Berikutnya" && isVisible(span)); if (nextBtn) { executeClick(nextBtn); log("KONFIRMASI : TERHAPUS"); await sleep(getRandomDelay()); } else { log("⚠️ Tidak ada alasan penawaran. Menganggap listing sudah dihapus."); } } await sleep(1000); // Phase 5: AI Response (lagi, jika muncul ulang) const responseText = getStrategicResponse(); if (await engageElement(responseText)) { await engageElement("Berikutnya"); } else { const confirmBtn = Array.from(document.querySelectorAll('span')) .find(span => span.textContent.trim() === "Berikutnya" && isVisible(span)); if (confirmBtn) { executeClick(confirmBtn); log("KONFIRMASI : TERHAPUS"); await sleep(getRandomDelay()); } } // Cool down period const waitingMsg = getAIResponse('waiting'); log(`${waitingMsg} (${config.coolDown} detik)...`); for (let s = 1; s <= config.coolDown; s++) { if (!config.running) { log("🛑 PROSES Dihentikan oleh pengguna."); return; } log(`🕒 ${s}`); await sleep(1000); } } log("PROSES HAPUS BERHASIL"); // log("ALL TARGETS NEUTRALIZED OR MISSION ABORTED"); } catch (e) { if (e.message === "TERMINATED") { log("🛑 PROSES DIHENTIKAN LANGSUNG OLEH PENGGUNA"); } else { log(`❌ ERROR: ${e.message}`); } } } // ====== HELPER FUNCTIONS startTerminationSequence() ====== // function findZeroClickListingButton() { // Temukan semua elemen yang berisi teks "0 klik tawaran" const zeroClickElements = Array.from(document.querySelectorAll("div.x78zum5.x1q0g3np.xg7h5cd")) .filter(el => el.textContent.includes("0 klik tawaran")); for (const el of zeroClickElements) { // Naik ke atas sampai container listing let current = el; for (let i = 0; i < 10; i++) { if (!current) break; if (current.querySelector("div[aria-label^='Opsi lainnya untuk']")) { const ellipsisBtn = current.querySelector("div[aria-label^='Opsi lainnya untuk']"); if (ellipsisBtn) return ellipsisBtn; } current = current.parentElement; } } // Jika tidak ada tombol ⋯ ditemukan dalam listing dengan 0 klik tawaran return null; } // Advanced Click Simulation function executeClick(elem) { if (!elem) return false; const rect = elem.getBoundingClientRect(); const mouseEventInit = { bubbles: true, cancelable: true, view: window, clientX: rect.left + rect.width/2, clientY: rect.top + rect.height/2 }; ['mousedown', 'mouseup', 'click'].forEach(type => { elem.dispatchEvent(new MouseEvent(type, mouseEventInit)); }); return true; } async function engageDeleteConfirmation() { // Cari semua tombol "Hapus" yang terlihat const candidates = Array.from(document.querySelectorAll('div[role="dialog"] span')) .filter(span => span.textContent.trim() === "Hapus" && isVisible(span)); if (candidates.length === 0) { log("❌ Tidak menemukan tombol 'Hapus' di dalam dialog."); return false; } // Ambil yang paling bawah (biasanya tombol konfirmasi biru) const button = candidates[candidates.length - 1]; button.scrollIntoView({ behavior: "smooth", block: "center" }); await sleep(getRandomDelay()); executeClick(button); log(`🧨 Konfirmasi 'Hapus' dieksekusi.`); await sleep(1000); return true; } // Strategic Element Engagement async function engageElement(text, tag = 'span') { const elements = Array.from(document.querySelectorAll(tag)); const lowerText = text.toLowerCase(); const target = elements.find(el => { const match = el.textContent.trim().toLowerCase() === lowerText; const visible = isVisible(el); return match && visible; }); if (target) { target.scrollIntoView({ behavior: "smooth", block: "center" }); await sleep(getRandomDelay()); executeClick(target); log(`${getAIResponse('deletion')}: "${text}"`); await sleep(getRandomDelay()); return true; } else { log(`${getAIResponse('failure')} - Target tidak ditemukan: "${text}"`); return false; } } // Special Ops: Ellipsis Engagement async function engageEllipsis() { const target = findZeroClickListingButton(); if (!target) { log("❌ Tidak ada listing dengan '0 klik tawaran' ditemukan."); return false; } target.scrollIntoView({ behavior: "smooth", block: "center" }); await sleep(1000); executeClick(target); log("🎯 Target '0 klik tawaran' ditemukan dan diserang."); await sleep(getRandomDelay()); return true; } // AI-Powered Response Selection function getStrategicResponse() { switch(config.aiBehavior) { case "sold": return Math.random() > 0.5 ? "Ya, terjual di Facebook" : "Ya, terjual di tempat lain"; case "unsold": return "Tidak, belum terjual"; case "no_answer": return "Memilih tidak menjawab"; default:{ const options = [ "Memilih tidak menjawab", "Ya, terjual di Facebook", "Ya, terjual di tempat lain", "Tidak, belum terjual", ]; return options[Math.floor(Math.random() * options.length)]; } } } // ====== END OF startTerminationSequence() ====== // // ====== START OF startRepostSequence() ====== // async function startRepostSequence() { try { log("🔄 MEMULAI REPOST SEQUENCE - Mencari listing dengan 'Hapus & Tawarkan Ulang'"); // Switch to list view for better scanning if (!(await switchToListViewRepost())) { log("⚠️ Gagal beralih ke tampilan daftar, melanjutkan dengan tampilan saat ini"); } let totalProcessed = 0; let scrollAttempts = 0; const maxScrollAttempts = 50; let consecutiveFails = 0; const maxConsecutiveFails = 5; let lastButtonCount = 0; let sameButtonCountOccurrences = 0; // Initial load wait await sleep(5000); while (scrollAttempts < maxScrollAttempts && consecutiveFails < maxConsecutiveFails) { // Find all unprocessed buttons with fresh scan const allButtons = await comprehensiveButtonScanRepost(); const unprocessedButtons = allButtons.filter(btn => isVisibleRepost(btn) && isClickableRepost(btn) && !btn.hasAttribute('data-processed') ); // Check if we're seeing the same number of buttons repeatedly (possible infinite loop) if (unprocessedButtons.length === lastButtonCount) { sameButtonCountOccurrences++; if (sameButtonCountOccurrences > 3) { log("⚠️ Deteksi kemungkinan infinite loop, melakukan reset..."); sameButtonCountOccurrences = 0; await reloadPage(); continue; } } else { sameButtonCountOccurrences = 0; lastButtonCount = unprocessedButtons.length; } if (unprocessedButtons.length === 0) { log(`ℹ️ Tidak menemukan tombol baru (scroll ${scrollAttempts + 1}/${maxScrollAttempts})`); // Special handling when no buttons found if (totalProcessed === 0 && scrollAttempts > 10) { log("⚠️ Tidak menemukan tombol sama sekali setelah beberapa scroll"); break; } let prevListingCount = await countListingsRepost(); await aggressiveScrollRepost(); await sleep(1000); // beri waktu loading let newListingCount = await countListingsRepost(); if (newListingCount > prevListingCount) { log(`📈 Ditemukan ${newListingCount - prevListingCount} listing baru setelah scroll`); continue; // skip ke atas untuk scan ulang } else { log("📉 Tidak ada listing baru setelah scroll"); } // await aggressiveScrollRepost(); // scrollAttempts++; // consecutiveFails++; // await sleep(4000); // continue; } log(`🔍 Ditemukan ${unprocessedButtons.length} tombol aktif yang belum diproses`); consecutiveFails = 0; // Reset fail counter // Process all unprocessed buttons in this batch for (let i = 0; i < unprocessedButtons.length; i++) { const button = unprocessedButtons[i]; // Verify button still exists and is clickable if (!document.contains(button) || !isClickableRepost(button)) { log("ℹ️ Tombol tidak valid lagi, melanjutkan..."); continue; } const listing = findParentListingRepost(button); if (!listing) { log("⚠️ Tidak dapat menemukan parent listing, menandai tombol sebagai gagal"); button.setAttribute('data-processed', 'failed'); continue; } log(`🔄 Memproses listing ${totalProcessed + 1}`); highlightButtonRepost(button, 'processing'); // More robust clicking with multiple fallbacks const success = await robustButtonClickRepost(button, listing); if (success) { totalProcessed++; highlightButtonRepost(button, 'success'); // More permanent marking of processed buttons button.setAttribute('data-processed', 'true'); button.setAttribute('data-processed-time', Date.now()); log(`✅ Berhasil memproses (Total: ${totalProcessed})`); // After successful processing, check if listing disappeared if (!document.contains(listing)) { log("ℹ️ Listing menghilang setelah diproses"); } } else { highlightButtonRepost(button, 'failed'); button.setAttribute('data-processed', 'failed'); log("⚠️ Gagal memproses tombol ini"); } // Randomized delay between buttons (1-4 seconds) await sleep(1000 + Math.random() * 3000); } await sleep(2000); // Final verification scan const remainingButtons = (await comprehensiveButtonScanRepost()).filter(btn => isVisibleRepost(btn) && isClickableRepost(btn) && !btn.hasAttribute('data-processed') ); if (remainingButtons.length > 0) { log(`ℹ️ Masih ada ${remainingButtons.length} tombol yang belum diproses`); // More aggressive scroll if we still have unprocessed buttons await aggressiveScrollRepost(); scrollAttempts++; await sleep(3000); } else { log("✔️ Semua tombol telah diproses"); break; } } log(`🎉 Selesai! Total tombol berhasil diklik: ${totalProcessed}`); } catch (e) { log(`❌ ERROR: ${e.message}`); console.error(e); } } // ====== HELPER FUNCTIONS startRepostSequence() ====== // async function reloadPage() { log("🔄 Memuat ulang halaman..."); window.scrollTo(0, 0); await sleep(2000); window.location.reload(); } async function robustButtonClickRepost(button, listing) { try { // Double-check button state if (!isVisibleRepost(button) || !isClickableRepost(button)) { return false; } // Store initial state const initialButtonState = isClickableRepost(button); const initialListingExists = document.contains(listing); const initialButtonText = button.textContent; const initialButtonHTML = button.outerHTML; // Scroll to button with offset to account for headers const yOffset = -100; // Adjust for fixed headers const buttonRect = button.getBoundingClientRect(); window.scrollTo({ top: window.scrollY + buttonRect.top + yOffset, behavior: 'smooth' }); await sleep(800); // Try multiple click methods with visual feedback const clickMethods = [ () => { button.style.transform = 'scale(0.98)'; button.click(); }, () => humanLikeClickRepost(button), () => simulateMouseClickRepost(button), () => { const rect = button.getBoundingClientRect(); const clickEvent = new MouseEvent('click', { bubbles: true, cancelable: true, clientX: rect.left + rect.width/2, clientY: rect.top + rect.height/2 }); button.dispatchEvent(clickEvent); } ]; let clickSuccess = false; for (const method of clickMethods) { if (clickSuccess) break; try { method(); await sleep(300 + Math.random() * 700); // Vary delay between attempts // Immediate verification if (verifyClickSuccessRepost(button, listing, initialButtonState, initialListingExists, initialButtonText)) { clickSuccess = true; break; } } catch (e) { console.log(`Click method failed: ${e.message}`); } } // Reset button style button.style.transform = ''; if (!clickSuccess) return false; // Progressive verification with multiple checks const verificationChecks = [ // Immediate check () => verifyClickSuccessRepost(button, listing, initialButtonState, initialListingExists, initialButtonText), // Delayed check async () => { await sleep(1500); return verifyClickSuccessRepost(button, listing, initialButtonState, initialListingExists, initialButtonText); }, // DOM change check () => button.outerHTML !== initialButtonHTML ]; for (const check of verificationChecks) { if (await check()) { return true; } } return false; } catch (e) { log(`⚠️ Click error: ${e.message}`); return false; } } function verifyClickSuccessRepost(button, listing, initialButtonState, initialListingExists, initialButtonText) { return ( (initialButtonState && !isClickableRepost(button)) || (initialListingExists && !document.contains(listing)) || (button.textContent !== initialButtonText) || (window.getComputedStyle(button).opacity < 0.5) || (button.getAttribute('aria-disabled') === 'true') ); } async function aggressiveScrollRepost() { // Scroll further than viewport height to ensure loading const scrollDistance = window.innerHeight * 2; window.scrollBy({ top: scrollDistance, behavior: 'smooth' }); // Additional micro-scrolls to trigger loading await sleep(1000); window.scrollBy(0, 300); await sleep(500); window.scrollBy(0, 100); } async function comprehensiveButtonScanRepost() { const scanMethods = [ () => document.querySelectorAll('div[aria-label="Hapus & Tawarkan Ulang"]'), () => document.querySelectorAll('span:contains("Hapus & Tawarkan Ulang")'), () => { const xpath = "//*[contains(translate(., 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'), 'hapus & tawarkan ulang')]"; const result = document.evaluate(xpath, document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null); const elements = []; for (let i = 0; i < result.snapshotLength; i++) { elements.push(result.snapshotItem(i)); } return elements; }, () => document.querySelectorAll('div.x1i10hfl.xjbqb8w.x6umtig') // Common FB button class ]; const allButtons = new Set(); const now = Date.now(); for (const method of scanMethods) { try { const buttons = method(); for (const btn of buttons) { try { // Skip buttons processed in the last 5 minutes to handle Facebook re-rendering const processedTime = btn.getAttribute('data-processed-time'); if (processedTime && (now - parseInt(processedTime)) < 300000) { continue; } if (btn.textContent && btn.textContent.toLowerCase().includes('hapus') && btn.textContent.toLowerCase().includes('tawarkan ulang')) { allButtons.add(btn); } } catch (e) { console.log('Error processing button:', e); } } } catch (e) { console.log(`Scan method error: ${e.message}`); } } return Array.from(allButtons); } async function xpathFindButtonsRepost() { const buttons = []; const xpathResult = document.evaluate( "//*[contains(text(), 'Hapus & Tawarkan Ulang')]", document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null ); for (let i = 0; i < xpathResult.snapshotLength; i++) { const element = xpathResult.snapshotItem(i); if (isVisibleRepost(element) && isClickableRepost(element)) { buttons.push(element); } } return buttons; } async function scrollToVeryBottomRepost() { const startPosition = window.pageYOffset; window.scrollTo({ top: document.body.scrollHeight, behavior: 'smooth' }); await sleep(3000); // Additional check to ensure we're not stuck if (window.pageYOffset <= startPosition + 500) { log("⚠️ Scroll tidak berpengaruh, mencoba alternatif..."); // Alternative scroll method for (let i = 0; i < 5; i++) { window.scrollBy(0, window.innerHeight * 2); await sleep(1000); } } } function simulateMouseClickRepost(element) { if (!element || !isVisibleRepost(element)) return false; try { const rect = element.getBoundingClientRect(); const mouseEventInit = { bubbles: true, cancelable: true, view: window, clientX: rect.left + rect.width/2, clientY: rect.top + rect.height/2 }; ['mouseover', 'mousedown', 'mouseup', 'click'].forEach(type => { element.dispatchEvent(new MouseEvent(type, mouseEventInit)); }); return true; } catch (e) { console.error('Mouse simulation failed:', e); return false; } } function hasVisualChangeRepost(element) { if (!element) return false; try { // Store current visual properties const currentStyle = window.getComputedStyle(element); const currentProps = { backgroundColor: currentStyle.backgroundColor, borderColor: currentStyle.borderColor, color: currentStyle.color, opacity: currentStyle.opacity }; // Wait briefly for potential changes return new Promise(resolve => { setTimeout(() => { const newStyle = window.getComputedStyle(element); const changed = ( newStyle.backgroundColor !== currentProps.backgroundColor || newStyle.borderColor !== currentProps.borderColor || newStyle.color !== currentProps.color || newStyle.opacity !== currentProps.opacity ); resolve(changed); }, 500); }); } catch (e) { console.error('Visual change check failed:', e); return false; } } async function findRepostButtonsDeepScanRepost() { // Try multiple scanning methods const buttons = []; // Method 1: Standard selector search buttons.push(...await findClickableRepostButtons()); // Method 2: Visual scanning for button text if (buttons.length < 5) { buttons.push(...await visualScanForButtonsRepost()); } // Method 3: XPath search as fallback if (buttons.length < 5) { buttons.push(...await xpathFindButtonsRepost()); } // Filter out duplicates and failed buttons const uniqueButtons = []; const seen = new Set(); for (const button of buttons) { if (!seen.has(button) && isVisibleRepost(button) && isClickableRepost(button) && !button.hasAttribute('data-processed')) { seen.add(button); uniqueButtons.push(button); } } return uniqueButtons; } async function visualScanForButtonsRepost() { const buttons = []; const textNodes = document.evaluate( "//text()[contains(., 'Hapus') and contains(., 'Tawarkan Ulang')]", document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null ); for (let i = 0; i < textNodes.snapshotLength; i++) { const node = textNodes.snapshotItem(i); let element = node.parentElement; // Walk up the DOM to find clickable container while (element && element !== document.body) { if (element.getAttribute('role') === 'button' || element.tagName === 'BUTTON' || element.onclick) { buttons.push(element); break; } element = element.parentElement; } } return buttons.filter(btn => isVisibleRepost(btn) && isClickableRepost(btn)); } async function enhancedClickAndVerifyRepost(button, listing) { try { // Store initial state const initialHtml = listing.innerHTML; const initialButtonText = button.textContent; // Scroll to center the button button.scrollIntoView({ behavior: 'smooth', block: 'center' }); await sleep(800); // Try different click methods const clickMethods = [ () => button.click(), () => humanLikeClickRepost(button), () => simulateMouseClickRepost(button) ]; let clickSuccess = false; for (const method of clickMethods) { try { method(); clickSuccess = true; break; } catch (e) { console.log(`Click method failed: ${e.message}`); } } if (!clickSuccess) return false; // Wait for changes await sleep(2000); // Verification methods const verificationChecks = [ // Button became disabled !isClickableRepost(button), // Listing disappeared !document.contains(listing), // Listing HTML changed significantly listing.innerHTML !== initialHtml, // Button text changed button.textContent !== initialButtonText, // Button visually changed (color, etc) hasVisualChangeRepost(button) ]; return verificationChecks.some(check => check); } catch (e) { log(`⚠️ Verification error: ${e.message}`); return false; } } // Modified smart scroll to be more aggressive when needed async function smartScrollRepost(processedCount, scrollAttempts) { // Base scroll distance let scrollDistance = window.innerHeight * 1.8; // Increased from 1.5 // Increase scroll distance based on progress if (processedCount > 15) scrollDistance *= 1.3; if (scrollAttempts > 8) scrollDistance *= 1.5; // Add random variation scrollDistance *= 0.9 + Math.random() * 0.2; window.scrollBy({ top: scrollDistance, behavior: 'smooth' }); // Additional micro-scrolls with random delays await sleep(800 + Math.random() * 1000); window.scrollBy(0, 200 + Math.random() * 100); await sleep(400 + Math.random() * 500); window.scrollBy(0, 50 + Math.random() * 50); } // Enhanced button highlighting function highlightButtonRepost(button, state) { const colors = { processing: 'hsl(30, 100%, 50%)', // Orange success: 'hsl(120, 100%, 40%)', // Green failed: 'hsl(0, 100%, 45%)' // Red }; button.style.border = `2px solid ${colors[state]}`; button.style.borderRadius = '6px'; button.style.transition = 'all 0.3s ease'; button.style.padding = '2px'; if (state === 'processing') { button.style.boxShadow = '0 0 0 3px rgba(255,165,0,0.3)'; button.style.animation = 'pulse 0.5s 2'; } else { button.style.boxShadow = 'none'; button.style.animation = 'none'; } // Create temporary highlight effect const highlight = document.createElement('div'); highlight.style.position = 'absolute'; highlight.style.backgroundColor = state === 'success' ? 'rgba(76, 175, 80, 0.2)' : state === 'failed' ? 'rgba(244, 67, 54, 0.2)' : 'rgba(255, 165, 0, 0.2)'; highlight.style.borderRadius = 'inherit'; highlight.style.inset = '0'; highlight.style.pointerEvents = 'none'; highlight.style.zIndex = '9999'; button.style.position = 'relative'; button.appendChild(highlight); setTimeout(() => { highlight.style.opacity = '0'; highlight.style.transition = 'opacity 0.5s'; setTimeout(() => { button.removeChild(highlight); button.style.border = ''; button.style.borderRadius = ''; button.style.padding = ''; }, 500); }, 1000); } // ======== ESSENTIAL HELPER FUNCTIONS ======== // async function switchToListViewRepost() { try { const listButton = [...document.querySelectorAll('div[aria-label="Tampilan Daftar"]')] .find(btn => isVisibleRepost(btn) && btn.getAttribute('aria-pressed') === 'false'); if (listButton) { humanLikeClickRepost(listButton); log("📃 Beralih ke Tampilan Daftar..."); await sleep(2000); return true; } return false; } catch (e) { log(`⚠️ Gagal beralih ke tampilan daftar: ${e.message}`); return false; } } async function clickAndVerifyRepost(button, listing) { try { // Scroll to ensure visibility if (listing && listing.scrollIntoView) { listing.scrollIntoView({ behavior: 'auto', block: 'center' }); await sleep(800); } // Store initial state const initialButtonState = isClickableRepost(button); const initialListingExists = document.contains(listing); const initialButtonText = button.textContent; // Perform click let clickSuccess = false; try { if (typeof button.click === 'function') { button.click(); clickSuccess = true; } else if (humanLikeClickRepost(button)) { clickSuccess = true; } else if (executeClickRepost(button)) { clickSuccess = true; } } catch (e) { log(`⚠️ Click error: ${e.message}`); } await sleep(1500); // Verification const isSuccessful = (initialButtonState && !isClickableRepost(button)) || (initialListingExists && !document.contains(listing)) || (initialButtonText !== button.textContent); return clickSuccess && isSuccessful; } catch (e) { log(`⚠️ Verification error: ${e.message}`); return false; } } function isVisibleRepost(elem) { if (!elem) return false; const style = window.getComputedStyle(elem); return style.display !== 'none' && style.visibility !== 'hidden' && elem.offsetWidth > 0 && elem.offsetHeight > 0 && elem.getClientRects().length; } function isClickableRepost(element) { if (!element || !isVisibleRepost(element)) return false; try { const style = window.getComputedStyle(element); return !(style.pointerEvents === 'none' || style.cursor === 'not-allowed' || parseFloat(style.opacity) < 0.6 || element.disabled); } catch (e) { console.log('Error checking clickable:', e); return false; } } // ======== OTHER REQUIRED FUNCTIONS ======== // function humanLikeClickRepost(elem) { if (!elem) return false; const rect = elem.getBoundingClientRect(); const x = rect.left + rect.width/2; const y = rect.top + rect.height/2; const events = [ new MouseEvent('mouseover', { bubbles: true }), new MouseEvent('mousedown', { bubbles: true }), new MouseEvent('mouseup', { bubbles: true }), new MouseEvent('click', { bubbles: true }) ]; events.forEach(evt => { elem.dispatchEvent(evt); }); return true; } function executeClickRepost(elem) { if (!elem) return false; const rect = elem.getBoundingClientRect(); const mouseEventInit = { bubbles: true, cancelable: true, view: window, clientX: rect.left + rect.width/2, clientY: rect.top + rect.height/2 }; ['mousedown', 'mouseup', 'click'].forEach(type => { elem.dispatchEvent(new MouseEvent(type, mouseEventInit)); }); return true; } async function findRepostButtonsWithRetry() { let buttons = []; let attempts = 0; while (attempts < 3 && buttons.length === 0) { buttons = await findClickableRepostButtons(); if (buttons.length > 0) break; attempts++; await sleep(1000); } return buttons; } async function findClickableRepostButtons() { const selectors = [ 'div[aria-label="Hapus & Tawarkan Ulang"]', 'span[dir="auto"]', 'div.x1i10hfl.xjbqb8w.x6umtig' ]; const allButtons = []; for (const selector of selectors) { try { const buttons = Array.from(document.querySelectorAll(selector)) .filter(btn => { if (!isVisibleRepost(btn)) return false; const text = btn.textContent?.trim() || ''; if (!text.includes("Hapus") || !text.includes("Tawarkan Ulang")) return false; return isClickableRepost(btn); }); allButtons.push(...buttons); } catch (e) { console.log(`Selector error: ${e.message}`); } } return [...new Set(allButtons)]; } async function scrollDownRepost() { window.scrollBy({ top: window.innerHeight * 1.5, behavior: 'smooth' }); await sleep(1000); window.scrollBy(0, 100); } async function countListingsRepost() { const selectors = [ '[data-testid="marketplace_your_listing_card"]', 'div.x1lliihq.x1n2onr6.x1jchvi3', 'div[role="article"]' ]; for (const selector of selectors) { const listings = document.querySelectorAll(selector); if (listings.length > 0) return listings.length; } return 0; } function findParentListingRepost(element) { const selectors = [ 'div[data-testid="marketplace_your_listing_card"]', 'div.x1lliihq.x1n2onr6.x1jchvi3', 'div[role="article"]', 'div.x1qjc9v5.x78zum5.x1q0g3np.x1a02dak.x1qughib' ]; for (const selector of selectors) { const parent = element.closest(selector); if (parent) return parent; } return element.closest('div[role="button"]') || element.closest('a[href*="/marketplace/item/"]'); } // ====== END OF startRepostSequence() ====== // // ====== START OF startUpdateSequence() ====== // async function startUpdateSequence() { try { log("🔄 MEMULAI UPDATE MODE - Memindai dan memperbarui listing..."); // Verify correct page if (!window.location.href.includes('/marketplace/you/selling')) { window.location.href = 'https://www.facebook.com/marketplace/you/selling?order=CREATION_TIMESTAMP'; await sleep(3000); return; } // Switch to grid view const gridButton = [...document.querySelectorAll('div[aria-label="Tampilan Kisi"]')].find(isVisibleUpdate); if (gridButton && gridButton.getAttribute('aria-pressed') === 'false') { humanLikeClickUpdate(gridButton); log("Beralih ke Tampilan Kisi..."); await sleep(1000); } let totalProcessed = 0; let scrollAttempts = 0; const maxScrollAttempts = 50; let consecutiveFails = 0; const maxConsecutiveFails = 5; // Main processing loop while (scrollAttempts < maxScrollAttempts && consecutiveFails < maxConsecutiveFails) { // Find listings with tips text const listingsWithTips = await findListingsWithTipsText(); if (listingsWithTips.length === 0) { log(`ℹ️ Tidak menemukan listing dengan tips (scroll ${scrollAttempts + 1}/${maxScrollAttempts})`); if (totalProcessed === 0 && scrollAttempts > 10) { log("⚠️ Tidak menemukan listing dengan tips sama sekali"); break; } await smartScrollUpdate(); scrollAttempts++; consecutiveFails++; await sleep(3000); continue; } log(`🔍 Ditemukan ${listingsWithTips.length} listing dengan tips`); consecutiveFails = 0; // Process each listing for (let i = 0; i < listingsWithTips.length; i++) { const listing = listingsWithTips[i]; log(`🔄 Memproses listing (${totalProcessed + 1}${listingsWithTips.length})`); // log(`🔄 Memproses listing ${totalProcessed + 1}/${listingsWithTips.length}`); try { const success = await processListing(listing); if (success) { totalProcessed++; log(`✅ Berhasil memproses (Total: ${totalProcessed}/${listingsWithTips.length})`); } else { log("⚠️ Gagal memproses listing ini"); } } catch (e) { log(`❌ Error: ${e.message}`); } await sleep(500 + Math.random() * 2000); } await sleep(1000); } log(`🎉 Selesai! Total listing berhasil diperbarui: ${totalProcessed}`); } catch (e) { log(`❌ FATAL ERROR: ${e.message}`); } } // ====== MISSING FUNCTION NOW INCLUDED ====== // async function findListingsWithTipsText() { // Find all elements containing the tips text const tipElements = Array.from(document.querySelectorAll('div')) .filter(div => div.textContent.includes("Tips: Perbarui tawaran Anda?") && isVisibleUpdate(div)); // Get unique parent listings const listings = []; const seen = new Set(); for (const tipElement of tipElements) { const listing = findParentListingUpdate(tipElement); if (listing && !seen.has(listing) && !listing.hasAttribute('data-processed')) { seen.add(listing); listings.push(listing); } } return listings; } async function processListing(listing) { try { // 1. Highlight and scroll to listing highlightListingUpdate(listing, 'processing'); listing.scrollIntoView({ behavior: 'smooth', block: 'center' }); await sleep(1000); // 2. Click to open listing // const listingLink = listing.querySelector('a[href*="/marketplace/item/"]') || // listing.querySelector('div[role="button"]'); // if (!listingLink) { // throw new Error("Tidak bisa menemukan link listing"); // } const mainDiv = listing.querySelector('div[role="button"]') || listing.querySelector('a[href*="/marketplace/item/"]'); if (!mainDiv || !isVisibleUpdate(mainDiv)) { log("⚠️ Gagal menemukan area yang bisa diklik pada listing"); return false; } humanLikeClickUpdate(mainDiv); log("Mencoba membuka listing..."); await sleep(3000); // 3. Find and click update button const updateBtn = await findAndClickUpdateButton(); await sleep(1000); if (!updateBtn) { throw new Error("Tombol update tidak ditemukan"); } await sleep(1000); // 4. Close dialog if still open closeAllDialogs(); highlightListingUpdate(listing, 'success'); listing.setAttribute('data-processed', 'true'); return true; } catch (e) { highlightListingUpdate(listing, 'failed'); closeAllDialogs(); throw e; } } async function findAndClickUpdateButton() { // Try multiple ways to find the update button const updateBtn = [...document.querySelectorAll('div[aria-label="Perbarui penawaran"]')] .find(isVisibleUpdate); if (updateBtn) { // let success = false; humanLikeClickUpdate(updateBtn); log("✅ Berhasil klik 'Perbarui penawaran'"); await sleep(500); return true; } else { log("⚠️ Gagal menemukan tombol perbarui setelah membuka listing"); return false; } } function closeAllDialogs() { const closeBtns = [...document.querySelectorAll('div[aria-label="Tutup"], svg[aria-label="Tutup"]')]; closeBtns.forEach(btn => { if (isVisibleUpdate(btn)) humanLikeClickUpdate(btn); }); } async function smartScrollUpdate() { window.scrollBy({ top: window.innerHeight * 1.5, behavior: 'smooth' }); await sleep(1000); window.scrollBy(0, 200); } function findParentListingUpdate(element) { const selectors = [ 'div[data-testid="marketplace_your_listing_card"]', 'div.x1lliihq.x1n2onr6.x1jchvi3', 'div.x9f619.x78zum5.x1r8uery', 'div[role="article"]', 'div.x1qjc9v5.x78zum5.x1q0g3np.x1a02dak.x1qughib' ]; for (const selector of selectors) { const parent = element.closest(selector); if (parent) return parent; } return element.closest('div[style*="position: relative"]')|| element.closest('div.x1lliihq.x1n2onr6.x1jchvi3') || element.closest('div[role="button"]') || element.closest('a[href*="/marketplace/item/"]') || element.closest('div.x9f619.x78zum5.x1r8uery') || element.closest('div[style*="position: relative"]'); } function isVisibleUpdate(element) { if (!element) return false; const style = window.getComputedStyle(element); return style.display !== 'none' && style.visibility !== 'hidden' && element.offsetWidth > 0; } function isClickableUpdate(element) { if (!element || !isVisibleUpdate(element)) return false; const style = window.getComputedStyle(element); return !(style.pointerEvents === 'none' || style.cursor === 'not-allowed' || parseFloat(style.opacity) < 0.6); } function highlightListingUpdate(element, state) { const colors = { processing: 'orange', success: 'green', failed: 'red' }; element.style.border = `2px solid ${colors[state]}`; element.style.borderRadius = '8px'; setTimeout(() => {element.style.border = ''}, 2000); } function humanLikeClickUpdate(element) { if (!element || !isVisibleUpdate(element)) return false; const rect = element.getBoundingClientRect(); const clickEvent = new MouseEvent('click', { bubbles: true, clientX: rect.left + rect.width/2, clientY: rect.top + rect.height/2 }); element.dispatchEvent(clickEvent); return true; } // Activation Protocol (function waitForPageReady() { if (document.readyState !== 'complete') { return setTimeout(waitForPageReady, 500); } createTerminatorUI(); log("SYSTEM ONLINE"); log("MENUNGGU PERINTAH"); })(); window.createTerminatorUI = createTerminatorUI; window.startTerminationSequence = startTerminationSequence; window.startUpdateSequence = startUpdateSequence; window.startRepostSequence = startRepostSequence; window.log = log; })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址