Twitch Ad blocker

Blocks All twitch ads 100% of the time! Never view another ad! (UPDATED) - Haven't tested, so may or may not work.

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==UserScript==
// @name         Twitch Ad blocker
// @namespace    http://tampermonkey.net/
// @version      V9
// @description  Blocks All twitch ads 100% of the time! Never view another ad! (UPDATED) - Haven't tested, so may or may not work.
// @author       NotYou (Gabriel Underwood)
// @match        https://www.twitch.tv/*
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

    // Function to check if element contains ad blocker detection text
    function hasAdBlockerText(element) {
        const text = element.textContent.toLowerCase();
        return text.includes('remove') || text.includes('ad blocker') || text.includes('adblocker') || 
               text.includes('disable your ad blocker') || text.includes('turn off ad blocker') ||
               text.includes('please disable') || text.includes('detected ad blocker');
    }

    // Function to check if element is a legitimate overlay (chat, controls, etc.)
    function isLegitimateOverlay(element) {
        const classList = element.className.toLowerCase();
        const id = element.id.toLowerCase();
        
        // Allow chat and overlay controls
        const allowedPatterns = [
            'chat',
            'control',
            'button',
            'menu',
            'tooltip',
            'dropdown',
            'modal',
            'notification',
            'alert',
            'popup-menu',
            'context-menu',
            'player-controls',
            'stream-info',
            'follow-button',
            'subscribe-button'
        ];
        
        return allowedPatterns.some(pattern => 
            classList.includes(pattern) || id.includes(pattern)
        );
    }

    // Function to check if element is covering significant screen area
    function isCoveringScreen(element) {
        const rect = element.getBoundingClientRect();
        const viewport = {
            width: window.innerWidth,
            height: window.innerHeight
        };
        
        // Consider it covering if it's large and positioned absolutely/fixed
        const style = window.getComputedStyle(element);
        const isOverlay = style.position === 'fixed' || style.position === 'absolute';
        const isLarge = rect.width > viewport.width * 0.3 || rect.height > viewport.height * 0.3;
        const isFullScreen = rect.width > viewport.width * 0.8 && rect.height > viewport.height * 0.8;
        
        return isOverlay && (isLarge || isFullScreen);
    }

    // Main function to remove unwanted overlays
    function removeUnwantedOverlays() {
        const allElements = document.querySelectorAll('*');
        
        allElements.forEach(element => {
            // Instantly remove anything with ad blocker detection text
            if (hasAdBlockerText(element)) {
                console.log('Removed ad blocker detection element:', element);
                element.remove();
                return;
            }
            
            // Remove elements covering the screen that aren't legitimate overlays
            if (isCoveringScreen(element) && !isLegitimateOverlay(element)) {
                // Additional check for common ad overlay patterns
                const classList = element.className.toLowerCase();
                const suspiciousPatterns = [
                    'overlay',
                    'interstitial',
                    'banner',
                    'popup',
                    'modal',
                    'dialog'
                ];
                
                const isSuspicious = suspiciousPatterns.some(pattern => classList.includes(pattern));
                
                if (isSuspicious) {
                    console.log('Removed suspicious overlay:', element);
                    element.remove();
                }
            }
        });
    }

    // Run immediately
    removeUnwantedOverlays();

    // Run when DOM is ready
    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', removeUnwantedOverlays);
    }

    // Run when page is fully loaded
    window.addEventListener('load', removeUnwantedOverlays);

    // Continuously monitor for new elements (ads can be dynamically loaded)
    const observer = new MutationObserver((mutations) => {
        mutations.forEach((mutation) => {
            mutation.addedNodes.forEach((node) => {
                if (node.nodeType === 1) { // Element node
                    // Check the new node itself
                    if (hasAdBlockerText(node)) {
                        console.log('Removed new ad blocker detection element:', node);
                        node.remove();
                        return;
                    }
                    
                    if (isCoveringScreen(node) && !isLegitimateOverlay(node)) {
                        console.log('Removed new overlay element:', node);
                        node.remove();
                        return;
                    }
                    
                    // Check children of the new node
                    const children = node.querySelectorAll('*');
                    children.forEach(child => {
                        if (hasAdBlockerText(child)) {
                            console.log('Removed nested ad blocker detection element:', child);
                            child.remove();
                        } else if (isCoveringScreen(child) && !isLegitimateOverlay(child)) {
                            console.log('Removed nested overlay element:', child);
                            child.remove();
                        }
                    });
                }
            });
        });
    });

    // Start observing
    observer.observe(document.body || document.documentElement, {
        childList: true,
        subtree: true
    });

    // Also run periodically as a backup
    setInterval(removeUnwantedOverlays, 2000);

    console.log('Twitch Screen Overlay Blocker is active');
})();