Blocks ads and makes the reward countdown nearly instant
// ==UserScript==
// @name ZeroAd: AdinPlay
// @namespace https://greasyfork.org/users/zeroadfinal
// @version 1.0.0
// @description Blocks ads and makes the reward countdown nearly instant
// @author ZeroAd Team
// @match *://*/*
// @grant none
// @run-at document-start
// @license MIT
// ==/UserScript==
(function() {
'use strict';
const MAX_DELAY_MS = 100; // Cap all timers to this value
const CLEANUP_INTERVAL = 1000; // How often we remove ad iframes
// ═══════════════════════════════════════════════════════
// 1. BLOCK ALL AD‑DELIVERY DOMAINS
// ═══════════════════════════════════════════════════════
const BLOCKED_DOMAINS = [
'pubads.g.doubleclick.net',
'securepubads.g.doubleclick.net',
'cpmstar.com',
'openx.net',
'casalemedia.com',
'richaudience.com',
'adnxs.com',
'rubiconproject.com',
'pubmatic.com',
'unrulymedia.com',
'googlesyndication.com',
'doubleclick.net',
'googleadservices.com',
'googletagmanager.com',
'googletagservices.com',
'imasdk.googleapis.com'
];
const isBlocked = url => BLOCKED_DOMAINS.some(d => String(url).toLowerCase().includes(d));
// Override src setters for iframes and scripts
const iframeSrcDesc = Object.getOwnPropertyDescriptor(HTMLIFrameElement.prototype, 'src');
const scriptSrcDesc = Object.getOwnPropertyDescriptor(HTMLScriptElement.prototype, 'src');
if (iframeSrcDesc?.set) {
Object.defineProperty(HTMLIFrameElement.prototype, 'src', {
set(val) { iframeSrcDesc.set.call(this, isBlocked(val) ? '' : val); },
get() { return iframeSrcDesc.get.call(this); },
configurable: true
});
}
if (scriptSrcDesc?.set) {
Object.defineProperty(HTMLScriptElement.prototype, 'src', {
set(val) { scriptSrcDesc.set.call(this, isBlocked(val) ? '' : val); },
get() { return scriptSrcDesc.get.call(this); },
configurable: true
});
}
// Patch document.createElement to catch dynamic elements
const origCreateElement = document.createElement.bind(document);
document.createElement = function(tag, options) {
const el = origCreateElement(tag, options);
if (tag.toLowerCase() === 'iframe' || tag.toLowerCase() === 'script') {
let srcVal = '';
Object.defineProperty(el, 'src', {
set(val) { srcVal = isBlocked(val) ? '' : val; this.setAttribute('src', srcVal); },
get() { return srcVal; },
configurable: true
});
// If the element was created with a src attribute, apply the filter immediately
const existing = el.getAttribute('src');
if (existing) el.src = existing;
}
return el;
};
// Periodically remove any ad iframes that slipped through
setInterval(() => {
document.querySelectorAll('iframe').forEach(iframe => {
if (isBlocked(iframe.src)) iframe.remove();
});
// Hide known ad containers
document.querySelectorAll('#videoad, .aip-video, [class*="adinplay"]').forEach(el => {
el.style.display = 'none';
el.innerHTML = '';
});
}, CLEANUP_INTERVAL);
// ═══════════════════════════════════════════════════════
// 2. SPEED UP THE COUNTDOWN BY HIJACKING TIMERS
// ═══════════════════════════════════════════════════════
const originalSetTimeout = window.setTimeout;
const originalSetInterval = window.setInterval;
window.setTimeout = function(fn, delay, ...args) {
if (delay > MAX_DELAY_MS) delay = MAX_DELAY_MS;
return originalSetTimeout.call(this, fn, delay, ...args);
};
window.setInterval = function(fn, delay, ...args) {
if (delay > MAX_DELAY_MS) delay = MAX_DELAY_MS;
return originalSetInterval.call(this, fn, delay, ...args);
};
// ═══════════════════════════════════════════════════════
// 3. AUTO‑DISMISS ANY LOADING OVERLAY
// ═══════════════════════════════════════════════════════
function dismissOverlay() {
const buttons = document.querySelectorAll('button, [role="button"], div[class*="close"], span[class*="close"]');
for (const btn of buttons) {
if (btn.textContent.match(/close|cancel|×|skip|continue/i)) {
btn.click();
break;
}
}
}
setInterval(dismissOverlay, 2000);
// ═══════════════════════════════════════════════════════
// 4. FIRE REWARD EVENTS CONTINUOUSLY (safety net)
// ═══════════════════════════════════════════════════════
setInterval(() => {
try {
window.dispatchEvent(new CustomEvent('rewardedComplete', { bubbles: true }));
window.dispatchEvent(new CustomEvent('rewardGranted', { bubbles: true }));
} catch(e) {}
}, 500);
})();