Auto Remove Datacaciques Ad

DataCaciques 广告屏蔽脚本

// ==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);
        };
    })();