Auto Remove Datacaciques Ad

DataCaciques 广告屏蔽脚本

Vous devrez installer une extension telle que Tampermonkey, Greasemonkey ou Violentmonkey pour installer ce script.

Vous devrez installer une extension telle que Tampermonkey ou Violentmonkey pour installer ce script.

Vous devrez installer une extension telle que Tampermonkey ou Violentmonkey pour installer ce script.

Vous devrez installer une extension telle que Tampermonkey ou Userscripts pour installer ce script.

Vous devrez installer une extension telle que Tampermonkey pour installer ce script.

Vous devrez installer une extension de gestionnaire de script utilisateur pour installer ce script.

(J'ai déjà un gestionnaire de scripts utilisateur, laissez-moi l'installer !)

Vous devrez installer une extension telle que Stylus pour installer ce style.

Vous devrez installer une extension telle que Stylus pour installer ce style.

Vous devrez installer une extension telle que Stylus pour installer ce style.

Vous devrez installer une extension du gestionnaire de style pour utilisateur pour installer ce style.

Vous devrez installer une extension du gestionnaire de style pour utilisateur pour installer ce style.

Vous devrez installer une extension du gestionnaire de style pour utilisateur pour installer ce style.

(J'ai déjà un gestionnaire de style utilisateur, laissez-moi l'installer!)

