BT4G Magnet AutoGen

自动转换BT4G哈希到磁力链接 | 添加高级搜索选项:分辨率、HDR、编码、杜比音频和模糊搜索 | 删除资源恢复 | 广告拦截(未精准测试)

当前为 2025-04-05 提交的版本,查看 最新版本

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name            BT4G Magnet AutoGen
// @namespace       https://ahogek.com
// @version         1.3.9
// @description     自动转换BT4G哈希到磁力链接 | 添加高级搜索选项:分辨率、HDR、编码、杜比音频和模糊搜索 | 删除资源恢复 | 广告拦截(未精准测试)
// @author          AhogeK
// @match           *://*.bt4g.org/*
// @match           *://*.bt4gprx.com/*
// @match           *://*.bt4g.com/*
// @match           *://*.downloadtorrentfile.com/hash/*
// @grant           GM_xmlhttpRequest
// @connect         itorrents.org
// @connect         btcache.me
// @connect         thetorrent.org
// @license         MIT
// ==/UserScript==

(function () {
    'use strict';

    // 查找所有磁力链接按钮
    const magnetButtons = document.querySelectorAll('a.btn-primary[href*="downloadtorrentfile.com/hash/"]');

    magnetButtons.forEach(button => {
        // 从URL中提取哈希值
        const url = new URL(button.href);
        const pathParts = url.pathname.split('/');
        const hash = pathParts[pathParts.length - 1].split('?')[0];

        if (hash && hash.length === 40) {
            // 构建真正的磁力链接
            // 修改按钮行为和外观
            button.href = `magnet:?xt=urn:btih:${hash}`;
            button.setAttribute('title', '直接打开磁力链接');
            button.removeAttribute('target'); // 移除新标签页打开

            // 添加新标签,表明这是直接链接
            const badge = document.createElement('span');
            badge.textContent = '直接';
            badge.style.cssText = `
                background-color: #ff5722;
                color: white;
                padding: 2px 5px;
                border-radius: 3px;
                font-size: 10px;
                margin-left: 5px;
                vertical-align: middle;
            `;

            // 在按钮图片后面插入标记
            const img = button.querySelector('img');
            button.insertBefore(badge, img?.nextSibling || null);
        }
    });

    // 寻找所有种子下载按钮
    const torrentButtons = document.querySelectorAll('a.btn-success[href*="downloadtorrentfile.com/hash/"]');

    torrentButtons.forEach(button => {
        // 从URL中提取哈希值
        const url = new URL(button.href);
        const pathParts = url.pathname.split('/');
        const hash = pathParts[pathParts.length - 1].split('?')[0];

        if (hash && hash.length === 40) {
            // 修改按钮为直接下载种子文件
            button.setAttribute('title', '直接下载种子文件');
            button.removeAttribute('target'); // 移除新标签页打开

            // 添加新标签,表明这是直接下载
            const badge = document.createElement('span');
            badge.textContent = '直接';
            badge.style.cssText = `
                background-color: #28a745;
                color: white;
                padding: 2px 5px;
                border-radius: 3px;
                font-size: 10px;
                margin-left: 5px;
                vertical-align: middle;
            `;

            // 在按钮图片后面插入标记
            const img = button.querySelector('img');
            button.insertBefore(badge, img?.nextSibling || null);

            // 添加点击事件监听器
            button.addEventListener('click', function (e) {
                e.preventDefault(); // 阻止默认导航行为

                // 保存原始按钮状态
                const originalText = button.innerHTML;
                const originalWidth = button.offsetWidth;
                button.style.width = `${originalWidth}px`; // 保持按钮宽度不变
                button.innerHTML = '<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span> 下载中...';
                button.disabled = true;

                // 尝试从多个源下载种子文件
                downloadTorrentFile(hash, [
                    `https://itorrents.org/torrent/${hash.toUpperCase()}.torrent`,
                    `https://btcache.me/torrent/${hash}`,
                    `https://thetorrent.org/${hash}.torrent`
                ], 0, button, originalText);
            });
        }
    });

    // 通过多个来源尝试下载种子文件的函数
    function downloadTorrentFile(hash, urls, index, button, originalText) {
        if (index >= urls.length) {
            // 所有来源都尝试过了,恢复按钮状态并显示错误
            button.innerHTML = originalText;
            button.disabled = false;
            button.style.width = '';

            // 显示错误消息
            showToast('无法下载种子文件,请尝试使用磁力链接', 'danger');
            return;
        }

        // 当前尝试的URL
        const url = urls[index];

        try {
            // 使用GM_xmlhttpRequest获取种子文件
            GM_xmlhttpRequest({
                method: "GET",
                url: url,
                responseType: "blob",
                timeout: 10000, // 10秒超时
                onload: function (response) {
                    if (response.status === 200) {
                        // 检查响应是否是torrent文件(简单检查)
                        const contentType = response.responseHeaders.match(/content-type:\s*(.*?)(\s|;|$)/i);
                        const isTorrent = contentType && (
                            contentType[1].includes('application/x-bittorrent') ||
                            contentType[1].includes('application/octet-stream')
                        );

                        // 还可以检查文件大小,极小的文件可能是错误页面
                        const hasContent = response.response && response.response.size > 50; // 至少50字节

                        if (isTorrent && hasContent) {
                            // 创建Blob并下载
                            const blob = new Blob([response.response], {
                                type: 'application/x-bittorrent'
                            });
                            const url = URL.createObjectURL(blob);
                            const a = document.createElement('a');
                            a.href = url;
                            a.download = `${hash.toLowerCase()}.torrent`;
                            document.body.appendChild(a);
                            a.click();
                            document.body.removeChild(a);
                            URL.revokeObjectURL(url);

                            // 恢复按钮状态
                            button.innerHTML = originalText;
                            button.disabled = false;
                            button.style.width = '';

                            // 显示成功消息
                            showToast('种子文件下载成功!', 'success');
                        } else {
                            // 不是有效的torrent文件,尝试下一个URL
                            downloadTorrentFile(hash, urls, index + 1, button, originalText);
                        }
                    } else {
                        // HTTP错误,尝试下一个URL
                        downloadTorrentFile(hash, urls, index + 1, button, originalText);
                    }
                },
                onerror: function () {
                    // 请求错误,尝试下一个URL
                    console.error(`从 ${url} 下载种子时出错`);
                    downloadTorrentFile(hash, urls, index + 1, button, originalText);
                },
                ontimeout: function () {
                    // 请求超时,尝试下一个URL
                    console.error(`从 ${url} 下载种子超时`);
                    downloadTorrentFile(hash, urls, index + 1, button, originalText);
                }
            });
        } catch (error) {
            // 发生异常,尝试下一个URL
            console.error('下载种子文件时出错:', error);
            downloadTorrentFile(hash, urls, index + 1, button, originalText);
        }
    }

    // 显示通知消息
    function showToast(message, type = 'success') {
        // 创建通知元素
        const toast = document.createElement('div');
        toast.className = `toast-notification toast-${type}`;
        // 添加特殊标识符,避免被广告拦截功能删除
        toast.setAttribute('data-bt4g-notification', 'true');
        toast.textContent = message;
        toast.style.cssText = `
            position: fixed;
            top: 20px;
            right: 20px;
            padding: 12px 20px;
            background-color: ${type === 'success' ? '#28a745' : '#dc3545'};
            color: white;
            border-radius: 4px;
            box-shadow: 0 4px 8px rgba(0,0,0,0.2);
            z-index: 9999;
            font-size: 14px;
            transition: opacity 0.3s ease-in-out;
            opacity: 0;
          `;

        // 添加到页面
        document.body.appendChild(toast);

        // 显示通知
        setTimeout(() => {
            toast.style.opacity = '1';
        }, 10);

        // 3秒后隐藏
        setTimeout(() => {
            toast.style.opacity = '0';
            setTimeout(() => {
                // 确保元素仍然存在再移除
                if (document.body.contains(toast)) {
                    document.body.removeChild(toast);
                }
            }, 300);
        }, 3000);
    }
})();

