ZeroAd: CrazyGames

Complete fake CrazyGames environment for all SDK versions & wrappers

Tendrás que instalar una extensión para tu navegador como Tampermonkey, Greasemonkey o Violentmonkey si quieres utilizar este script.

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

Tendrás que instalar una extensión como Tampermonkey o Violentmonkey para instalar este script.

Necesitarás instalar una extensión como Tampermonkey o Userscripts para instalar este script.

Tendrás que instalar una extensión como Tampermonkey antes de poder instalar este script.

Necesitarás instalar una extensión para administrar scripts de usuario si quieres instalar este script.

(Ya tengo un administrador de scripts de usuario, déjame instalarlo)

Advertisement:

Tendrás que instalar una extensión como Stylus antes de poder instalar este script.

Tendrás que instalar una extensión como Stylus antes de poder instalar este script.

Tendrás que instalar una extensión como Stylus antes de poder instalar este script.

Para poder instalar esto tendrás que instalar primero una extensión de estilos de usuario.

Para poder instalar esto tendrás que instalar primero una extensión de estilos de usuario.

Para poder instalar esto tendrás que instalar primero una extensión de estilos de usuario.

(Ya tengo un administrador de estilos de usuario, déjame instalarlo)

Advertisement:

// ==UserScript==
// @name         ZeroAd: CrazyGames
// @namespace    https://greatest.deepsurf.us/users/YOUR_USER_ID
// @version      6.2.1
// @description  Complete fake CrazyGames environment for all SDK versions & wrappers
// @author       ZeroAd Team
// @match        *://*.crazygames.com/*
// @match        *://crazygames.com/*
// @grant        none
// @run-at       document-start
// @license      MIT
// ==/UserScript==

(function() {
    'use strict';

    if (window.__zeroAdInstalled) return;
    window.__zeroAdInstalled = true;

    const CONFIG = {
        DEBUG: false,
        REWARD_DELAY_MS: 10,   // 0.1s – fast enough to feel instant, safe for game unpause
        SIMULATE_AD_ERROR: false
    };

    const log = (...args) => CONFIG.DEBUG && console.log('[ZeroAd]', ...args);
    const warn = (...args) => CONFIG.DEBUG && console.warn('[ZeroAd]', ...args);

    const hookState = {
        adModulePatched: false,
        interceptedCalls: 0
    };

    // ────────────────────────────────────────────────
    //  Patch the AdModule object
    // ────────────────────────────────────────────────
    function patchAdModule(ad) {
        if (!ad || ad.__zaPatched) return;
        ad.__zaPatched = true;

        // Override requestAd
        ad.requestAd = async function(adType, callbacks = {}) {
            hookState.interceptedCalls++;
            log(`✓ INTERCEPTED: SDK.ad.requestAd("${adType}")`);

            if (CONFIG.SIMULATE_AD_ERROR) {
                if (typeof callbacks.adError === 'function') {
                    try { callbacks.adError({ code: 'INTERNAL_ERROR', message: 'Simulated error' }); } catch(e) {}
                }
                return;
            }

            // Fire adStarted (game's callback will handle pointer lock)
            if (typeof callbacks.adStarted === 'function') {
                try { callbacks.adStarted(); } catch(e) {}
            }
            log('  → adStarted fired');

            // After a short delay, fire adFinished
            return new Promise(resolve => {
                setTimeout(() => {
                    if (typeof callbacks.adFinished === 'function') {
                        try { callbacks.adFinished(); } catch(e) {}
                    }
                    log('  → adFinished fired');
                    log(`  → ✅ Reward granted for "${adType}"`);
                    resolve();
                }, CONFIG.REWARD_DELAY_MS);
            });
        };

        // Stub other ad methods
        if (ad.prefetchAd) ad.prefetchAd = () => Promise.resolve();
        if (ad.hasAdblock) ad.hasAdblock = () => Promise.resolve(false);
        if (ad.hasAdblockEnabled) ad.hasAdblockEnabled = () => Promise.resolve(false);

        hookState.adModulePatched = true;
        log('✓ SDK.ad fully patched');
    }

    // ────────────────────────────────────────────────
    //  Attempt to patch immediately or wait for SDK
    // ────────────────────────────────────────────────
    function attemptPatch() {
        if (hookState.adModulePatched) return;
        if (window.CrazyGames?.SDK?.ad) {
            patchAdModule(window.CrazyGames.SDK.ad);
        }
    }

    // ────────────────────────────────────────────────
    //  Watch for SDK script injection
    // ────────────────────────────────────────────────
    const observer = new MutationObserver(mutations => {
        for (const mutation of mutations) {
            for (const node of mutation.addedNodes) {
                if (node.tagName === 'SCRIPT' && node.src && node.src.includes('crazygames-sdk')) {
                    log('SDK script detected');
                    node.addEventListener('load', () => {
                        log('SDK loaded – patching...');
                        setTimeout(() => {
                            attemptPatch();
                            if (hookState.adModulePatched) {
                                observer.disconnect();
                                log('✓ Observer disconnected');
                            }
                        }, 0);
                    });
                }
            }
        }
    });
    observer.observe(document.documentElement, { childList: true, subtree: true });

    attemptPatch();

    // Fallback retries
    let retries = 0;
    const interval = setInterval(() => {
        if (hookState.adModulePatched || retries > 50) {
            clearInterval(interval);
            return;
        }
        attemptPatch();
        retries++;
    }, 200);

    // Legacy CrazygamesAds fallback
    function patchCrazygamesAds(ads) {
        if (!ads || ads.__zaPatched) return;
        ads.__zaPatched = true;
        ['requestAd','requestAds','showAd','render','requestOnly','preloadAd'].forEach(m => {
            if (typeof ads[m] === 'function') {
                ads[m] = () => {
                    hookState.interceptedCalls++;
                    log(`✓ INTERCEPTED: CrazygamesAds.${m}()`);
                    return Promise.resolve({ success: true });
                };
            }
        });
        if (ads.hasAdblock) ads.hasAdblock = () => Promise.resolve(false);
    }
    let _ads = window.CrazygamesAds;
    Object.defineProperty(window, 'CrazygamesAds', {
        configurable: true, enumerable: true,
        get() { return _ads; },
        set(v) { _ads = v; patchCrazygamesAds(v); }
    });
    if (window.CrazygamesAds) patchCrazygamesAds(window.CrazygamesAds);

})();