ZeroAd: Poki

Instant, zero-delay Poki SDK bypass with global object scanning

Voor het installeren van scripts heb je een extensie nodig, zoals Tampermonkey, Greasemonkey of Violentmonkey.

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

Voor het installeren van scripts heb je een extensie nodig, zoals Tampermonkey of Violentmonkey.

Voor het installeren van scripts heb je een extensie nodig, zoals Tampermonkey of Userscripts.

Voor het installeren van scripts heb je een extensie nodig, zoals {tampermonkey_link:Tampermonkey}.

Voor het installeren van scripts heb je een gebruikersscriptbeheerder nodig.

(Ik heb al een user script manager, laat me het downloaden!)

Voor het installeren van gebruikersstijlen heb je een extensie nodig, zoals {stylus_link:Stylus}.

Voor het installeren van gebruikersstijlen heb je een extensie nodig, zoals {stylus_link:Stylus}.

Voor het installeren van gebruikersstijlen heb je een extensie nodig, zoals {stylus_link:Stylus}.

Voor het installeren van gebruikersstijlen heb je een gebruikersstijlbeheerder nodig.

Voor het installeren van gebruikersstijlen heb je een gebruikersstijlbeheerder nodig.

Voor het installeren van gebruikersstijlen heb je een gebruikersstijlbeheerder nodig.

(Ik heb al een beheerder - laat me doorgaan met de installatie!)

// ==UserScript==
// @name         ZeroAd: Poki
// @namespace    https://greasyfork.org/en/users/1483567-vujohn123
// @version      4.0.5
// @description  Instant, zero-delay Poki SDK bypass with global object scanning
// @author       ZeroAd Team
// @match        *://*.poki.com/*
// @match        *://poki.com/*
// @grant        none
// @run-at       document-start
// @license      MIT
// ==/UserScript==