(function () {
    'use strict';

    // 等待DOM完全加载
    window.addEventListener('load', () => {
        // 检查是否在搜索页面
        const searchForm = document.querySelector('form[action="/search"]');
        if (!searchForm) return;

        // 获取搜索输入框
        const searchInput = document.getElementById('search');
        if (!searchInput) return;

        // 检查页面上是否已经存在高级搜索选项容器
        if (document.querySelector('.advanced-search')) {
            console.log('高级搜索选项已存在,跳过创建');
            return;
        }

        // 使用一个全局标识符确保只初始化一次
        if (window.bt4gAdvancedSearchInitialized) return;
        window.bt4gAdvancedSearchInitialized = true;

        // 定义关键字映射表,用于表示各种格式的常见变体
        const keywordMaps = {
            resolution: {
                '720p': ['720p', '720P', 'HD'],
                '1080p': ['1080p', '1080P', 'HD1080P', 'FHD', 'FullHD', '1920x1080'],
                '4K/UHD': ['2160p', '2160P', '4K', '4k', 'UHD', 'UltraHD', '3840x2160', '4096x2160']
            },
            hdr: {
                'HDR': ['HDR'],
                'HDR10': ['HDR10'],
                'HDR10+': ['HDR10+', 'HDR10Plus'],
                'Dolby Vision': ['DV', 'DoVi', 'DolbyVision']
            },
            codec: {
                'H264/AVC': ['H264', '264', 'AVC', 'h264', 'MPEG4AVC', 'x264'],
                'H265/HEVC': ['H265', '265', 'HEVC', 'x265', 'h265'],
                'AV1': ['AV1'],
                'VP9': ['VP9']
            },
            mediaType: {
                'BD': ['BD', 'BLURAY', "BLU", "RAY", 'BDMV', 'BDREMUX', 'REMUX'],
                'WEB-DL': ['WEBDL'],
                'WEB': ['WEB', 'WEBRIP', 'WEBRip'],
                'HDTV': ['HDTV', 'TV'],
                'DVD': ['DVD', 'DVDRIP']
            },
            audio: {
                '杜比': ['Dolby', 'DD', 'DD+', 'DDP', 'DolbyDigital', 'DDP5 1'],
                '杜比全景声': ['Atmos', 'DolbyAtmos'],
                'DTS': ['DTS', 'DTSHD', 'DTSHDMA', 'DTSX'],
                'TrueHD': ['TrueHD', 'TRUEHD', 'TrueHD7']
            }
        };

        // 检测当前主题模式
        const isDarkMode = document.body.classList.contains('dark-mode') ||
            document.documentElement.classList.contains('dark') ||
            document.documentElement.getAttribute('data-bs-theme') === 'dark';

        // 获取URL参数
        const urlParams = new URLSearchParams(window.location.search);

        // 创建高级搜索选项容器,直接放在搜索框下方
        const advancedSearchDiv = document.createElement('div');
        advancedSearchDiv.className = 'advanced-search mb-3 mt-2';
        advancedSearchDiv.setAttribute('data-initialized', 'true');

        // 应用固定样式而非弹出样式
        updateFixedAdvancedSearchStyle(advancedSearchDiv, isDarkMode);

        // 添加到搜索表单之后(不是内部)
        searchForm.parentNode.insertBefore(advancedSearchDiv, searchForm.nextSibling);

        // 创建分辨率选项行
        const resolutionRow = createOptionRow('resolution', '分辨率:', [
            {value: '', label: '任意'},
            {value: '720p', label: '720p/HD'},
            {value: '1080p', label: '1080p/Full HD'},
            {value: '4K/UHD', label: '4K/UHD/2160p'}
        ], isDarkMode);
        advancedSearchDiv.appendChild(resolutionRow);

        // 创建HDR选项行
        const hdrRow = createOptionRow('hdr', 'HDR:', [
            {value: '', label: '任意'},
            {value: 'HDR', label: 'HDR'},
            {value: 'HDR10', label: 'HDR10'},
            {value: 'HDR10+', label: 'HDR10+'},
            {value: 'Dolby Vision', label: 'Dolby Vision/DV'}
        ], isDarkMode);
        advancedSearchDiv.appendChild(hdrRow);

        // 创建编码选项行
        const codecRow = createOptionRow('codec', '编码:', [
            {value: '', label: '任意'},
            {value: 'H264/AVC', label: 'H.264/AVC/x264'},
            {value: 'H265/HEVC', label: 'H.265/HEVC/x265'},
            {value: 'AV1', label: 'AV1'},
            {value: 'VP9', label: 'VP9'}
        ], isDarkMode);
        advancedSearchDiv.appendChild(codecRow);

        // 创建媒体类型选项行
        const mediaTypeRow = createOptionRow('mediaType', '媒体类型:', [
            {value: '', label: '任意'},
            {value: 'BD', label: 'BD/蓝光/REMUX'},
            {value: 'WEB-DL', label: 'WEB-DL'},
            {value: 'WEB', label: 'WEB/WEBRip'},
            {value: 'HDTV', label: 'HDTV'},
            {value: 'DVD', label: 'DVD'}
        ], isDarkMode);
        advancedSearchDiv.appendChild(mediaTypeRow);

        // 创建音频行(包含音频选项和重置按钮)
        const audioRow = document.createElement('div');
        audioRow.style.cssText = 'display: flex; align-items: center; justify-content: space-between; margin-bottom: 8px; width: 100%;';

        // 音频选项部分
        const audioOptions = document.createElement('div');
        audioOptions.style.cssText = 'display: flex; align-items: center;';

        // 创建音频标签
        const audioLabel = document.createElement('span');
        audioLabel.textContent = '音频:';
        audioLabel.style.cssText = 'width: 80px; margin-right: 10px; white-space: nowrap; font-weight: bold;';
        if (isDarkMode) {
            audioLabel.style.color = '#e9ecef';
        } else {
            audioLabel.style.color = '#212529';
        }
        audioOptions.appendChild(audioLabel);

        // 创建音频选项组
        const audioChoices = [
            {value: '', label: '任意'},
            {value: '杜比', label: '杜比/Dolby'},
            {value: '杜比全景声', label: '杜比全景声/Atmos'},
            {value: 'DTS', label: 'DTS系列'},
            {value: 'TrueHD', label: 'TrueHD'}
        ];

        const audioGroup = document.createElement('div');
        audioGroup.style.cssText = 'display: flex; flex-wrap: wrap; gap: 5px;';

        // 添加各个音频选项
        audioChoices.forEach((choice, index) => {
            const id = `audio_${index}`;

            const radio = document.createElement('input');
            radio.type = 'radio';
            radio.name = 'audio';
            radio.id = id;
            radio.value = choice.value;
            radio.className = 'btn-check';
            radio.checked = index === 0;

            const optionLabel = document.createElement('label');
            optionLabel.className = isDarkMode ? 'btn btn-outline-light btn-sm' : 'btn btn-outline-dark btn-sm';
            optionLabel.htmlFor = id;
            optionLabel.textContent = choice.label;

            audioGroup.appendChild(radio);
            audioGroup.appendChild(optionLabel);
        });

        audioOptions.appendChild(audioGroup);

        // 将音频选项部分添加到音频行
        audioRow.appendChild(audioOptions);

        // 创建重置按钮
        const resetButton = document.createElement('button');
        resetButton.type = 'button';
        resetButton.className = isDarkMode ? 'btn btn-outline-light btn-sm' : 'btn btn-outline-dark btn-sm';
        resetButton.textContent = '重置选项';

        // 添加重置按钮的点击事件
        resetButton.addEventListener('click', resetAdvancedOptions);

        // 将重置按钮添加到音频行
        audioRow.appendChild(resetButton);

        // 将音频行添加到高级搜索容器
        advancedSearchDiv.appendChild(audioRow);

        // 设置一个隐藏字段来存储原始查询
        const originalQueryInput = document.createElement('input');
        originalQueryInput.type = 'hidden';
        originalQueryInput.id = 'originalQuery';
        searchForm.appendChild(originalQueryInput);

        // 恢复上次的搜索关键词(如果有)
        const lastSearchQuery = localStorage.getItem('bt4g_original_query') || '';
        if (lastSearchQuery && !urlParams.has('q')) {
            searchInput.value = lastSearchQuery;
        }

        // 存储高级搜索项
        const storeAdvancedSettings = () => {
            const settings = {
                resolution: document.querySelector('input[name="resolution"]:checked')?.value || '',
                hdr: document.querySelector('input[name="hdr"]:checked')?.value || '',
                codec: document.querySelector('input[name="codec"]:checked')?.value || '',
                mediaType: document.querySelector('input[name="mediaType"]:checked')?.value || '',
                audio: document.querySelector('input[name="audio"]:checked')?.value || '',
            };
            localStorage.setItem('bt4g_advanced_settings', JSON.stringify(settings));
        };

        // 恢复高级搜索项
        const restoreAdvancedSettings = () => {
            try {
                const settings = JSON.parse(localStorage.getItem('bt4g_advanced_settings')) || {};
                if (settings.resolution) setRadioValue('resolution', settings.resolution);
                if (settings.hdr) setRadioValue('hdr', settings.hdr);
                if (settings.codec) setRadioValue('codec', settings.codec);
                if (settings.mediaType) setRadioValue('mediaType', settings.mediaType);
                if (settings.audio) setRadioValue('audio', settings.audio);
            } catch (e) {
                console.error('Failed to restore advanced settings:', e);
            }
        };

        // 抽取搜索处理逻辑为独立函数
        function processSearch(e) {
            if (e) {
                e.preventDefault(); // 阻止表单默认提交
            }

            // 获取基本搜索词
            const baseQuery = searchInput.value.trim();

            // 如果搜索词为空,直接提交表单
            if (!baseQuery) {
                searchForm.submit();
                return;
            }

            // 存储原始查询
            localStorage.setItem('bt4g_original_query', baseQuery);
            originalQueryInput.value = baseQuery;

            // 获取选中的选项
            const resolution = document.querySelector('input[name="resolution"]:checked').value;
            const hdr = document.querySelector('input[name="hdr"]:checked').value;
            const codec = document.querySelector('input[name="codec"]:checked').value;
            const mediaType = document.querySelector('input[name="mediaType"]:checked').value;
            const audio = document.querySelector('input[name="audio"]:checked').value;

            // 存储高级搜索设置
            storeAdvancedSettings();

            // 构建搜索查询
            let baseQueryProcessed = baseQuery;
            let advancedConditions = [];

            // 构建高级条件数组
            if (resolution && keywordMaps.resolution[resolution]) {
                const variants = keywordMaps.resolution[resolution];
                if (variants.length > 0) {
                    advancedConditions.push(`(${variants.join('|')})`);
                }
            }

            if (hdr && keywordMaps.hdr[hdr]) {
                const variants = keywordMaps.hdr[hdr];
                if (variants.length > 0) {
                    advancedConditions.push(`(${variants.join('|')})`);
                }
            }

            if (codec && keywordMaps.codec[codec]) {
                const variants = keywordMaps.codec[codec];
                if (variants.length > 0) {
                    advancedConditions.push(`(${variants.join('|')})`);
                }
            }

            if (mediaType && keywordMaps.mediaType[mediaType]) {
                const variants = keywordMaps.mediaType[mediaType];
                if (variants.length > 0) {
                    advancedConditions.push(`(${variants.join('|')})`);
                }
            }

            if (audio && keywordMaps.audio[audio]) {
                const variants = keywordMaps.audio[audio];
                if (variants.length > 0) {
                    advancedConditions.push(`(${variants.join('|')})`);
                }
            }

            // 合并处理后的基本查询和高级条件
            let finalQuery = baseQueryProcessed;
            if (advancedConditions.length > 0) {
                finalQuery += ' ' + advancedConditions.join(' ');
            }

            // 更新搜索框的值
            searchInput.value = finalQuery;

            // 提交表单
            searchForm.submit();
        }

        // 重置高级搜索选项函数
        function resetAdvancedOptions() {
            // 重置所有单选按钮到第一个选项("任意")
            ['resolution', 'hdr', 'codec', 'mediaType', 'audio'].forEach(name => {
                const firstOption = document.querySelector(`input[name="${name}"][id="${name}_0"]`);
                if (firstOption) {
                    firstOption.checked = true;
                }
            });

            // 更新本地存储
            const settings = {
                resolution: '',
                hdr: '',
                codec: '',
                mediaType: '',
                audio: '',
            };
            localStorage.setItem('bt4g_advanced_settings', JSON.stringify(settings));
        }

        // 监听表单提交事件
        searchForm.addEventListener('submit', processSearch);

        // 监听搜索输入框的回车键事件
        searchInput.addEventListener('keydown', (e) => {
            if (e.key === 'Enter') {
                processSearch(e);
            }
        });

        // 添加搜索结果链接的监听器
        function addResultLinkListeners() {
            // 查找所有可能是搜索结果的链接
            const resultLinks = document.querySelectorAll('a[href^="/magnet/"]');

            resultLinks.forEach(link => {
                link.addEventListener('click', () => {
                    // 在用户点击链接时保存高级搜索设置
                    storeAdvancedSettings();
                });
            });
        }

        // 调用函数添加链接监听器
        // 使用MutationObserver来处理动态加载的内容
        const observer = new MutationObserver(() => {
            addResultLinkListeners();
        });
        observer.observe(document.body, {childList: true, subtree: true});

        // 初始化时也添加一次
        addResultLinkListeners();

        // 始终尝试恢复高级搜索设置,无论页面类型
        restoreAdvancedSettings();

        // 只在搜索结果页恢复原始查询到搜索框
        if (urlParams.has('q')) {
            const originalQuery = localStorage.getItem('bt4g_original_query');
            if (originalQuery) {
                setTimeout(() => {
                    searchInput.value = originalQuery;
                }, 100);
            }
        }

        // 监听主题切换按钮的点击事件
        const themeToggle = document.getElementById('theme-toggle');
        if (themeToggle) {
            themeToggle.addEventListener('click', () => {
                // 给浏览器一点时间来切换主题
                setTimeout(() => {
                    // 重新检测主题
                    const newDarkMode = document.body.classList.contains('dark-mode') ||
                        document.documentElement.classList.contains('dark') ||
                        document.documentElement.getAttribute('data-bs-theme') === 'dark';

                    // 更新高级搜索样式
                    updateFixedAdvancedSearchStyle(advancedSearchDiv, newDarkMode);

                    // 更新标签样式
                    document.querySelectorAll('.advanced-search label').forEach(label => {
                        if (newDarkMode) {
                            label.className = label.className.replace('btn-outline-dark', 'btn-outline-light');
                        } else {
                            label.className = label.className.replace('btn-outline-light', 'btn-outline-dark');
                        }
                    });

                    // 更新标题样式
                    document.querySelectorAll('.advanced-search span').forEach(span => {
                        if (newDarkMode) {
                            span.style.color = '#e9ecef';
                        } else {
                            span.style.color = '#212529';
                        }
                    });

                    // 更新重置按钮样式
                    resetButton.className = newDarkMode ?
                        'btn btn-outline-light btn-sm' :
                        'btn btn-outline-dark btn-sm';
                }, 100);
            });
        }
    });

    // 创建选项行
    function createOptionRow(name, label, choices, isDarkMode) {
        const row = document.createElement('div');
        row.style.cssText = 'display: flex; align-items: center; margin-bottom: 8px; width: 100%;';

        // 创建标签
        const labelElement = document.createElement('span');
        labelElement.textContent = label;
        labelElement.style.cssText = 'width: 80px; margin-right: 10px; white-space: nowrap;';
        labelElement.style.fontWeight = 'bold';
        if (isDarkMode) {
            labelElement.style.color = '#e9ecef';
        } else {
            labelElement.style.color = '#212529'; // 确保亮色模式下标签文字颜色为深色
        }
        row.appendChild(labelElement);

        // 创建选项组
        const optionsGroup = document.createElement('div');
        optionsGroup.style.cssText = 'display: flex; flex-wrap: wrap; gap: 5px;';

        // 添加各个选项
        choices.forEach((choice, index) => {
            const id = `${name}_${index}`;

            const radio = document.createElement('input');
            radio.type = 'radio';
            radio.name = name;
            radio.id = id;
            radio.value = choice.value;
            radio.className = 'btn-check';
            radio.checked = index === 0; // 默认选中第一个选项

            const optionLabel = document.createElement('label');
            optionLabel.className = isDarkMode ? 'btn btn-outline-light btn-sm' : 'btn btn-outline-dark btn-sm'; // 改为outline-dark
            optionLabel.htmlFor = id;
            optionLabel.textContent = choice.label;

            optionsGroup.appendChild(radio);
            optionsGroup.appendChild(optionLabel);
        });

        row.appendChild(optionsGroup);
        return row;
    }

    // 辅助函数:设置单选按钮的值
    function setRadioValue(name, value) {
        const radioButtons = document.querySelectorAll(`input[name="${name}"]`);
        let found = false;

        radioButtons.forEach(radio => {
            if (radio.value === value) {
                radio.checked = true;
                found = true;
            }
        });

        // 如果没有找到匹配项,选择"任意"选项
        if (!found && radioButtons.length > 0) {
            radioButtons[0].checked = true;
        }
    }

    // 更新固定式高级搜索面板的样式
    function updateFixedAdvancedSearchStyle(element, isDarkMode) {
        let backgroundColor, textColor, borderColor;

        if (isDarkMode) {
            backgroundColor = '#212529';
            textColor = '#e9ecef';
            borderColor = '#495057';
        } else {
            backgroundColor = '#f8f9fa';
            textColor = '#212529';
            borderColor = '#6c757d'; // 加深边框颜色,增加对比度
        }

        element.style.cssText = `
           display: flex;
           flex-direction: column;
           width: 100%;
           padding: 12px;
           background-color: ${backgroundColor};
           color: ${textColor};
           border: 1px solid ${borderColor};
           border-radius: 5px;
           margin-bottom: 10px;
       `;
    }
})();

