Greasy Fork

Greasy Fork is available in English.

Anti-Adblock Killer (Safe + Exceptions + Hotkeys)

Neutralizes adblock detection scripts without breaking major websites. Includes hotkeys for adding/removing exceptions (Ctrl+Shift+E / Ctrl+Shift+X).

当前为 2025-11-19 提交的版本,查看 最新版本

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name         Anti-Adblock Killer (Safe + Exceptions + Hotkeys)
// @namespace    https://tampermonkey.net/
// @version      3.2
// @description  Neutralizes adblock detection scripts without breaking major websites. Includes hotkeys for adding/removing exceptions (Ctrl+Shift+E / Ctrl+Shift+X).
// @author       TAUÃ B. KLOCH LEITE
// @match        *://*/*
// @license      GPL-3.0
// @grant        none
// ==/UserScript==

(function () {
    'use strict';

    /* -------------------------------
       Storage & defaults
    ------------------------------- */
    const STORAGE_KEY = 'antiAdblockExceptions';
    const DEFAULT_EXCEPTIONS = [
        "google",
        "youtube",
        "greasyfork.org",
        "instagram",
        "whatsapp",
        "reddit",
        "github",
        "x.com",
        "twitter",
        "tiktok",
        "wikipedia",
        "linkedin",
        "amazon",
        "netflix",
        "hbo",
        "disney",
        "spotify",
        "paypal",
        "microsoft",
        "office",
        "live",
        "outlook",
        "steam",
        "epicgames",
        "roblox",
        "discord",
        "twitch"
    ];

    // load saved exceptions (user edits persist)
    let exceptions;
    try {
        const saved = localStorage.getItem(STORAGE_KEY);
        exceptions = saved ? JSON.parse(saved) : DEFAULT_EXCEPTIONS.slice();
        if (!Array.isArray(exceptions)) exceptions = DEFAULT_EXCEPTIONS.slice();
    } catch (e) {
        exceptions = DEFAULT_EXCEPTIONS.slice();
    }

    function saveExceptions() {
        try { localStorage.setItem(STORAGE_KEY, JSON.stringify(exceptions)); } catch(e){}
    }

    /* -------------------------------
       Helper: normalized hostname & matching
    ------------------------------- */
    function normalizeHost(h) {
        if (!h) return '';
        return h.toLowerCase().replace(/^www\./, '').trim();
    }
    const currentHost = normalizeHost(window.location.hostname);

    // returns exception that matches this host (or undefined)
    function findMatchingExceptionForHost(host) {
        for (const ex of exceptions) {
            const exNorm = ex.toLowerCase().replace(/^www\./, '').trim();
            if (!exNorm) continue;
            if (host === exNorm) return ex;                     // exact
            if (host.endsWith('.' + exNorm)) return ex;         // subdomain
            if (host.includes(exNorm)) return ex;               // fallback substring (keeps behavior compatible)
        }
        return undefined;
    }

    /* -------------------------------
       HOTKEYS: register BEFORE early-return so remove works on exception sites
       Ctrl+Shift+E => add current site to exceptions
       Ctrl+Shift+X => remove current site from exceptions
    ------------------------------- */
    document.addEventListener('keydown', (ev) => {
        // require ctrl + shift
        if (!ev.ctrlKey || !ev.shiftKey) return;

        // normalize current host on key press (fresh)
        const hostNow = normalizeHost(window.location.hostname);

        // ADD: Ctrl + Shift + E
        if (ev.key.toLowerCase() === 'e') {
            ev.preventDefault();
            const existing = findMatchingExceptionForHost(hostNow);
            if (existing) {
                alert(`This site is already in exceptions: ${existing}`);
                return;
            }
            // save normalized host (without www) so matching works consistently
            exceptions.push(hostNow);
            saveExceptions();
            alert(`Added to exceptions: ${hostNow}\nReload page to apply.`);
            return;
        }

        // REMOVE: Ctrl + Shift + X
        if (ev.key.toLowerCase() === 'x') {
            ev.preventDefault();
            const match = findMatchingExceptionForHost(hostNow);
            if (!match) {
                alert(`This site is not in exceptions:\n${hostNow}`);
                return;
            }
            // remove all entries that equal match (keeps duplicates cleared)
            exceptions = exceptions.filter(e => {
                const eNorm = e.toLowerCase().replace(/^www\./, '').trim();
                return eNorm !== match.toLowerCase().replace(/^www\./, '').trim();
            });
            saveExceptions();
            alert(`Removed from exceptions: ${match}\nReload page to apply.`);
            return;
        }
    }, true);

    /* -------------------------------
       Now check exception list
    ------------------------------- */
    const matched = findMatchingExceptionForHost(currentHost);
    if (matched) {
        console.log(`[Anti-Adblock Killer] Exception applied for: ${currentHost} (matched '${matched}')`);
        // do not run the anti-adblock remover on this site
        return;
    }

    /* -------------------------------
       The original working behavior 
    ------------------------------- */

    // Neutralize known adblock detection scripts
    try {
        Object.defineProperty(window, 'FuckAdBlock', { value: function(){}, writable: false });
    } catch(e){}
    try {
        Object.defineProperty(window, 'BlockAdBlock', { value: function(){}, writable: false });
    } catch(e){}

    // Block future adblock detection scripts from executing
    const blockScripts = ["fuckadblock", "blockadblock", "adblock-detector"];
    const observer = new MutationObserver((mutations) => {
        for (const mutation of mutations) {
            mutation.addedNodes.forEach(node => {
                try {
                    if (node.tagName === 'SCRIPT') {
                        const src = (node.src || '').toLowerCase();
                        if (blockScripts.some(s => src.includes(s))) {
                            node.type = 'javascript/blocked';
                            node.remove();
                            console.log('Blocked an anti-adblock script:', src);
                        }
                    }
                } catch(e){}
            });
        }
    });
    observer.observe(document.documentElement, { childList: true, subtree: true });

    // Remove visual "disable adblock" messages
    const removeWarnings = () => {
        const warningKeywords = ['adblock', 'disable', 'whitelist', 'bloqueador'];
        document.querySelectorAll('div,section,aside,dialog').forEach(el => {
            try {
                if (warningKeywords.some(k => (el.textContent || '').toLowerCase().includes(k))) {
                    el.style.display = 'none';
                }
            } catch(e){}
        });
    };
    setInterval(removeWarnings, 1500);

    console.log('✅ Anti-Adblock Killer is active (hotkeys enabled)');
})();