(function() {
    'use strict';

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

    const CONFIG = { DEBUG: true };  // Set false to disable logs
    const METRICS = {
        hooksInstalled: 0,
        interceptedCalls: 0,
        failedHooks: 0,
        rewardsGranted: 0
    };

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

    // --- Core hook functions (mutates the passed object) ---
    function safeDispatchEvent(target, eventName) {
        try { target.dispatchEvent(new CustomEvent(eventName, { bubbles: true })); } catch (e) {}
    }
    function safeCallback(fn, ...args) {
        if (typeof fn === 'function') {
            try { fn(...args); } catch (e) { warn('Callback error:', e); }
        }
    }

    function hookPokiSDK(sdk) {
        if (!sdk || sdk.__zaHooked) return false;
        log('Hooking SDK object...');

        try {
            sdk.__zaHooked = true;

            // --- commercialBreak ---
            if (typeof sdk.commercialBreak === 'function') {
                sdk.commercialBreak = function(...args) {
                    log('🚫 commercialBreak skipped');
                    METRICS.interceptedCalls++;
                    if (args.length && typeof args[0] === 'function') try { args[0](); } catch(e) {}
                    return Promise.resolve();
                };
                log('✅ commercialBreak hooked');
            }

            // --- rewardedBreak ---
            if (typeof sdk.rewardedBreak === 'function') {
                sdk.rewardedBreak = function(callbacks) {
                    log('🎁 rewardedBreak → instant reward');
                    METRICS.interceptedCalls++;
                    let onStart = null, onReward = null, onError = null;
                    if (typeof callbacks === 'function') {
                        onReward = callbacks;
                    } else if (callbacks && typeof callbacks === 'object') {
                        onStart = callbacks.onStart || callbacks.start;
                        onReward = callbacks.adFinished || callbacks.onComplete || callbacks.onReward || callbacks.complete;
                        onError = callbacks.onError || callbacks.error;
                    }
                    safeCallback(onStart);
                    safeCallback(onReward);
                    safeCallback(onError, null);
                    METRICS.rewardsGranted++;
                    safeDispatchEvent(window, 'rewardedComplete');
                    safeDispatchEvent(window, 'rewardGranted');
                    safeDispatchEvent(window, 'adComplete');
                    log('✅ Reward granted instantly');
                    return Promise.resolve(true);
                };
                log('✅ rewardedBreak hooked');
            }

            // --- display ads ---
            if (typeof sdk.hoistDisplayAd === 'function') {
                sdk.hoistDisplayAd = () => { METRICS.interceptedCalls++; return false; };
            }
            if (typeof sdk.destroyDisplayAd === 'function') {
                sdk.destroyDisplayAd = () => { METRICS.interceptedCalls++; };
            }
            if (typeof sdk.displayAd === 'function') {
                sdk.displayAd = (e, t, o, i) => {
                    METRICS.interceptedCalls++;
                    if (i) safeCallback(i, true);
                    if (o) safeCallback(o);
                    return false;
                };
            }
            if (typeof sdk.destroyAd === 'function') {
                sdk.destroyAd = () => { METRICS.interceptedCalls++; };
            }

            // --- playground / platform breaks ---
            ['playgroundCommercialBreak', 'platformCommercialBreak'].forEach(m => {
                if (typeof sdk[m] === 'function') {
                    sdk[m] = () => { log(m + ' skipped'); METRICS.interceptedCalls++; return Promise.resolve(); };
                }
            });

            // --- monetization internals ---
            if (sdk.__monetization) {
                if (typeof sdk.__monetization.requestAd === 'function') sdk.__monetization.requestAd = () => Promise.resolve();
                if (typeof sdk.__monetization.displayAd === 'function') sdk.__monetization.displayAd = () => false;
                if (typeof sdk.__monetization.init === 'function') sdk.__monetization.init = () => Promise.resolve();
            }

            // --- no-op tracking ---
            ['happyTime','gameLoading','gameplayStart','gameplayStop','captureError','sendEvent','track','setDebug','measure','gameLoadingFinished','gameLoadingProgress','gameInteractive','logError','muteAd','roundEnd','roundStart','sendHighscore','setLogging','setPlayerAge','enableEventTracking','openExternalLink'].forEach(m => {
                if (typeof sdk[m] === 'function') {
                    sdk[m] = (...args) => {
                        if (m === 'gameplayStart' || m === 'gameplayStop') log(m + ' tracked (no-op)');
                        else log(m + ' no-op');
                    };
                }
            });

            METRICS.hooksInstalled++;
            log('✅ SDK object fully hooked!');
            return true;
        } catch (e) {
            error('Hook failed:', e);
            METRICS.failedHooks++;
            return false;
        }
    }

    // --- Trap for window.PokiSDK (non-configurable) ---
    function installTrap() {
        let _pokiSDK = window.PokiSDK;
        if (_pokiSDK && !_pokiSDK.__zaHooked) {
            hookPokiSDK(_pokiSDK);
        }
        Object.defineProperty(window, 'PokiSDK', {
            configurable: false,
            enumerable: true,
            get: function() {
                // log('PokiSDK GET'); // optional, can be noisy
                return _pokiSDK;
            },
            set: function(newValue) {
                log('PokiSDK SET (new SDK)');
                _pokiSDK = newValue;
                if (newValue && !newValue.__zaHooked) {
                    hookPokiSDK(newValue);
                }
            }
        });
        log('✅ Non‑configurable trap installed');
    }

    // --- Global scanner: find and hook any object with SDK methods ---
    function scanAndHookAllSDKObjects() {
        let found = 0;
        // Check all properties of window
        for (let key in window) {
            try {
                const val = window[key];
                if (val && typeof val === 'object' && val !== window && !val.__zaHooked) {
                    // Check if it has the typical SDK methods
                    if (typeof val.commercialBreak === 'function' && typeof val.rewardedBreak === 'function') {
                        log('Found SDK object at window.' + key + ' – hooking its methods');
                        hookPokiSDK(val);
                        found++;
                    }
                }
            } catch(e) {}
        }
        // Also check common aliases
        const aliases = ['Poki', 'PokiUnitySDK', 'PokiSDK', 'poki'];
        for (let alias of aliases) {
            try {
                const val = window[alias];
                if (val && typeof val === 'object' && !val.__zaHooked && typeof val.commercialBreak === 'function') {
                    log('Found SDK object at window.' + alias + ' – hooking');
                    hookPokiSDK(val);
                    found++;
                }
            } catch(e) {}
        }
        if (found > 0) {
            log(`✅ Hooked ${found} additional SDK object(s)`);
        }
        return found;
    }

    // --- Observer for script loads (fallback) ---
    function setupObserver() {
        const observer = new MutationObserver(mutations => {
            for (const mutation of mutations) {
                for (const node of mutation.addedNodes) {
                    if (node.tagName === 'SCRIPT') {
                        const src = (node.src || '').toLowerCase();
                        if (src.includes('poki') && (src.includes('sdk') || src.includes('hoist') || src.includes('playground') || src.includes('v2') || src.includes('ay'))) {
                            log('SDK script detected:', src.substring(0, 80));
                            if (node.readyState === 'complete' || node.readyState === 'loaded') {
                                setTimeout(() => { scanAndHookAllSDKObjects(); }, 0);
                            } else {
                                node.addEventListener('load', () => {
                                    setTimeout(() => { scanAndHookAllSDKObjects(); }, 0);
                                });
                            }
                        }
                    }
                }
            }
        });
        if (document.documentElement) {
            observer.observe(document.documentElement, { childList: true, subtree: true });
        }
        log('✅ MutationObserver active');
    }

    // --- Initialization ---
    function initialize() {
        log('🚀 ZeroAd: Poki SDK v4.0.5 – Global scanner');
        installTrap();
        setupObserver();

        // Initial scan after a short delay
        setTimeout(scanAndHookAllSDKObjects, 100);

        // Keep scanning for a few seconds to catch late objects
        let attempts = 0;
        const maxAttempts = 20; // 10 seconds
        const interval = setInterval(() => {
            attempts++;
            const found = scanAndHookAllSDKObjects();
            if (attempts >= maxAttempts || found > 0) {
                // If we found something, we can slow down or stop, but we'll keep going a bit more.
                if (found > 0) {
                    log('Found objects, continuing scan...');
                }
                if (attempts >= maxAttempts) {
                    clearInterval(interval);
                    log('🔍 Scan finished');
                }
            }
        }, 500);

        window._zaMetrics = window._zaMetrics || {};
        window._zaMetrics.poki = METRICS;

        // Status report after 5 seconds
        setTimeout(() => {
            log('📊 Status:', {
                hooksInstalled: METRICS.hooksInstalled,
                interceptedCalls: METRICS.interceptedCalls,
                rewardsGranted: METRICS.rewardsGranted
            });
        }, 5000);
    }

    initialize();

    // Also scan on DOMContentLoaded as a safety net
    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', () => {
            setTimeout(scanAndHookAllSDKObjects, 0);
        });
    }
})();