// 添加处理被删除内容的直接磁链功能
(function () {
    'use strict';

    // 等待DOM完全加载
    window.addEventListener('load', () => {
        // 检查是否在资源详细页面且内容已被删除
        const paragraphs = document.querySelectorAll('div.col-12 p');
        let deletedContentP = null;

        for (const p of paragraphs) {
            if (p.textContent.includes('On request, content has been deleted')) {
                deletedContentP = p;
                break;
            }
        }

        if (!deletedContentP) {
            return; // 不是删除内容页面,直接返回
        }

        // 尝试从meta标签中获取哈希值
        const metaOgUrl = document.querySelector('meta[property="og:url"]');

        if (!metaOgUrl) {
            return; // 没有找到包含哈希的meta标签
        }

        // 从meta标签的content属性中提取哈希值
        const urlContent = metaOgUrl.getAttribute('content');
        const hashMatch = RegExp(/\/([a-fA-F0-9]{40})(?:\?|$)/).exec(urlContent);

        if (!hashMatch?.[1]) {
            return; // 没有找到有效的40位哈希值
        }

        const hash = hashMatch[1];
        const magnetLink = `magnet:?xt=urn:btih:${hash}`;

        // 检测当前主题模式
        const isDarkMode = document.body.classList.contains('dark-mode') ||
            document.documentElement.classList.contains('dark') ||
            document.documentElement.getAttribute('data-bs-theme') === 'dark';

        // 创建一个容器,用于更好的样式布局
        const buttonContainer = document.createElement('div');
        buttonContainer.style.cssText = 'margin-top: 20px; text-align: center;';

        // 创建说明文本
        const infoText = document.createElement('p');
        infoText.textContent = '虽然内容显示已删除,但您仍可通过以下方式获取资源:';
        infoText.style.cssText = 'margin-bottom: 10px; font-style: italic; color: ' + (isDarkMode ? '#adb5bd' : '#6c757d');
        buttonContainer.appendChild(infoText);

        // 创建打开磁力链接按钮
        const magnetButton = document.createElement('a');
        magnetButton.href = magnetLink;
        magnetButton.className = 'btn btn-success';
        magnetButton.innerHTML = '🧲 打开磁力链接';
        magnetButton.style.cssText = 'padding: 8px 15px; font-weight: bold;';
        buttonContainer.appendChild(magnetButton);

        // 创建显示磁力链接的元素(方便用户手动复制)
        const hashDisplay = document.createElement('div');
        hashDisplay.textContent = magnetLink;
        hashDisplay.style.cssText = 'margin-top: 10px; font-family: monospace; word-break: break-all; ' +
            'border: 1px solid ' + (isDarkMode ? '#495057' : '#dee2e6') + '; ' +
            'padding: 6px; border-radius: 4px; ' +
            'background-color: ' + (isDarkMode ? '#343a40' : '#f8f9fa') + '; ' +
            'color: ' + (isDarkMode ? '#adb5bd' : '#6c757d') + '; font-size: 0.9em; ' +
            'max-width: 100%; overflow-x: auto; text-align: left; cursor: pointer;';

        // 点击磁力链接文本区域时复制到剪贴板
        hashDisplay.addEventListener('click', function () {
            if (navigator.clipboard && window.isSecureContext) {
                navigator.clipboard.writeText(magnetLink).then(() => {
                    const originalText = hashDisplay.textContent;
                    hashDisplay.textContent = '✅ 已复制到剪贴板';
                    setTimeout(() => {
                        hashDisplay.textContent = originalText;
                    }, 1000);
                });
            } else {
                const textArea = document.createElement('textarea');
                textArea.value = magnetLink;
                textArea.style.position = 'fixed';
                textArea.style.left = '-9999px';
                document.body.appendChild(textArea);
                textArea.focus();
                textArea.select();

                hashDisplay.addEventListener('click', async function () {
                    try {
                        await navigator.clipboard.writeText(magnetLink);
                        const originalText = hashDisplay.textContent;
                        hashDisplay.textContent = '✅ 已复制到剪贴板';
                        setTimeout(() => {
                            hashDisplay.textContent = originalText;
                        }, 1000);
                    } catch (err) {
                        console.error('复制失败:', err);
                    }
                });

                document.body.removeChild(textArea);
            }
        });

        buttonContainer.appendChild(hashDisplay);

        // 将按钮容器添加到内容已删除的消息所在的div中
        deletedContentP.parentNode.appendChild(buttonContainer);

        // 监听主题切换以更新元素样式
        const themeToggle = document.getElementById('theme-toggle');
        if (themeToggle) {
            themeToggle.addEventListener('click', () => {
                // 给浏览器一点时间来切换主题
                setTimeout(() => {
                    // 重新检测主题
                    const newDarkMode = document.body.classList.contains('dark-mode') ||
                        document.documentElement.classList.contains('dark') ||
                        document.documentElement.getAttribute('data-bs-theme') === 'dark';

                    // 更新文本颜色和样式
                    infoText.style.color = newDarkMode ? '#adb5bd' : '#6c757d';
                    hashDisplay.style.color = newDarkMode ? '#adb5bd' : '#6c757d';
                    hashDisplay.style.backgroundColor = newDarkMode ? '#343a40' : '#f8f9fa';
                    hashDisplay.style.borderColor = newDarkMode ? '#495057' : '#dee2e6';
                }, 100);
            });
        }
    });
})();

