ZeroAd: CrazyGames

Complete fake CrazyGames environment for all SDK versions & wrappers

За да инсталирате този скрипт, трябва да имате инсталирано разширение като Tampermonkey, Greasemonkey или Violentmonkey.

За да инсталирате този скрипт, трябва да инсталирате разширение, като например Tampermonkey .

За да инсталирате този скрипт, трябва да имате инсталирано разширение като Tampermonkey или Violentmonkey.

За да инсталирате този скрипт, трябва да имате инсталирано разширение като Tampermonkey или Userscripts.

За да инсталирате скрипта, трябва да инсталирате разширение като Tampermonkey.

За да инсталирате този скрипт, трябва да имате инсталиран скриптов мениджър.

(Вече имам скриптов мениджър, искам да го инсталирам!)

Advertisement:

За да инсталирате този стил, трябва да инсталирате разширение като Stylus.

За да инсталирате този стил, трябва да инсталирате разширение като Stylus.

За да инсталирате този стил, трябва да инсталирате разширение като Stylus.

За да инсталирате този стил, трябва да имате инсталиран мениджър на потребителски стилове.

За да инсталирате този стил, трябва да имате инсталиран мениджър на потребителски стилове.

За да инсталирате този стил, трябва да имате инсталиран мениджър на потребителски стилове.

(Вече имам инсталиран мениджър на стиловете, искам да го инсталирам!)

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);

})();