草榴社区优化脚本 v2.9.1

[v2.9.1] A comprehensive optimization script for t66y.com, featuring ad-blocking, anti-adblock bypass, media fixes, short post filtering, and auto-expansion of content.

K instalaci tototo skriptu si budete muset nainstalovat rozšíření jako Tampermonkey, Greasemonkey nebo Violentmonkey.

K instalaci tohoto skriptu si budete muset nainstalovat rozšíření jako Tampermonkey nebo Violentmonkey.

K instalaci tohoto skriptu si budete muset nainstalovat rozšíření jako Tampermonkey nebo Violentmonkey.

K instalaci tohoto skriptu si budete muset nainstalovat rozšíření jako Tampermonkey nebo Userscripts.

You will need to install an extension such as Tampermonkey to install this script.

K instalaci tohoto skriptu si budete muset nainstalovat manažer uživatelských skriptů.

(Už mám manažer uživatelských skriptů, nechte mě ho nainstalovat!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(Už mám manažer uživatelských stylů, nechte mě ho nainstalovat!)

// ==UserScript==
// @name         草榴社区优化脚本 v2.9.1
// @name:zh-CN   草榴社区优化脚本 v2.9.1
// @namespace    caoliu-optimizer-script
// @version      2.9.1
// @description  [v2.9.1] A comprehensive optimization script for t66y.com, featuring ad-blocking, anti-adblock bypass, media fixes, short post filtering, and auto-expansion of content.
// @description:zh-CN  (v2.9.1) 修复元数据错误。集广告过滤、反屏蔽、图片/视频修复、短回复过滤、内容自动展开等多功能于一身,旨在提供极致、清爽、流畅的草榴社区浏览体验。修复了评论展开问题并新增原图链接功能。
// @author       Gemini-Pro
// @match        *://*.t66y.com/*
// @match        *://t66y.com/*
// @match        *://*.t66y.com/thread*
// @match        *://*/htm_data/*/*.html
// @grant        none
// @run-at       document-start
// @license      MIT
// ==/UserScript==

(function() {
    'use strict';

    // --- 核心配置 ---
    const CONFIG = {
        // 楼层内容少于或等于 N 个字将被折叠 (0 表示不启用)
        MIN_POST_LENGTH: 5,
        // 调试模式,开启后会在控制台输出脚本信息
        DEBUG_MODE: false
    };

    /**
     * =================================================================
     * 阶段一: 页面加载前执行 (Run at document-start)
     * 目标: 抢在网站本身的恶意脚本执行前,进行主动防御。
     * =================================================================
     */

    // 关键防御:定义一个假的恶意函数,让网站的反广告屏蔽机制失效
    // 这是对抗 "去广告插件屏蔽" 提示的第一道防线
    try {
        Object.defineProperty(window, 'r9aeadS', {
            value: () => {
                log('已成功拦截恶意函数 r9aeadS 的执行。');
            },
            writable: false,
            configurable: false
        });
        Object.defineProperty(window, 'adhtml', {
            value: () => {
                log('已成功拦截恶意函数 adhtml 的执行。');
            },
            writable: false,
            configurable: false
        });
    } catch (e) {
        error('拦截恶意函数失败:', e);
    }


    /**
     * =================================================================
     * 阶段二: DOM 加载完成后执行
     * 目标: 对页面元素进行全面的清理、修复和功能增强。
     * =================================================================
     */
    document.addEventListener('DOMContentLoaded', () => {
        log('v2.9.1 脚本开始执行...');

        // 执行所有优化函数
        runAllOptimizations();

        // 设置一个动态内容监视器(哨兵),应对翻页等异步内容加载
        // 这是确保所有功能在页面变化后依然有效的核心
        const observer = new MutationObserver(mutations => {
            let shouldRun = false;
            for (const mutation of mutations) {
                if (mutation.addedNodes.length > 0) {
                    // 检查添加的节点是否是楼层元素,避免不必要的重复执行
                    if (Array.from(mutation.addedNodes).some(node => node.nodeType === 1 && node.querySelector('.t_row_1, #main'))) {
                        shouldRun = true;
                        break;
                    }
                }
            }
            if (shouldRun) {
                log('检测到页面内容变化,重新执行优化...');
                runAllOptimizations();
            }
        });

        const mainContent = document.querySelector('#main');
        if (mainContent) {
            observer.observe(mainContent, {
                childList: true,
                subtree: true
            });
        }

        log('动态内容监视器已启动。');
    });


    /**
     * =================================================================
     * 核心优化功能函数库
     * =================================================================
     */

    /**
     * 主调度函数,按顺序执行所有优化
     */
    function runAllOptimizations() {
        log('--- 开始新一轮全面优化 ---');
        removeAnnoyingElements();
        filterShortPosts();
        fixMediaContent();
        addOriginalImageLinks();
        autoExpandContent();
        deobfuscateLinks();
        log('--- 本轮优化执行完毕 ---');
    }

    /**
     * 1. 广告和干扰元素移除
     * - 移除顶部、底部、帖子内部等所有已知广告位。
     * - 移除 "去广告插件屏蔽" 的告警提示DIV(第二道防线)。
     */
    function removeAnnoyingElements() {
        const selectors = [
            '#header > div.banner > center', // 顶部横幅广告
            '#main > div.t > table.t_msg > tbody > tr > th > b', // 帖子内 "百万影院" 这类文字广告
            'div[class="tac"]', // 帖子下方的一系列广告容器
            'div.ftad-ct', // 页脚滚动广告
            '#main > div.t:not([id])', // 页面中没有ID的顶层div广告块
            '.t_row_1 > .tiptop > .tips', // “去广告插件屏蔽”的告警提示
            '#cnzz_stat_icon_1278893455', // cnzz统计图标
            'a[href*="a.app"]', // APP推广链接
            'a[href*="ysos8.com"]', // 广告链接
            'a[href*="bkmh.me"]' // 广告链接
        ];

        document.querySelectorAll(selectors.join(', ')).forEach(el => {
            log('移除广告/干扰元素:', el);
            el.remove();
        });
    }

    /**
     * 2. 短回复过滤(带主楼保护)
     * - 自动隐藏所有内容长度小于等于设定值的楼层。
     * - 智能保护,确保主楼(第一个帖子)永远不会被隐藏。
     */
    function filterShortPosts() {
        if (CONFIG.MIN_POST_LENGTH <= 0) return;

        const posts = document.querySelectorAll('.t_row_1');
        posts.forEach((post, index) => {
            // index === 0 是主楼,跳过不处理
            if (index === 0) return;

            const content = post.querySelector('.tpc_content');
            if (content && content.innerText.trim().length <= CONFIG.MIN_POST_LENGTH) {
                log(`隐藏短回复 (字数: ${content.innerText.trim().length}):`, post);
                post.style.display = 'none';
            }
        });
    }

    /**
     * 3. 媒体内容修复
     * - 修复因懒加载导致的图片不显示问题。
     * - 修复 thumbsnap.com 视频跳转,使其能直接播放。
     */
    function fixMediaContent() {
        // 修复图片懒加载
        document.querySelectorAll('img[ess-data]').forEach(img => {
            const realSrc = img.getAttribute('ess-data');
            if (realSrc) {
                img.src = realSrc;
                img.removeAttribute('ess-data');
                log('修复懒加载图片:', img);
            }
        });

        // 修复 thumbsnap 视频跳转
        document.querySelectorAll("video[src*='thumbsnap.com/i/']").forEach(video => {
            const originalSrc = video.getAttribute('src');
            if (originalSrc && !originalSrc.includes('cdn2.thumbsnap.com')) {
                const newSrc = originalSrc.replace('thumbsnap.com/i/', 'cdn2.thumbsnap.com/i/87/53/'); // 使用一个可用的CDN前缀
                video.src = newSrc;
                log(`修复视频链接: ${originalSrc} -> ${newSrc}`);
            }
        });
    }

    /**
     * 4. 为图片添加原图链接和点击图标
     * - 在帖子内的每张图片下方,生成一个可点击的“原图链接”。
     * - 在图片左上角添加一个图标,点击可直接打开原图。
     */
    function addOriginalImageLinks() {
        document.querySelectorAll('.tpc_content img:not([data-processed="true"])').forEach(img => {
            img.dataset.processed = 'true'; // 添加处理标记,防止重复添加

            const originalUrl = img.src;

            // 创建一个新的div作为包裹容器,用于相对定位
            const wrapper = document.createElement('div');
            wrapper.style.position = 'relative';
            wrapper.style.display = 'inline-block';

            // 创建左上角的图标链接
            const iconLink = document.createElement('a');
            iconLink.href = originalUrl;
            iconLink.target = '_blank';
            iconLink.title = '在新标签页中打开原图';
            iconLink.innerHTML = '&#128279;'; // 链接符号 emoji
            Object.assign(iconLink.style, {
                position: 'absolute',
                top: '5px',
                left: '5px',
                zIndex: '10',
                fontSize: '20px',
                color: 'white',
                textDecoration: 'none',
                textShadow: '0 0 4px black, 0 0 4px black' // 加强阴影,使其在任何背景下都可见
            });

            // 创建图片下方的文字链接
            const textLink = document.createElement('a');
            textLink.href = originalUrl;
            textLink.target = '_blank';
            textLink.textContent = '【点击此处查看原图】';
            Object.assign(textLink.style, {
                display: 'block',
                fontWeight: 'bold',
                color: '#E53333',
                marginTop: '5px',
                textAlign: 'center'
            });

            // DOM 操作:将图片放入包裹容器,再添加图标和文字链接
            img.parentNode.insertBefore(wrapper, img);
            wrapper.appendChild(img);
            wrapper.appendChild(iconLink);
            // 将文字链接插入到包裹容器之后
            wrapper.parentNode.insertBefore(textLink, wrapper.nextSibling);

            log('为图片添加原图链接:', img);
        });
    }


    /**
     * 5. [修复] 内容自动展开
     * - 自动点击“還有 X 條點評”,展开被折叠的楼中楼评论。
     * - 自动展开被隐藏的视频等内容。
     */
    function autoExpandContent() {
        // 展开楼中楼评论
        document.querySelectorAll('div[onclick="show_tpc(this)"]').forEach(el => {
             if (el.style.display !== 'none') {
                log('自动展开评论:', el);
                el.click();
             }
        });

        // 展开其他可能被隐藏的内容 (例如一些需要点击才能加载的视频)
        // 可根据需要添加更多选择器
        const otherExpandableSelectors = [
            // '.some-other-hidden-content-selector'
        ];
        if (otherExpandableSelectors.length > 0) {
            document.querySelectorAll(otherExpandableSelectors.join(',')).forEach(el => el.click());
        }
    }


    /**
     * 6. 下载链接反混淆 (占位)
     * - 此处为未来功能保留,用于处理复杂的跳转和加密链接。
     */
    function deobfuscateLinks() {
        // 示例:将所有指向 "down.com" 的链接的 URL 参数进行解码
        document.querySelectorAll("a[href*='down.com']").forEach(link => {
            // 此处添加具体的反混淆逻辑
        });
    }


    /**
     * =================================================================
     * 辅助函数
     * =================================================================
     */

    /**
     * 日志输出函数,仅在调试模式开启时输出
     * @param {...any} args - 需要打印的日志内容
     */
    function log(...args) {
        if (CONFIG.DEBUG_MODE) {
            console.log('[草榴优化脚本]', ...args);
        }
    }

    /**
     * 错误输出函数
     * @param {...any} args - 需要打印的错误内容
     */
    function error(...args) {
        console.error('[草榴优化脚本]', ...args);
    }

})();