// ==UserScript==
// @name         Auto Remove Datacaciques Ad
// @namespace    http://tampermonkey.net/
// @version      1.7
// @description  DataCaciques 广告屏蔽脚本
// @match        *://*.datacaciques.com/*
// @grant        GM_addStyle
// @run-at       document-idle
// @license MIT
// ==/UserScript==

    (function() {
        'use strict';

        // 定义颜色渐变数组
        const colorPalettes = [
            { start: '#2EC4B6', end: '#1A936F', hoverStart: '#56D4C7', hoverEnd: '#136B4F' }, // Teal to Deep Teal
            { start: '#FF6B6B', end: '#D00000', hoverStart: '#FF8787', hoverEnd: '#A00000' }, // Coral to Crimson
            { start: '#7209B7', end: '#3A0CA3', hoverStart: '#9B59D0', hoverEnd: '#2A0877' }, // Purple to Indigo
            { start: '#F48C06', end: '#DC2F02', hoverStart: '#F7A634', hoverEnd: '#B02402' }  // Orange to Amber
        ];

        // 添加 CSS 屏蔽,优化按钮样式
        GM_addStyle(`
            .listingExceedModal {
                display: none !important;
            }
            #backdropHideBtn {
                position: fixed;
                top: 50%;
                right: 20px;
                transform: translateY(-50%);
                z-index: 100000;
                background: linear-gradient(135deg, ${colorPalettes[0].start}, ${colorPalettes[0].end});
                color: white;
                width: 48px;
                height: 48px;
                border-radius: 50%;
                border: none;
                cursor: pointer;
                box-shadow: 0 4px 12px rgba(0,0,0,0.2);
                display: none;
                transition: transform 0.2s ease, background 0.3s ease, box-shadow 0.2s ease, opacity 0.2s ease;
                outline: none;
                touch-action: none;
            }
            #backdropHideBtn:hover {
                background: linear-gradient(135deg, ${colorPalettes[0].hoverStart}, ${colorPalettes[0].hoverEnd});
                box-shadow: 0 6px 16px rgba(0,0,0,0.3);
                transform: scale(1.05);
            }
            #backdropHideBtn:active {
                transform: scale(0.95);
            }
            #backdropHideBtn:focus {
                box-shadow: 0 0 0 3px rgba(255, 107, 107, 0.3);
            }
            #backdropHideBtn.dragging {
                opacity: 0.8;
                cursor: grabbing;
            }
            #backdropHideBtn.color-switch {
                animation: pulse 0.3s ease;
            }
            #backdropHideBtn::after {
                content: '✕';
                font-size: 20px;
                line-height: 48px;
                text-align: center;
                display: block;
            }
            @keyframes pulse {
                0% { transform: scale(1); }
                50% { transform: scale(1.1); }
                100% { transform: scale(1); }
            }
            @media (max-width: 768px) {
                #backdropHideBtn {
                    width: 40px;
                    height: 40px;
                    top: 15px;
                    right: 15px;
                }
                #backdropHideBtn::after {
                    font-size: 18px;
                    line-height: 40px;
                }
            }
            .__web-inspector-hide-shortcut__ {
                display: none !important;
            }
        `);

        // 创建按钮
        function createBackdropButton() {
            try {
                if (document.querySelector('#backdropHideBtn')) {
                    console.log('Button already exists');
                    return;
                }
                const button = document.createElement('button');
                button.id = 'backdropHideBtn';
                button.setAttribute('aria-label', '隐藏遮罩 (右键切换颜色,长按或按住鼠标拖拽移动)');
                button.setAttribute('title', '隐藏遮罩 (右键切换颜色,长按或按住鼠标拖拽移动)');
                button.setAttribute('role', 'button');

                // 加载保存的颜色和位置
                const savedColorIndex = localStorage.getItem('backdropButtonColorIndex') || '0';
                applyButtonColor(button, parseInt(savedColorIndex));
                const savedPosition = JSON.parse(localStorage.getItem('backdropButtonPosition')) || {  top: '50%',right: '20px',transform: 'translateY(-50%)' };
                button.style.top = savedPosition.top;
                button.style.right = savedPosition.right;
                button.style.left = 'auto';
                button.style.bottom = 'auto';

                // 事件监听
                button.addEventListener('click', hideBackdrop);
                button.addEventListener('contextmenu', (e) => {
                    e.preventDefault();
                    switchButtonColor(button);
                });
                button.addEventListener('keydown', (e) => {
                    if (e.key === 'Enter' || e.key === ' ') {
                        e.preventDefault();
                        hideBackdrop();
                    } else if (e.key === 'c') {
                        switchButtonColor(button);
                    }
                });

                // 拖拽支持
                let isDragging = false;
                let longPressTimeout;
                let startX, startY;

                // 鼠标拖拽
                button.addEventListener('mousedown', (e) => {
                    longPressTimeout = setTimeout(() => {
                        isDragging = true;
                        button.classList.add('dragging');
                        startX = e.clientX - parseInt(button.style.left || window.getComputedStyle(button).left);
                        startY = e.clientY - parseInt(button.style.top || window.getComputedStyle(button).top);
                        console.log('Started dragging button');
                    }, 500);
                });

                document.addEventListener('mousemove', (e) => {
                    if (isDragging) {
                        const newX = e.clientX - startX;
                        const newY = e.clientY - startY;
                        // 限制按钮在视口内
                        const maxX = window.innerWidth - button.offsetWidth;
                        const maxY = window.innerHeight - button.offsetHeight;
                        button.style.left = `${Math.max(0, Math.min(newX, maxX))}px`;
                        button.style.top = `${Math.max(0, Math.min(newY, maxY))}px`;
                        button.style.right = 'auto';
                        button.style.bottom = 'auto';
                    }
                });

                document.addEventListener('mouseup', () => {
                    if (isDragging) {
                        isDragging = false;
                        button.classList.remove('dragging');
                        // 保存位置
                        localStorage.setItem('backdropButtonPosition', JSON.stringify({
                            top: button.style.top,
                            left: button.style.left
                        }));
                        console.log('Stopped dragging, saved position:', button.style.top, button.style.left);
                    }
                    clearTimeout(longPressTimeout);
                });

                // 触摸拖拽
                button.addEventListener('touchstart', (e) => {
                    longPressTimeout = setTimeout(() => {
                        isDragging = true;
                        button.classList.add('dragging');
                        const touch = e.touches[0];
                        startX = touch.clientX - parseInt(button.style.left || window.getComputedStyle(button).left);
                        startY = touch.clientY - parseInt(button.style.top || window.getComputedStyle(button).top);
                        console.log('Started touch dragging button');
                    }, 500);
                });

                document.addEventListener('touchmove', (e) => {
                    if (isDragging) {
                        e.preventDefault();
                        const touch = e.touches[0];
                        const newX = touch.clientX - startX;
                        const newY = touch.clientY - startY;
                        const maxX = window.innerWidth - button.offsetWidth;
                        const maxY = window.innerHeight - button.offsetHeight;
                        button.style.left = `${Math.max(0, Math.min(newX, maxX))}px`;
                        button.style.top = `${Math.max(0, Math.min(newY, maxY))}px`;
                        button.style.right = 'auto';
                        button.style.bottom = 'auto';
                    }
                });

                document.addEventListener('touchend', () => {
                    if (isDragging) {
                        isDragging = false;
                        button.classList.remove('dragging');
                        localStorage.setItem('backdropButtonPosition', JSON.stringify({
                            top: button.style.top,
                            left: button.style.left
                        }));
                        console.log('Stopped touch dragging, saved position:', button.style.top, button.style.left);
                    }
                    clearTimeout(longPressTimeout);
                });

                if (document.body) {
                    document.body.appendChild(button);
                    console.log('Backdrop button created and appended');
                } else {
                    console.warn('document.body not ready, retrying...');
                    setTimeout(createBackdropButton, 500);
                }
            } catch (e) {
                console.error('Error creating button:', e);
            }
        }

        // 应用按钮颜色
        function applyButtonColor(button, colorIndex) {
            const palette = colorPalettes[colorIndex];
            button.style.background = `linear-gradient(135deg, ${palette.start}, ${palette.end})`;
            button.setAttribute('data-color-index', colorIndex);
            GM_addStyle(`
                #backdropHideBtn:hover {
                    background: linear-gradient(135deg, ${palette.hoverStart}, ${palette.hoverEnd}) !important;
                }
            `);
        }

        // 切换按钮颜色
        function switchButtonColor(button) {
            try {
                let currentIndex = parseInt(button.getAttribute('data-color-index') || '0');
                currentIndex = (currentIndex + 1) % colorPalettes.length;
                applyButtonColor(button, currentIndex);
                localStorage.setItem('backdropButtonColorIndex', currentIndex);
                button.classList.add('color-switch');
                setTimeout(() => button.classList.remove('color-switch'), 300);
                console.log('Switched button color to index:', currentIndex);
            } catch (e) {
                console.error('Error switching button color:', e);
            }
        }

        // 隐藏遮罩函数
        function hideBackdrop() {
            try {
                const backdrops = document.querySelectorAll('.modal-backdrop.in');
                const button = document.querySelector('#backdropHideBtn');
                if (backdrops.length > 0) {
                    backdrops.forEach(backdrop => {
                        backdrop.style.display = 'none';
                        backdrop.classList.add('__web-inspector-hide-shortcut__');
                        console.log('Hid backdrop:', backdrop, 'Classes:', backdrop.classList.toString(), 'Style:', backdrop.style.display);
                    });
                    if (button) button.style.display = 'none';
                } else {
                    console.warn('No .modal-backdrop.in found');
                }
            } catch (e) {
                console.error('Error hiding backdrop:', e);
            }
        }

        // 显示/隐藏按钮
        function toggleBackdropButton() {
            try {
                const button = document.querySelector('#backdropHideBtn');
                const backdrops = document.querySelectorAll('.modal-backdrop.in');
                if (button && backdrops.length > 0) {
                    let isVisible = false;
                    backdrops.forEach(backdrop => {
                        if (backdrop.style.display !== 'none' && !backdrop.classList.contains('__web-inspector-hide-shortcut__')) {
                            isVisible = true;
                        }
                    });
                    if (isVisible) {
                        const backdropZIndex = backdrops[0] ? parseInt(window.getComputedStyle(backdrops[0]).zIndex) || 1050 : 1050;
                        button.style.zIndex = backdropZIndex + 1;
                        button.style.display = 'block';
                        console.log('Backdrop detected, button shown. Backdrop count:', backdrops.length, 'Z-index:', backdropZIndex);
                    } else {
                        button.style.display = 'none';
                        console.log('No visible backdrop, button hidden');
                    }
                } else {
                    console.warn('Button or backdrop missing. Button:', !!button, 'Backdrops:', backdrops.length);
                }
            } catch (e) {
                console.error('Error toggling button:', e);
            }
        }

        // 移除遮罩函数,支持重试
        function removeBackdrop() {
            try {
                const backdrop = document.querySelector('.modal-backdrop.in');
                const hasNormalModal = document.querySelector('.editItem, .pgUploadModal');
                if (backdrop && !hasNormalModal) {
                    backdrop.remove();
                    console.log('Removed ad backdrop');
                    return true;
                }
                return false;
            } catch (e) {
                console.error('Error removing backdrop:', e);
                return false;
            }
        }

        // 使用 MutationObserver 监控 DOM
        const observer = new MutationObserver((mutations) => {
            mutations.forEach((mutation) => {
                try {
                    mutation.addedNodes.forEach((node) => {
                        if (node.nodeType === 1 && node.matches('.listingExceedModal')) {
                            // 检查标题
                            const title = node.querySelector('h1, h4');
                            if (title && title.textContent.includes('在线Listing数量已超过套餐上限')) {
                                try {
                                    node.remove(); // 移除广告弹窗
                                    // 移除遮罩,尝试 5 次
                                    let attempts = 0;
                                    const maxAttempts = 5;
                                    const retryInterval = setInterval(() => {
                                        if (removeBackdrop() || attempts >= maxAttempts) {
                                            clearInterval(retryInterval);
                                        }
                                        attempts++;
                                    }, 200);
                                    const closeButton = node.querySelector('.btnClose, .close-button, [class*="close"], button');
                                    if (closeButton) {
                                        closeButton.removeAttribute('disabled');
                                        closeButton.click(); // 自动点击关闭
                                    }
                                    hideBackdrop(); // 确保遮罩被隐藏
                                    console.log('Removed ad modal:', node);
                                } catch (e) {
                                    console.error('Error removing modal:', e);
                                }
                            }
                        }
                    });
                } catch (e) {
                    console.error('Error in MutationObserver:', e);
                }
            });
        });

        // 初始化
        function init() {
            try {
                createBackdropButton();
                observer.observe(document.body, {
                    childList: true,
                    subtree: true,
                    attributes: true,
                    attributeFilter: ['class', 'style']
                });
                console.log('MutationObserver started');
                toggleBackdropButton();
                setInterval(toggleBackdropButton, 1000);
            } catch (e) {
                console.error('Error initializing:', e);
            }
        }

        // 在 DOM 加载完成后启动
        if (document.readyState === 'complete' || document.readyState === 'interactive') {
            init();
        } else {
            document.addEventListener('DOMContentLoaded', init);
        }

        // 拦截 15-25 秒倒计时
        const originalSetTimeout = window.setTimeout;
        window.setTimeout = function(callback, time) {
            if (time >= 15000 && time <= 25000) {
                console.log('Blocked ad countdown:', time);
                return null;
            }
            return originalSetTimeout.apply(this, arguments);
        };
    })();