Greasy Fork is available in English.

ZeroAd: Poki

Instant, zero-delay Poki SDK bypass with bulletproof hook

À data de 21/08/2026. Ver a versão mais recente.

Terá de instalar uma extensão como Tampermonkey, Greasemonkey ou Violentmonkey para instalar este script.

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

Terá de instalar uma extensão como Tampermonkey ou Violentmonkey para instalar este script.

Terá de instalar uma extensão como Tampermonkey ou Userscripts para instalar este script.

Terá de instalar uma extensão como Tampermonkey para instalar este script.

Terá de instalar uma extensão de gestão de scripts de utilizador para instalar este script.

(Já tenho um gestor de scripts de utilizador, deixe-me instalá-lo!)

Terá de instalar uma extensão como Stylus para instalar este estilo.

Terá de instalar uma extensão como Stylus para instalar este estilo.

Terá de instalar uma extensão como Stylus para instalar este estilo.

Terá de instalar uma extensão de gestão de estilos de utilizador para instalar este estilo.

Terá de instalar uma extensão de gestão de estilos de utilizador para instalar este estilo.

Terá de instalar uma extensão de gestão de estilos de utilizador para instalar este estilo.

(Já tenho um gestor de estilos de utilizador, deixe-me instalá-lo!)

// ==UserScript==
// @name         ZeroAd: Poki
// @namespace    https://greasyfork.org/en/users/1483567-vujohn123
// @version      4.0.4
// @description  Instant, zero-delay Poki SDK bypass with bulletproof hook
// @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);

    // --- Hook functions (same as before) ---
    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 PokiSDK...');

        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('✅ PokiSDK hooked successfully!');
            return true;
        } catch (e) {
            error('Hook failed:', e);
            METRICS.failedHooks++;
            return false;
        }
    }

    // --- BULLETPROOF TRAP: non-configurable property descriptor ---
    function installBulletproofTrap() {
        let _pokiSDK = window.PokiSDK;

        // If the SDK already exists, hook it and use it as the stored value.
        if (_pokiSDK && !_pokiSDK.__zaHooked) {
            hookPokiSDK(_pokiSDK);
        }

        // Define a non-configurable property that can't be overwritten.
        Object.defineProperty(window, 'PokiSDK', {
            configurable: false,   // Prevents any redefinition
            enumerable: true,
            get: function() {
                log('PokiSDK GET');
                return _pokiSDK;
            },
            set: function(newValue) {
                log('PokiSDK SET (new SDK)');
                _pokiSDK = newValue;
                if (newValue && !newValue.__zaHooked) {
                    hookPokiSDK(newValue);
                }
            }
        });

        log('✅ Bulletproof trap installed (non-configurable)');
    }

    // --- Fallback observers (just in case) ---
    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'))) {
                            log('SDK script detected:', src.substring(0, 80));
                            if (node.readyState === 'complete' || node.readyState === 'loaded') {
                                setTimeout(() => {
                                    if (window.PokiSDK && !window.PokiSDK.__zaHooked) {
                                        hookPokiSDK(window.PokiSDK);
                                    }
                                }, 0);
                            } else {
                                node.addEventListener('load', () => {
                                    setTimeout(() => {
                                        if (window.PokiSDK && !window.PokiSDK.__zaHooked) {
                                            hookPokiSDK(window.PokiSDK);
                                        }
                                    }, 0);
                                });
                            }
                        }
                    }
                }
            }
        });
        if (document.documentElement) {
            observer.observe(document.documentElement, { childList: true, subtree: true });
        }
        log('✅ MutationObserver active');
    }

    function startRetry() {
        let attempts = 0;
        const maxAttempts = 100;
        const interval = setInterval(() => {
            attempts++;
            if (window.PokiSDK && !window.PokiSDK.__zaHooked) {
                log('Retry attempt ' + attempts + ' - hooking SDK');
                hookPokiSDK(window.PokiSDK);
            }
            if (attempts >= maxAttempts || (window.PokiSDK && window.PokiSDK.__zaHooked)) {
                clearInterval(interval);
                if (window.PokiSDK && window.PokiSDK.__zaHooked) {
                    log('✅ SDK hooked via retry');
                } else {
                    warn('⚠️ SDK not found after retries');
                }
            }
        }, 50);
    }

    // --- Global reference cleanup (scans for cached SDK references) ---
    function scanAndReplaceCachedReferences() {
        // This is a sledgehammer approach: look at all properties of `window`
        // and if any of them point to the original SDK object, replace them with our hooked version.
        // We only do this once, after the SDK is known to be hooked.
        setTimeout(() => {
            if (!window.PokiSDK || !window.PokiSDK.__zaHooked) return;
            const hooked = window.PokiSDK;
            // We need a way to detect the original object. We'll check if a property has the same methods as the hooked one, but it's tricky.
            // Instead, we can look for properties that are objects and have a `rewardedBreak` function that is not our hooked one.
            for (let key in window) {
                try {
                    const val = window[key];
                    if (val && typeof val === 'object' && val !== hooked && typeof val.rewardedBreak === 'function' && val !== window.PokiSDK) {
                        // Check if it's the original by seeing if its `rewardedBreak` is the same as the original?
                        // We can't easily compare, but we can check if it has `__zaHooked` flag – if not, it's likely the original.
                        if (!val.__zaHooked) {
                            log('Found cached reference: window.' + key + ' – replacing with hooked version');
                            try {
                                window[key] = hooked;
                            } catch(e) {}
                        }
                    }
                } catch(e) {}
            }
        }, 1000);
    }

    // --- Initialization ---
    function initialize() {
        log('🚀 ZeroAd: Poki SDK v4.0.4 – Bulletproof');
        installBulletproofTrap();
        setupObserver();
        startRetry();
        scanAndReplaceCachedReferences();

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

        setTimeout(() => {
            log('📊 Status:', {
                hookState: !!(window.PokiSDK && window.PokiSDK.__zaHooked),
                metrics: METRICS
            });
        }, 5000);
    }

    initialize();

    // Additional safety: on DOMContentLoaded, re-scan and hook if not yet.
    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', () => {
            if (window.PokiSDK && !window.PokiSDK.__zaHooked) {
                hookPokiSDK(window.PokiSDK);
            }
            scanAndReplaceCachedReferences();
        });
    }
})();