ZeroAd: CrazyGames

Complete fake CrazyGames environment for all SDK versions & wrappers

Na nainštalovanie skriptu si budete musieť nainštalovať rozšírenie, ako napríklad Tampermonkey, Greasemonkey alebo Violentmonkey.

Na inštaláciu tohto skriptu je potrebné nainštalovať rozšírenie, ako napríklad Tampermonkey.

Na nainštalovanie skriptu si budete musieť nainštalovať rozšírenie, ako napríklad Tampermonkey, % alebo Violentmonkey.

Na nainštalovanie skriptu si budete musieť nainštalovať rozšírenie, ako napríklad Tampermonkey alebo Userscripts.

Na inštaláciu tohto skriptu je potrebné nainštalovať rozšírenie, ako napríklad Tampermonkey.

Na inštaláciu tohto skriptu je potrebné nainštalovať rozšírenie správcu používateľských skriptov.

(Už mám správcu používateľských skriptov, nechajte ma ho nainštalovať!)

Advertisement:

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie, ako napríklad Stylus.

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie, ako napríklad Stylus.

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie, ako napríklad Stylus.

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie správcu používateľských štýlov.

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie správcu používateľských štýlov.

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie správcu používateľských štýlov.

(Už mám správcu používateľských štýlov, nechajte ma ho nainštalovať!)

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

})();