Greasy Fork

ad 反广告检测bypass

提高稳定性与性能,增加自定义排除功能,确保不会干扰扫码验证等功能,优化错误处理和性能

目前为 2025-02-27 提交的版本。查看 最新版本

// ==UserScript==
// @name            ad 反广告检测bypass 
// @version         1.1.0
// @description     提高稳定性与性能,增加自定义排除功能,确保不会干扰扫码验证等功能,优化错误处理和性能
// @match           *://*/*
// @run-at          document-start
// @grant           none
// @license         MIT
// @namespace       https://greasyfork.org/users/1440075
// ==/UserScript==

(function() {
    'use strict';
    try {
        // 备份原始的 getComputedStyle 函数
        const originalGetComputedStyle = window.getComputedStyle;

        // 用于缓存检测过的元素状态,避免重复检测
        const elementCache = new WeakMap();

        // 用户自定义排除关键词
        const userExcludedKeywords = [
            'qr', 'verify', 'captcha', 'validate', 'recaptcha', 'g-recaptcha',
            'security', 'auth', '扫码', '验证', '验证码', 'popup', 'modal', 'overlay'
        ];

        // 排除广告相关的常见 HTML 标签
        const adElementTags = ['IMG', 'IFRAME', 'SCRIPT', 'DIV', 'SPAN', 'BANNER'];

        // 优化错误处理和日志输出
        function logError(message, data = {}) {
            console.error(message, data);
        }

        // 重写 getComputedStyle,支持第二个参数 pseudoElement
        Object.defineProperty(window, "getComputedStyle", {
            get() {
                return function(element, pseudoElement) {
                    try {
                        // 如果请求的是伪元素,则直接返回原始结果
                        if (pseudoElement) {
                            return originalGetComputedStyle(element, pseudoElement);
                        }

                        // 检查缓存,减少重复检查
                        if (elementCache.has(element)) {
                            return elementCache.get(element);
                        }

                        // 获取原始样式对象
                        const style = originalGetComputedStyle(element, pseudoElement);

                        // 排除验证相关元素
                        if (element && typeof element.getAttribute === 'function') {
                            const idStr = element.id ? element.id.toLowerCase() : "";
                            const classStr = (typeof element.className === 'string' ? element.className.toLowerCase() : "");
                            if (userExcludedKeywords.some(kw => idStr.includes(kw) || classStr.includes(kw))) {
                                elementCache.set(element, style);
                                return style;
                            }
                        }

                        // 排除广告元素(通过标签类型)
                        if (adElementTags.includes(element.tagName)) {
                            const isAd = (
                                element.src && (element.src.includes('ad') || element.src.includes('banner') || element.src.includes('ads')) ||
                                element.id && element.id.includes('ad') ||
                                element.className && element.className.includes('ad') ||
                                element.style && element.style.display === 'none'
                            );
                            if (isAd && style.display === "none") {
                                const proxyStyle = new Proxy(style, {
                                    get(target, prop, receiver) {
                                        if (prop === "display") {
                                            return "block";
                                        }
                                        return Reflect.get(target, prop, receiver);
                                    }
                                });
                                elementCache.set(element, proxyStyle);
                                return proxyStyle;
                            }
                        }

                        // 默认返回原始样式对象
                        elementCache.set(element, style);
                        return style;
                    } catch (e) {
                        logError("getComputedStyle 重写异常:", e);
                        return originalGetComputedStyle(element, pseudoElement);
                    }
                };
            },
            configurable: true,
            enumerable: true
        });
    } catch (e) {
        console.error("全局脚本异常:", e);
    }
})();