// ==UserScript== // @name RafBlocker // @namespace http://tampermonkey.net/ // @version 1.2 // @description Aggressively blocks YouTube ads and attempts to suppress the AdBlock warning by forcing the player state and instantly hiding the modal. // @author Raf // @match *://www.youtube.com/* // @grant none // @run-at document-idle // @license MIT // @downloadURL https://update.greasyfork.icu/scripts/553492/RafBlocker.user.js // @updateURL https://update.greasyfork.icu/scripts/553492/RafBlocker.meta.js // ==/UserScript== /* * MIT License * * Copyright (c) 2025 Raf (or your chosen name) * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ (function() { 'use strict'; // --- Configuration and Selectors --- const AD_CONTAINER_SELECTOR = '.ad-container, .video-ads, .ytp-ad-module'; const SKIP_BUTTON_SELECTOR = '.ytp-ad-skip-button, .ytp-skip-ad-button'; const AD_OVERLAY_SELECTOR = '.ytp-player-content-container .ytp-ce-element, .ytp-ad-overlay-container, .ytp-ad-image-overlay'; // Aggressive selectors for the warning modal and backdrop const WARNING_MODAL_SELECTOR = 'ytd-popup-container, #popup, .yt-spec-general-modal, tp-yt-paper-dialog'; const DISMISS_BUTTON_SELECTOR = 'ytd-button-renderer button.ytd-popup-container, ytd-button-renderer button.yt-spec-general-modal'; // --- Core Functions --- // Function to remove elements from the DOM function removeElement(selector) { document.querySelectorAll(selector).forEach(element => { if (element) { element.remove(); } }); } // Function to skip the video ad (works on pre-roll/mid-roll) function skipVideoAd() { const skipButton = document.querySelector(SKIP_BUTTON_SELECTOR); if (skipButton) { skipButton.click(); return true; } const videoPlayer = document.querySelector('video'); const adShowing = document.querySelector('.ad-showing'); // Check if an ad is clearly marked as playing and try to jump to the end if (videoPlayer && adShowing) { videoPlayer.currentTime = videoPlayer.duration; return true; } return false; } // --- Ad Block Warning Evasion (The Core Fix) --- function evadeAdDetection() { // 1. Aggressively Hide the Modal and Backdrop via CSS let style = document.getElementById('RafBlockerStyle'); if (!style) { style = document.createElement('style'); style.id = 'RafBlockerStyle'; style.type = 'text/css'; document.head.appendChild(style); } // Keep the modal hidden and restore scrolling style.innerHTML = ` ${WARNING_MODAL_SELECTOR} { display: none !important; visibility: hidden !important; } body { overflow: auto !important; } `; // 2. Click any hidden dismiss buttons just in case document.querySelectorAll(DISMISS_BUTTON_SELECTOR).forEach(button => { if (button.innerText.toUpperCase().includes('DISMISS') || button.innerText.toUpperCase().includes('CLOSE')) { button.click(); } }); // 3. Forcing Player State (Most important part for persistent warnings) // This attempts to trick YouTube's internal ad-check functions. if (window.ytplayer) { // Force the player to believe the ad has timed out or is already skipped if (window.ytplayer.config.args) { window.ytplayer.config.args.advideo = 0; // Standard ad flag window.ytplayer.config.args.is_ad = false; // Is Ad flag window.ytplayer.config.args.ad_flags = 0; // Ad flags } // Also check for the global Player object (if available) const player = document.querySelector('#movie_player'); if (player && player.getPlayerState) { // If the player is paused (state 2) due to the warning, try to play it (state 1 is playing) if (player.getPlayerState() === 2) { player.playVideo(); } } } } // --- Main Blocking Loop --- function blockAdsAndWarning() { // Always run evasion first to catch the warning instantly evadeAdDetection(); // Standard ad removal removeElement(AD_CONTAINER_SELECTOR); removeElement(AD_OVERLAY_SELECTOR); // Attempt to skip the video ad skipVideoAd(); } // Use a MutationObserver for dynamic content loading const observer = new MutationObserver((mutations, obs) => { // Only run the logic if we're on a YouTube page blockAdsAndWarning(); }); // Start observing the body for changes observer.observe(document.body, { childList: true, subtree: true }); // Also run blockAdsAndWarning on a rapid interval for aggressive ad/warning removal setInterval(blockAdsAndWarning, 100); // Check every 100 milliseconds for maximum speed })();