// 去除广告弹窗和叠加层功能
(function () {
    'use strict';

    // 允许的域名列表
    const ALLOWED_DOMAINS = [
        location.hostname, // 当前网站
        'bt4g', // BT4G相关域名
        'downloadtorrentfile.com',
        'filepax.com'
    ];

    // 检查URL是否是允许的
    function isAllowedUrl(url) {
        if (!url) return false;
        // 允许磁力链接
        if (url.startsWith('magnet:')) return true;
        // 允许网站内部链接
        if (url.startsWith('/') || url.startsWith('#')) return true;
        try {
            const urlObj = new URL(url, location.origin);
            // 检查是否是允许的域名
            return ALLOWED_DOMAINS.some(domain => urlObj.hostname.includes(domain));
        } catch (e) {
            // URL解析失败,默认允许相对路径
            return !url.includes('://');
        }
    }

    // 增强版叠加层选择器
    const overlaySelectors = [
        // 常见广告层选择器
        'div[style*="position: fixed"]',
        'div[style*="z-index: 999"]',
        'div[class*="ad-"]',
        'div[class*="popup"]',
        'div[class*="overlay"]',
        'div[id*="ad-"]',
        'div[id*="popup"]',
        'div[id*="overlay"]',
        // 针对可能的弹窗广告
        'div.modal.fade.show',
        'div.modal-backdrop',
        'div[style*="pointer-events"]',
        'iframe[src*="ad"]',
        // 处理任何位置的可疑iframe
        'iframe:not([src*="bt4g"])',

        // 新增选择器 - 针对隐形覆盖层
        'div[style*="opacity: 0"]',
        'div[style*="opacity:0"]',
        'div[style*="height: 100%"][style*="width: 100%"]',
        'div[style*="top: 0"][style*="left: 0"][style*="right: 0"][style*="bottom: 0"]',
        'div[style*="cursor: pointer"]',
        'div[style*="position: absolute"][style*="width: 100%"]',
        'a[target="_blank"]:not([href^="magnet:"])',
        'a[rel*="nofollow"]',
        'a[rel*="sponsored"]',

        // 新增 - 特殊隐藏iframe
        'iframe[style*="opacity: 0"]',
        'iframe[width="1"][height="1"]',
        'iframe[style*="visibility: hidden"]'
    ];

    // 检测和删除叠加层
    function removeOverlays() {
        // 恢复被禁用的滚动
        if (document.body && document.body.style.overflow === 'hidden') {
            document.body.style.overflow = '';
        }

        // 删除匹配的叠加层
        overlaySelectors.forEach(selector => {
            try {
                const elements = document.querySelectorAll(selector);
                elements.forEach(el => {
                    if (el && isOverlay(el) && !isEssentialElement(el) && !isScriptNotification(el)) {
                        console.log('移除广告叠加层:', el);
                        el.remove();
                    }
                });
            } catch (error) {
                console.error('选择器处理错误:', selector, error);
            }
        });

        // 处理与body同级的元素
        removeBodySiblings();
    }

    // 专门处理与body同级的元素
    function removeBodySiblings() {
        // 获取documentElement的所有子元素
        const htmlChildren = Array.from(document.documentElement.children);
        // 遍历所有子元素
        for (const element of htmlChildren) {
            // 保留head和body,删除其他非法添加的元素
            if (element !== document.body && element !== document.head) {
                // 检查是否是我们自己的元素,如果不是则移除
                if (!isScriptNotification(element)) {
                    console.log('移除与body同级的非法元素:', element);
                    element.remove();
                }
            }
        }
    }

    // 判断元素是否为我们自己的通知元素
    function isScriptNotification(element) {
        // 检查是否是我们的通知元素
        return element.hasAttribute('data-bt4g-notification') ||
            element.classList.contains('toast-notification');
    }

    // 判断元素是否为叠加层(增强版)
    function isOverlay(element) {
        const style = window.getComputedStyle(element);
        const position = style.getPropertyValue('position');
        const zIndex = parseInt(style.getPropertyValue('z-index'), 10);
        const opacity = parseFloat(style.getPropertyValue('opacity'));

        // iframe特殊处理
        if (element.tagName === 'IFRAME') {
            const src = element.getAttribute('src') || '';
            // 更严格的iframe检查
            return !src.includes(location.hostname) && !src.includes('bt4g');
        }

        // 增强检测
        // 1. 检测隐形覆盖层
        const isFullPageOverlay =
            element.offsetWidth > window.innerWidth * 0.8 &&
            element.offsetHeight > window.innerHeight * 0.8;

        // 2. 检测可疑的空链接包装器
        const hasMultipleChildAnchors = element.querySelectorAll('a').length > 3;

        // 3. 检测隐藏但可点击的元素
        const isHiddenButClickable =
            (opacity === 0 || style.getPropertyValue('visibility') === 'hidden') &&
            style.getPropertyValue('pointer-events') !== 'none';

        return (
            // 原有条件
            ((position === 'fixed' || position === 'absolute') &&
                ((zIndex > 100) || (style.getPropertyValue('display') !== 'none' && opacity > 0))) ||
            // 新增条件
            isFullPageOverlay ||
            hasMultipleChildAnchors ||
            isHiddenButClickable
        );
    }

    // 判断是否为页面必要元素
    function isEssentialElement(element) {
        // 检查是否包含重要的页面功能元素
        const isNavbar = element.classList.contains('navbar') ||
            element.id === 'header' ||
            element.querySelector('.navbar');

        // 检查是否是BT4G的搜索表单或重要UI元素
        const isSearchForm = element.querySelector('form[action="/search"]') ||
            element.classList.contains('advanced-search');

        // 检查是否包含磁力按钮
        const hasMagnetButton = element.querySelector('a[href^="magnet:"]') ||
            element.querySelector('.btn-primary');

        // 检查是否是我们的通知元素
        const isNotification = isScriptNotification(element);

        return isNavbar || isSearchForm || hasMagnetButton || isNotification;
    }

    function setupNavigationProtection() {
        // 保存当前URL
        let currentUrl = window.location.href;

        // 监控URL变化(定期检查) - 修复未使用变量警告
        setInterval(() => {
            if (window.location.href !== currentUrl) {
                const newUrl = window.location.href;
                if (!isAllowedUrl(newUrl)) {
                    console.log('检测到不允许的URL变化:', newUrl);
                    window.showAdBlockerNotification?.();
                    // 尝试回退到上一个URL
                    try {
                        window.history.pushState(null, '', currentUrl);
                    } catch (e) {
                        console.log('无法回退到上一个URL:', e);
                    }
                } else {
                    // 更新当前URL
                    currentUrl = newUrl;
                }
            }
        }, 100);

        // 监听popstate事件(历史导航)
        window.addEventListener('popstate', function (e) {
            if (!isAllowedUrl(window.location.href)) {
                console.log('检测到不允许的历史导航:', window.location.href);
                window.showAdBlockerNotification?.();
                // 尝试恢复到之前的URL
                try {
                    window.history.pushState(null, '', currentUrl);
                } catch (e) {
                    console.log('无法恢复popstate导航:', e);
                }
            } else {
                currentUrl = window.location.href;
            }
        });

        // 增强beforeunload事件处理 - 移除废弃的API
        window.addEventListener('beforeunload', function (e) {
            // 检查当前活动元素
            const activeElement = document.activeElement;
            let shouldBlock = false;

            // 检查链接元素 - 使用可选链接
            const href = activeElement?.tagName === 'A' ? activeElement?.getAttribute('href') : null;
            if (href && !isAllowedUrl(href)) {
                shouldBlock = true;
                console.log('拦截beforeunload导航:', href);
            }

            // 检查表单提交 - 使用可选链接
            const action = activeElement?.form?.getAttribute('action');
            if (action && !isAllowedUrl(action)) {
                shouldBlock = true;
                console.log('拦截表单提交导航:', action);
            }

            // 使用现代标准方法阻止导航 - 不再使用returnValue
            if (shouldBlock) {
                e.preventDefault();
                window.showAdBlockerNotification?.();
            }
        }, true);

        // 监听form提交事件
        document.addEventListener('submit', function (e) {
            const form = e.target;
            const action = form.getAttribute('action') || window.location.href;
            if (!isAllowedUrl(action)) {
                e.preventDefault();
                e.stopPropagation();
                console.log('拦截表单提交:', action);
                window.showAdBlockerNotification?.();
            }
        }, true);

        // 替换有问题的Navigation API监控
        monitorPageNavigation();
    }

    // 使用更广泛支持的方法替代Navigation API
    function monitorPageNavigation() {
        // 监听所有a标签的点击事件
        document.addEventListener('click', function (e) {
            // 查找最近的a标签
            const linkElement = e.target.closest('a');
            if (linkElement) {
                const href = linkElement.getAttribute('href');
                if (href && !isAllowedUrl(href)) {
                    e.preventDefault();
                    e.stopPropagation();
                    console.log('拦截链接导航:', href);
                    window.showAdBlockerNotification?.();
                }
            }
        }, true);

        // 监听hashchange事件
        window.addEventListener('hashchange', function (e) {
            const newURL = e.newURL;
            if (newURL && !isAllowedUrl(newURL)) {
                e.preventDefault(); // 在某些浏览器中可能不起作用
                console.log('拦截hash变化导航:', newURL);
                window.showAdBlockerNotification?.();

                // 尝试恢复到上一个URL
                try {
                    window.location.hash = e.oldURL.split('#')[1] || '';
                } catch (error) {
                    console.log('无法恢复hash变化:', error);
                }
            }
        });

        // 拦截window.history方法
        try {
            const originalPushState = window.history.pushState;
            window.history.pushState = function (state, title, url) {
                if (url && !isAllowedUrl(url)) {
                    console.log('拦截history.pushState导航:', url);
                    window.showAdBlockerNotification?.();
                    return;
                }
                return originalPushState.apply(this, arguments);
            };

            const originalReplaceState = window.history.replaceState;
            window.history.replaceState = function (state, title, url) {
                if (url && !isAllowedUrl(url)) {
                    console.log('拦截history.replaceState导航:', url);
                    window.showAdBlockerNotification?.();
                    return;
                }
                return originalReplaceState.apply(this, arguments);
            };
        } catch (e) {
            console.log('无法拦截history方法:', e);
        }
    }

    // 将这个新函数添加到preventRedirects函数中
    function preventRedirects() {
        // 1. 覆盖 window.open
        if (!window.originalOpen) {
            window.originalOpen = window.open;
            window.open = function (url, name, params) {
                if (isAllowedUrl(url)) {
                    return window.originalOpen(url, name, params);
                } else {
                    console.log('拦截弹窗:', url);
                    window.showAdBlockerNotification?.();
                    return {
                        // 模拟窗口对象,防止脚本错误
                        closed: true,
                        close: function () {
                        },
                        focus: function () {
                        },
                        blur: function () {
                        }
                    };
                }
            };
        }

        // window.open的其他别名
        window.openWindow = window.open;
        window.openTab = window.open;

        // 2. 覆盖 location.href (使用描述符)
        try {
            const originalLocationHrefDescriptor = Object.getOwnPropertyDescriptor(window.Location.prototype, 'href') ||
                Object.getOwnPropertyDescriptor(location, 'href');

            if (originalLocationHrefDescriptor?.configurable) {
                Object.defineProperty(window.location, 'href', {
                    set: function (url) {
                        if (isAllowedUrl(url)) {
                            originalLocationHrefDescriptor.set.call(this, url);
                        } else {
                            console.log('拦截location.href跳转:', url);
                            window.showAdBlockerNotification?.();
                        }
                    },
                    get: originalLocationHrefDescriptor.get,
                    configurable: true
                });
            }
        } catch (e) {
            console.log('无法覆盖location.href:', e);
        }

        // 3-4. 替换原来的location.assign和replace覆盖,使用我们的新方法
        setupNavigationProtection();

        // 5. 增强 - 拦截 window 上下文
        try {
            // 防止iframe修改顶层窗口
            if (window !== window.top) {
                Object.defineProperty(window, 'top', {
                    get: function () {
                        return window;
                    }
                });
                Object.defineProperty(window, 'parent', {
                    get: function () {
                        return window;
                    }
                });
            }
        } catch (e) {
            console.log('无法覆盖window上下文属性:', e);
        }

        // 6. 拦截 window.postMessage
        const originalPostMessage = window.postMessage;
        window.postMessage = function (message, targetOrigin, transfer) {
            if (typeof message === 'object' && message) {
                // 检查消息是否包含可疑URL
                const messageString = JSON.stringify(message).toLowerCase();
                if (messageString.includes('http') || messageString.includes('url')) {
                    console.log('拦截可疑postMessage:', messageString.substring(0, 100));
                    return;
                }
            }
            return originalPostMessage.apply(this, arguments);
        };
    }

    // 增强版点击拦截 - 主要针对新标签页劫持
    function interceptLinkClicks() {
        // 使用捕获阶段拦截所有点击
        document.addEventListener('click', function (e) {
            // 1. 检查是否点击了链接
            let targetElement = e.target;
            let isBlocked = false;

            // 2. 检查点击目标及其所有父元素
            while (targetElement && targetElement !== document) {
                // 检查是否是链接
                if (targetElement.tagName === 'A') {
                    const href = targetElement.getAttribute('href');
                    if (href && !isAllowedUrl(href)) {
                        console.log('拦截链接跳转:', href);
                        e.preventDefault();
                        e.stopPropagation();
                        isBlocked = true;
                        window.showAdBlockerNotification?.();
                        break;
                    }
                }

                // 检查onclick和其他事件
                const suspiciousEventAttrs = ['onclick', 'onmousedown', 'onmouseup'];

                // 使用some()方法,可以在返回true时提前退出循环
                suspiciousEventAttrs.some(attr => {
                    const handler = targetElement.getAttribute(attr);
                    if (handler && (
                        handler.includes('window.open') ||
                        handler.includes('location') ||
                        handler.includes('http')
                    )) {
                        console.log(`拦截可疑${attr}事件:`, handler);
                        e.preventDefault();
                        e.stopPropagation();
                        isBlocked = true;
                        targetElement.removeAttribute(attr); // 立即移除事件
                        window.showAdBlockerNotification?.();
                        return true; // 相当于break
                    }
                    return false;
                });

                // 检查data属性中的URL - 如果尚未被阻止
                if (!isBlocked) {
                    // 直接使用some方法,不存储返回值
                    Array.from(targetElement.attributes).some(attr => {
                        if (attr.name.startsWith('data-') &&
                            typeof attr.value === 'string' &&
                            (attr.value.includes('http') || attr.value.includes('www.'))) {

                            if (!isAllowedUrl(attr.value)) {
                                console.log('拦截data属性中的URL:', attr.value);
                                e.preventDefault();
                                e.stopPropagation();
                                isBlocked = true;
                                return true; // 提前退出循环
                            }
                        }
                        return false;
                    });
                }

                if (isBlocked) break;
                targetElement = targetElement.parentElement;
            }

            // 3. 点击后延迟检查是否有尝试打开新窗口
            if (!isBlocked) {
                setTimeout(() => {
                    // 检查是否有新的异常iframe
                    const newIframes = document.querySelectorAll('iframe:not([data-checked])');
                    newIframes.forEach(iframe => {
                        iframe.setAttribute('data-checked', 'true');
                        const src = iframe.getAttribute('src') || '';
                        if (src && !isAllowedUrl(src)) {
                            console.log('移除可疑iframe:', src);
                            iframe.remove();
                            window.showAdBlockerNotification?.();
                        }
                    });
                }, 100);
            }
        }, true);

        // 拦截mousedown/mouseup事件 (有些广告用这些事件触发)
        ['mousedown', 'mouseup', 'auxclick', 'contextmenu'].forEach(eventType => {
            document.addEventListener(eventType, function (e) {
                const target = e.target.closest('a') || e.target;
                if (target.tagName === 'A') {
                    const href = target.getAttribute('href');
                    if (href && !isAllowedUrl(href)) {
                        console.log(`拦截${eventType}事件:`, href);
                        e.preventDefault();
                        e.stopPropagation();
                        window.showAdBlockerNotification?.();
                    }
                }
            }, true);
        });
    }

    // 阻止全局事件捕获可能导致弹窗的行为
    function preventPopupEvents() {
        // 调用增强的重定向拦截
        preventRedirects();

        // 处理链接点击
        interceptLinkClicks();

        // 阻止页面级别的点击劫持
        document.addEventListener('click', function (e) {
            // 处理非链接和按钮的全页面点击
            const isLinkOrButton = e.target.tagName === 'A' ||
                e.target.tagName === 'BUTTON' ||
                e.target.closest('a') ||
                e.target.closest('button');

            if (!isLinkOrButton && e.currentTarget === document) {
                // 检查是否点击了覆盖整个页面的元素
                const rect = e.target.getBoundingClientRect();
                const isFullPageOverlay = (rect.width > window.innerWidth * 0.9 &&
                    rect.height > window.innerHeight * 0.9);

                if (isFullPageOverlay) {
                    e.stopPropagation();
                    e.preventDefault();
                    console.log('阻止可疑的全页面点击');
                    removeOverlays();
                }
            }
        }, true); // 使用捕获阶段
    }

    // 清理可能的内联事件处理程序
    function cleanupInlineEvents() {
        // 查找并清理可疑的内联事件
        const suspiciousElements = document.querySelectorAll('[onclick], [onmousedown], [onmouseup], [onmousemove], [onload], [onunload]');
        suspiciousElements.forEach(el => {
            // 检查所有内联事件属性
            const eventAttributes = ['onclick', 'onmousedown', 'onmouseup', 'onmousemove', 'onload', 'onunload'];

            // 排除我们自己的通知元素
            if (isScriptNotification(el)) {
                return;
            }

            // 检查链接元素的目标
            if (el.tagName === 'A') {
                const href = el.getAttribute('href');
                if (href && !isAllowedUrl(href)) {
                    console.log('修改可疑链接:', href);
                    el.setAttribute('data-original-href', href);
                    el.removeAttribute('href');
                }
            }

            // 清除可疑的事件处理器
            for (const attr of eventAttributes) {
                const eventHandler = el.getAttribute(attr);
                if (eventHandler && (
                    eventHandler.includes('window.open') ||
                    eventHandler.includes('popup') ||
                    eventHandler.includes('location') ||
                    eventHandler.includes('href')
                )) {
                    console.log(`移除可疑内联事件 ${attr}:`, eventHandler);
                    el.removeAttribute(attr);
                }
            }
        });
    }

    // 防止通过特殊手段添加的脚本和iframe
    function preventDynamicElements() {
        // 1. 覆盖document.write和document.writeln
        const originalWrite = document.write;
        document.write = function (...args) {
            const content = args.join('');
            // 检查内容是否包含可疑代码
            if (content.includes('<iframe') || content.includes('window.open') ||
                content.includes('onclick') || content.includes('http')) {
                console.log('拦截可疑document.write:', content.substring(0, 100));
                return;
            }
            return originalWrite.apply(this, args);
        };
        document.writeln = document.write;

        // 2. 监控appendChild和insertBefore方法
        const originalAppendChild = Element.prototype.appendChild;
        Element.prototype.appendChild = function (node) {
            // 检查是否添加敏感元素
            if (node.nodeName === 'IFRAME' || node.nodeName === 'SCRIPT') {
                // 检查iframe的src
                if (node.nodeName === 'IFRAME') {
                    const src = node.getAttribute('src');
                    if (src && !isAllowedUrl(src)) {
                        console.log('拦截添加可疑iframe:', src);
                        return document.createElement('div'); // 返回空div代替iframe
                    }
                }

                // 检查script的内容
                if (node.nodeName === 'SCRIPT') {
                    const content = node.textContent || node.innerText || '';
                    const src = node.getAttribute('src') || '';

                    if ((content && (content.includes('window.open') || content.includes('popup'))) ||
                        (src && !isAllowedUrl(src))) {
                        console.log('拦截可疑script:', src || content.substring(0, 100));
                        return document.createElement('script'); // 返回空脚本
                    }
                }
            }
            return originalAppendChild.call(this, node);
        };

        // 同样处理insertBefore方法
        const originalInsertBefore = Element.prototype.insertBefore;
        Element.prototype.insertBefore = function (node, referenceNode) {
            // 与appendChild相同的检查逻辑
            if (node.nodeName === 'IFRAME' || node.nodeName === 'SCRIPT') {
                // 检查iframe的src
                if (node.nodeName === 'IFRAME') {
                    const src = node.getAttribute('src');
                    if (src && !isAllowedUrl(src)) {
                        console.log('拦截插入可疑iframe:', src);
                        return document.createElement('div');
                    }
                }

                // 检查script的内容
                if (node.nodeName === 'SCRIPT') {
                    const content = node.textContent || node.innerText || '';
                    const src = node.getAttribute('src') || '';

                    if ((content && (content.includes('window.open') || content.includes('popup'))) ||
                        (src && !isAllowedUrl(src))) {
                        console.log('拦截可疑script:', src || content.substring(0, 100));
                        return document.createElement('script');
                    }
                }
            }
            return originalInsertBefore.call(this, node, referenceNode);
        };
    }

    // 创建防跳转通知层
    function createBlockingLayer() {
        const style = document.createElement('style');
        style.innerHTML = `
        .ad-blocker-notification {
            position: fixed;
            bottom: 20px;
            right: 20px;
            background-color: #f8d7da;
            color: #721c24;
            border: 1px solid #f5c6cb;
            border-radius: 4px;
            padding: 10px 15px;
            box-shadow: 0 2px 5px rgba(0,0,0,0.2);
            z-index: 999999;
            font-family: Arial, sans-serif;
            max-width: 300px;
            animation: fade-in 0.3s ease-in-out;
            pointer-events: auto;
            display: none;
        }
        @keyframes fade-in {
            from { opacity: 0; }
            to { opacity: 1; }
        }
        `;
        document.head.appendChild(style);

        const notification = document.createElement('div');
        notification.className = 'ad-blocker-notification';
        notification.setAttribute('data-bt4g-notification', 'true');
        notification.textContent = '已阻止可疑广告跳转';
        document.body.appendChild(notification);

        // 显示通知的方法
        window.showAdBlockerNotification = function () {
            notification.style.display = 'block';
            setTimeout(() => {
                notification.style.display = 'none';
            }, 3000);
        };
    }

    // 主函数:初始化广告拦截器
    function initAdBlocker() {
        console.log('BT4G 增强广告拦截器已激活 - 强化新标签页防护');

        // 立即调用所有拦截函数
        removeOverlays();
        preventPopupEvents();
        cleanupInlineEvents();
        preventDynamicElements();

        // MutationObserver监视DOM变化
        const observer = new MutationObserver((mutations) => {
            // 检查是否有新增的html子节点
            const hasHtmlChildChanges = mutations.some(mutation =>
                mutation.target === document.documentElement && mutation.type === 'childList');

            if (hasHtmlChildChanges) {
                removeBodySiblings();
            }

            // 检查变化的节点
            for (const mutation of mutations) {
                // 使用可选链检查和迭代添加的节点
                mutation.addedNodes?.forEach(node => {
                    // 检查是否添加了iframe或script
                    if (node.nodeName === 'IFRAME' || node.nodeName === 'SCRIPT') {
                        // 针对iframe检查src
                        if (node.nodeName === 'IFRAME') {
                            const src = node.getAttribute('src');
                            if (src && !isAllowedUrl(src)) {
                                console.log('移除动态添加的可疑iframe:', src);
                                node.remove();
                            }
                        }
                    }
                });
            }

            removeOverlays();
            cleanupInlineEvents();
        });

        // 增强监视范围,包括document和html
        observer.observe(document.documentElement, {
            childList: true,
            subtree: true,
            attributes: true,
            attributeFilter: ['style', 'class', 'src', 'href']
        });

        // 更频繁地检查覆盖层和跳转
        setInterval(() => {
            removeOverlays();
            removeBodySiblings();
            preventRedirects();
        }, 500); // 降低间隔时间以提高检测频率

        // 鼠标移动和按键检测
        ['mousemove', 'keydown', 'scroll'].forEach(event => {
            document.addEventListener(event, () => {
                setTimeout(removeOverlays, 50);
            }, {passive: true});
        });

        // 监视iframe消息 - 修改后的版本
        window.addEventListener('message', function (event) {
            // 使用与ALLOWED_DOMAINS相同的逻辑来验证消息来源
            let isFromTrustedOrigin = false;

            try {
                // 解析消息来源的主机名
                const originHostname = new URL(event.origin).hostname;

                // 检查是否是允许的域名
                isFromTrustedOrigin = ALLOWED_DOMAINS.some(domain =>
                    originHostname === domain || originHostname.includes(domain)
                );

            } catch (e) {
                console.log('解析消息来源失败:', e);
            }

            // 如果消息来源不在信任列表中,则拒绝处理
            if (!isFromTrustedOrigin) {
                console.log('拦截来自不受信任来源的消息:', event.origin);
                return; // 不处理来自未知来源的消息
            }

            // 在验证来源后,再检查消息内容
            if (event.data && typeof event.data === 'string' &&
                (event.data.includes('http') || event.data.includes('url')) &&
                !isAllowedUrl(event.data)) {
                console.log('拦截postMessage包含的URL:', event.data.substring(0, 100));
                event.stopPropagation();
            }
        }, true);
    }

    // 在文档准备前预先拦截重定向方法
    preventRedirects();

    // 在DOM开始构建时就拦截关键行为
    document.addEventListener('readystatechange', function () {
        if (document.readyState === 'interactive' || document.readyState === 'complete') {
            removeOverlays();
            preventPopupEvents();
            preventDynamicElements();
            interceptLinkClicks();
        }
    });

    // DOMContentLoaded时启动防护
    document.addEventListener('DOMContentLoaded', () => {
        removeOverlays();
        preventPopupEvents();
        createBlockingLayer();
        preventDynamicElements();
    });

    // 立即执行这些关键防护
    interceptLinkClicks();
    preventDynamicElements();

    // 页面加载后启动完整防护
    window.addEventListener('load', initAdBlocker);
})();